Verkettete Summen mit Nest

Aug 20 2020

Ich möchte eine verkettete Summe wie diese berechnen $$ 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} $$ Zum Beispiel wenn $m=3$wird dies $$ 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 $$ Natürlich geht es mir darum $m$im Algorithmus nicht spezifiziert bleiben. Jetzt weiß ich, wie man dies implementiert, indem man die Iteratorlisten (zB mit Tuples) manuell erstellt und darauf anwendet Sum. Aber für mich ist das eher ein Hack als ein eleganter Code.

Da ich immer versuche, meinen Code so elegant wie möglich zu gestalten, sehe ich dies als eine gute Gelegenheit zum Lernen. Eines der Konzepte, die ich immer schwer zu verstehen habe (aber gerne beherrschen würde), ist die Verwendung von Nestund Fold. Diese Summe kann als eine Funktion angesehen werden, die auf sich selbst verschachtelt ist$$ 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] $$Ich würde erwarten Nest, ein idealer Kandidat zu sein. Ich habe es ein bisschen versucht, aber das Beste, was ich mir einfallen lassen kann, ist

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]

Das finde ich besonders hässlich, vor allem der beiden Funktionsdefinitionen , die nach wie vor eine reine Funktion innerhalb benötigen F, sowie die Tatsache , dass ich eine zusätzliche wickeln fum Nest. Es wird noch hässlicher, wenn ich versuche, die Notwendigkeit zu vermeiden, Folgendes zu definieren fund F:

c[m_] := Sum[
  Nest[ Function[var,Sum[var[k]A[k],{k,#+1,5}]&], 1&, m-1][l] A[l]
, {l,1,n}]

mit der Notwendigkeit zu verwenden Functionund &.

Hier ist meine Frage: Gibt es eine bessere Möglichkeit, diese verkettete Summe mit zu erreichen Nest? Wenn nicht, vielleicht mit Foldeinem anderen funktionellen Konstrukt?

Antworten

3 march Aug 20 2020 at 21:21

Tablemacht das automatisch. Sie sollten in der Lage sein, den folgenden Code anzupassen:

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
  ]

So

f[2, 3]
(* A[1] A[2] + A[1] A[3] + A[2] A[3] *)

und

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] *)

Alternativ können Sie die Indizes direkt generieren und die Funktion wie folgt auf sie anwenden:

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] *)

und

f[3, 5] - f2[3, 5]
(* 0 *)

Oder

f3[n_, m_] := Sum[Times @@ A /@ is, {is, Subsets[Range[m], {n}]}]
SteffenJaeschke Aug 22 2020 at 18:48

"Nest [f, Ausdruck, n] gibt einen Ausdruck, wobei f n-mal auf Ausdruck angewendet wird."

Nest nimmt eine Funktion, einen Ausdruck, ein n von positiven ganzen Zahlen.

Nicht mehr und nicht weniger.

Nest ist irgendwie veraltet.

Es wird ersetzt durch Composition.

Compositionist der mathematische Elementarbegriff von mit Nestwird abgeleitet.

In der Dokumentation der Komposition gibt es ein Beispiel für eine Summe:

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]\)

Dies macht deutlich, dass Summe und Nest ziemlich unterschiedlich sind.

Sumwird auf Plusdie obige Weise abgeleitet. Die Dokumentationsseite von Pluszeigt eine Alternative zu Sum.

Um komplizierte Produkte aufzubauen, bietet Mathematica das eingebaute an Product. Es gibt weder eine Zeile mit Nestauf der Dokumentationsseite von Productnoch umgekehrt.

Was bedeutet das für Ihre Frage? Jetzt zunächst nichts. Aber es ist ein starker Hinweis.

Während Nestmit n iterativ ist, Producterfordert die "times" -Konstante an der dritten Argumentposition kein x ", sondern einen Iterator i mit Start und Ende. Das ist, was Ihre Summanden darstellen. Ich akzeptiere die Beispiele auf der Dokumentationsseite für Productsind weit entfernt einfach oder viel spezialisiert.

Es gibt einige schöne Beispiele und Methoden, wie dies effizienter gestaltet werden kann:

∑𝑖=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]

Diese Frage betrifft bereits die Summe oder das Produkt mit Ausschlüssen .

Die Summe ist wichtiger, um geschlossene Formulare wie in diesem Beispiel zu erhalten:

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}]

oder

With[{n = 6}, Times @@ f /@ Subtract @@@ Subsets[Array[a, n], {2}]]

kann entweder mit einem Iterator oder einer Liste durchgeführt werden. Der Iterator muss die Koeffizientenliste bereits definiert haben und iteriert linear darüber. In moderneren Mathematica-Versionen soll die zweite Version in den meisten Kontexten schneller sein.

Die Formel macht von verschiedenen Betreibern @, @@und @@@die sind unterschiedlich Composition @*.

Dies ist eine hoch bewertete Antwort zu Scan vs Map vs Apply . Diese Antwort erklärt einige Unterschiede zwischen Zusammensetzung und Anwenden . Diese Antworten gehen viel tiefer in die verwandten Themen: v10s Operator-Formulare, wofür sind sie gut?

Einig weit verbreitetes Missverständnis ist in diesen Antworten angesprochen: wie kann ich Argument in einer verschachtelten Karte bezeichnen kann .

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

Aber das gewünschte Ergebnis ist dies

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]}} *)

Wenn f in nicht auflistbar ist, kann dies folgendermaßen geschrieben werden:

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]}}
*)

Die nächste Alternative ist

Tupel [{{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]} )

Und dies ermöglicht wiederum das Gewünschte Nest:

Nest [f, #, 1] & / @ Tupel [{{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}]} )

Diese Frage zu Nest-Falte-gibt-es-eine-Erweiterung-für-mehr-als-2-Argumente bezieht sich auf ein Kapitel 5.5.3. Die Beschränkung der Fold-ed-Funktion auf zwei Argumente ist falsch für ein Online-Buch von Leonid Shifrin und Ein Beispiel mit drei Slots:

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}

Diese sind sehr speziell, aber sie machen den Trick und die Erweiterungen sind bereits enthalten.

Im Moment möchte ich mich endlich auf diesen Übersichtsartikel beziehen

Alternativen-zu-prozeduralen-Schleifen-und-Iterieren-über-Listen-in-Mathematica /

Dazu gehören einige Beispiele für die Verwendung von Fold und Nest, und vergleichen Sie diese in verschiedenen Situationen mit alternativen integrierten Funktionen. Das ist alles ganz nett und bietet tieferes Wissen darüber, was Nesttut und kann und was nicht. Ich vergleiche die eingebauten Nestmit anderen eingebauten und Kombinationen und Compositions.

Durchsuchen Sie die Mathematica-Dokumentation nach Iterator, um dies als bessere Definition für den Eingabewert n und eine Erklärung für die Auswahl des Mathematica-Paradigmas zu erhalten.

In der Mathematica-Dokumentation gibt es zwei Definitionen für Ausdruck, eine für die Zellen und eine für den Wolfram-Sprachinterpreter. Also eine solche Suchanleitung in Eingaben, die der Hilfsbereitschaft von WolframAlpha gewidmet sind

Werfen Sie einen Blick auf FixedPoint, ein in Nest historisch gruppiertes System, und für die Generierung von Mathematica-Benutzern als einschränkendes integriertes Nest für Anwendungen mit unendlichen Iterationen. Das berühmte Tutorial war das wiederholte Anwenden von Funktionen.

definiert die Bereiche für die Indizes, mit denen Mathematica basierend auf der Wolfram-Sprache umgehen kann.

Genau das fehlt Nest und Prodcut.