Sommes enchaînées avec Nest
Je cherche à calculer une somme enchaînée comme celle-ci $$ C_m = \sum\limits_{i_1=1}^N \;\sum\limits_{i_2=i_1+1}^N \;\sum\limits_{i_3=i_2+1}^N \cdots \;\sum\limits_{i_m=i_{m-1}+1}^N A_{i_1}A_{i_2}A_{i_3}\cdots A_{i_m} $$ Par exemple, quand $m=3$, cela devient $$ C_3 = \sum\limits_{i=1}^N \;\sum\limits_{j=i+1}^N \;\sum\limits_{k=j+1}^N A_i A_j A_k $$ Bien sûr, le fait est que je veux $m$pour ne pas être spécifié dans l'algorithme. Maintenant, je sais comment implémenter cela en créant manuellement les listes d'itérateurs (par exemple avec Tuples
) et en appliquant Sum
dessus. Mais pour moi, cela ressemble plus à un hack qu'à un code élégant.
Comme j'essaie toujours de rendre mon code aussi élégant que possible, je vois cela comme une bonne opportunité d'apprendre. L'un des concepts que j'ai toujours du mal à comprendre (mais que j'aimerais maîtriser) est l'utilisation de Nest
et Fold
. A cette somme peut être vue comme une fonction imbriquée sur elle-même$$ C_m = \sum\limits_{i_1=1}^N A_{i_1} \left[ \;\sum\limits_{i_2=i_1+1}^N A_{i_2} \left[ \;\sum\limits_{i_3=i_2+1}^N A_{i_3} \left[ \cdots\vphantom{\sum\limits_{i_3=i_2+1}^N} \right]\right]\right] $$Je m'attendrais Nest
à être un candidat idéal. J'ai essayé un peu, mais le mieux que je puisse trouver est
f[g_,j_] := Sum[g[k]A[k], {k,j+1,n}]
F[x_] := f[x,#]&
c[m_] := f[Nest[F,1&,m-1],0]
Je trouve cela particulièrement laid, en particulier les deux définitions de fonctions qui ont encore besoin d' un intérieur pur fonction F
, ainsi que le fait que je dois envelopper un montant supplémentaire f
autour Nest
. Cela devient encore plus laid si j'essaie d'éviter d'avoir à définir f
et F
:
c[m_] := Sum[
Nest[ Function[var,Sum[var[k]A[k],{k,#+1,5}]&], 1&, m-1][l] A[l]
, {l,1,n}]
avec la nécessité d'utiliser Function
et &
.
Alors, voici ma question: y a-t-il un moyen plus propre d'atteindre cette somme enchaînée en utilisant Nest
? Sinon, peut-être en utilisant Fold
ou en utilisant une autre construction fonctionnelle?
Réponses
Table
fait cela automatiquement. Vous devriez pouvoir adapter le code suivant:
f[m_, n_] := Sum[
Product[A[i[j]], {j, 1, m}] // Evaluate,
Sequence @@ Prepend[Table[{i[j], i[j - 1] + 1, n}, {j, 2, m}], {i[1], 1, n}] // Evaluate
]
Donc
f[2, 3]
(* A[1] A[2] + A[1] A[3] + A[2] A[3] *)
et
f[3, 5]
(* A[1] A[2] A[3] + A[1] A[2] A[4] + A[1] A[3] A[4] + A[2] A[3] A[4] + A[1] A[2] A[5] + A[1] A[3] A[5] + A[2] A[3] A[5] + A[1] A[4] A[5] + A[2] A[4] A[5] + A[3] A[4] A[5] *)
Vous pouvez également générer les indices directement et leur appliquer la fonction, comme ceci:
f2[n_, m_] := Times @@@ Map[A, Subsets[Range[m], {n}], {2}] // Total
f2[3, 5]
(* A[1] A[2] A[3] + A[1] A[2] A[4] + A[1] A[3] A[4] + A[2] A[3] A[4] + A[1] A[2] A[5] + A[1] A[3] A[5] + A[2] A[3] A[5] + A[1] A[4] A[5] + A[2] A[4] A[5] + A[3] A[4] A[5] *)
et
f[3, 5] - f2[3, 5]
(* 0 *)
Ou
f3[n_, m_] := Sum[Times @@ A /@ is, {is, Subsets[Range[m], {n}]}]
"Nest [f, expr, n] donne une expression avec f appliqué n fois à expr."
Nest
prend une fonction, une expression, un n d'entiers positifs.
Ni plus ni moins.
Nest
est en quelque sorte dépassé.
Il est remplacé par Composition.
Composition
est le terme mathématique élémentaire de avec Nest
est dérivé.
Il y a un exemple dans la documentation de Composition pour une somme:
Composition[HoldForm, Plus] @@ Range[20]
___
\!\(
TagBox[
RowBox[{"1", "+", "2", "+", "3", "+", "4", "+", "5", "+", "6", "+",
"7", "+", "8", "+", "9", "+", "10", "+", "11", "+", "12", "+",
"13", "+", "14", "+", "15", "+", "16", "+", "17", "+", "18", "+",
"19", "+", "20"}],
HoldForm]\)
Cela montre que Sum et Nest sont assez différents.
Sum
est dérivé de Plus
la manière ci-dessus. La page de documentation de Plusmontre une alternative à Sum
.
Pour créer des produits complexes, Mathematica propose le module intégré Product. Il n'y a pas de ligne avec Nest
sur la page de documentation de Product
ni vice versa.
Qu'est-ce que cela implique pour votre question? Maintenant, au début, rien. Mais c'est un indice fort.
Bien qu'elle Nest
soit itérative avec n, la constante "times" à la troisième position de l'argument, Product
ne nécessite pas un x "mais un itérateur i avec début et fin. C'est ce que représentent vos sommations. J'accepte les exemples de la page de documentation car ils Product
sont loin d'être facile ou beaucoup le spécialisé.
Il existe de jolis exemples et méthodes pour rendre cela plus efficace:
∑𝑖=2𝑁cos𝜃𝑖cos𝜃′𝑖∏𝑗=𝑖+1𝑀sin𝜃𝑗𝜃′𝑗
NSum[Cos[θ[[i]]] Cos[Θp[[i]]] Product[ Sin[θ[[j]]] Sin[θp[[j]]], {j, i + 1, d - 1}], {i, 2, d - 1}]
f[M_, n_] := Reverse[Table[Cos[θ[i]] Cos[θ'[i]], {i, 2, n}]].PadLeft[FoldList[
Sin[θ[M - #2] θ'[M - #2]] # &, Sin[θ[M] θ'[M]], Range[M - 3]], Max[n - 1, 0], 1]
Cette question concerne déjà la somme ou le produit avec des exclusions .
La somme est plus essentielle pour obtenir des formulaires fermés comme dans cet exemple:
Sum[Product[i^2, {i, 1, n}], {i, 1, n}]
n (n!)^2
n = 4;
Times @@ Flatten@Table[f[a[i] - a[j]], {i, 1, n - 1}, {j, i + 1, n}]
ou
With[{n = 6}, Times @@ f /@ Subtract @@@ Subsets[Array[a, n], {2}]]
peut être fait avec un itérateur ou une liste. L'itérateur a besoin que la liste de coefficients soit déjà définie et l'itère de manière linéaire. Dans les versions Mathematica plus modernes, la deuxième version sera plus rapide dans la plupart des contextes.
La formule utilise différents opérateurs @
, @@
et @@@
qui sont différents de Composition
@*
.
C'est une réponse très appréciée sur scan vs map vs apply . Cette réponse explique certaines différences entre Composition et Apply . Ces réponses vont beaucoup plus loin dans les sujets liés: les formulaires d'opérateurs v10 à quoi servent-ils?
Certaines idées fausses courantes sont abordées dans ces réponses: comment désigner des arguments dans une carte imbriquée .
ClearAll[list1, list2, a, b, c, x, y, z, f]
list1 = {a, b, c}
list2 = {x, y, z}
___
Map[Map[f[#1, #2] &, list1] &, list2]
__
list2
___
Map[Function[x, Map[f[#1, x] &, list1]], list2]
___
list2
Mais le résultat souhaité est le suivant
Outer[f, list1, list2]
(*
{{f[a, x], f[a, y], f[a, z]},
{f[b, x], f[b, y], f[b, z]},
{f[c, x], f[c, y], f[c, z]}}
*)
Map[Function[p2, Map[Function[p1, f[p1, p2]], list1]], list2]
(* {{f [a, x], f [b, x], f [c, x]}, {f [a, y], f [b, y], f [c, y]}, { f [a, z], f [b, z], f [c, z]}} *)
Si f n'est pas listable, cela peut être trop écrit de cette façon:
Distribute[f[{a, b, c}, {x, y, z}], List]
(*
{{f[a, x], f[b, x], f[c, x]},
{f[a, y], f[b, y], f[c, y]},
{f[a, z], f[b, z], f[c, z]}}
*)
La prochaine alternative est
Tuples [{{a, b, c}, {x, y, z}}] ( {{a, x}, {a, y}, {a, z}, {b, x}, {b, y }, {b, z}, {c, x}, {c, y}, {c, z}} )
Apply[f, Tuples[{{a, b, c}, {x, y, z}}], {1}]
( {f [a, x], f [a, y], f [a, z], f [b, x], f [b, y], f [b, z], f [c, x] , f [c, y], f [c, z]} )
Et cela, à son tour, permet d'obtenir le Nest
:
Nest [f, #, 1] & / @ Tuples [{{a, b, c}, {x, y, z}}] ( {f [{a, x}], f [{a, y}] , f [{a, z}], f [{b, x}], f [{b, y}], f [{b, z}], f [{c, x}], f [{c , y}], f [{c, z}]} )
Cette question sur nest-fold-is-there-an-extension-for-more-than-2-arguments fait référence à un chapitre 5.5.3 La restriction de la fonction Fold-ed à deux arguments est un faux d'un livre en ligne de Leonid Shifrin et un exemple avec trois emplacements:
multiFoldList[f_, start_, args__List] :=
FoldList[f @@ Prepend[#2, #] &, start, {args}\[Transpose]]
____
multiFoldList[#1 (1 + #2) - #3 &, 1000, {.01, .02, .03}, {100, 200,
300}]
___
{1000, 910., 728.2, 450.046}
Celles-ci sont très spéciales mais elles font l'affaire et les extensions sont déjà incluses.
Pour l'instant enfin, j'aime me référer à cet article de présentation
alternatives-aux-boucles-procédurales-et-itération-sur-des-listes-en-mathématique /
qui comprend quelques exemples utilisant Fold et Nest et comparez cela dans différentes situations à d'autres éléments intégrés. Tout cela est très agréable et offre une connaissance plus approfondie de ce qui Nest
fait et peut faire et de ce qui ne l'est pas. Je compare le intégré à Nest
d'autres intégrés et combinaisons et Composition
s.
Recherchez Iterator dans la documentation Mathematica pour obtenir la meilleure définition de la valeur d'entrée n et une explication de la sélection de paradigme Mathematica à ce sujet.
Il existe deux définitions de l'expression dans la documentation Mathematica, une pour les cellules et une pour l'interpréteur de Wolfram Language. Donc, un tel guide de recherche dans les entrées dédiées à l'utilité de WolframAlpha
Jetez un oeil à FixedPoint un intégré historiquement regroupé avec Nest et pour la génération d'utilisateurs Mathematica comme le intégré limitant de Nest pour des itérations infinies, des applications. Le célèbre tutoriel était l'application répétée des fonctions.

C'est donc ce qui manque à Nest et à Prodcut.