Somme concatenate con Nest

Aug 20 2020

Sto cercando di calcolare una somma concatenata come questa $$ 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} $$ Ad esempio, quando $m=3$, questo diventa $$ 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 $$ Ovviamente il punto è che voglio $m$rimanere non specificato nell'algoritmo. Ora, so come implementarlo creando manualmente gli elenchi di iteratori (ad esempio con Tuples) e applicandoli Sum. Ma a me sembra più un hack che un codice elegante.

Poiché cerco sempre di rendere il mio codice il più elegante possibile, vedo questa come una buona opportunità per imparare. Uno dei concetti che ho sempre difficile da comprendere (ma mi piacerebbe padroneggiarlo), è l'uso di Neste Fold. Questa somma può essere vista come una funzione annidata su se stessa$$ 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] $$Mi aspetto Nestdi essere un candidato ideale. Ho provato un po ', ma il meglio che sono riuscito a trovare è

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]

Trovo questo particolarmente brutto, specialmente le due definizioni di funzione che necessitano ancora di una funzione pura all'interno F, così come il fatto che ho bisogno di avvolgere un ulteriore fgiro Nest. Diventa ancora più brutto se cerco di evitare la necessità di definire fe F:

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

con la necessità di utilizzare Functione &.

Quindi ecco la mia domanda: c'è un modo più ordinato per ottenere questa somma concatenata usando Nest? In caso contrario, forse utilizzando Foldo un altro costrutto funzionale?

Risposte

3 march Aug 20 2020 at 21:21

Tablelo fa automaticamente. Dovresti essere in grado di adattare il seguente codice:

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
  ]

Così

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

e

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

In alternativa, genera direttamente gli indici e applica loro la funzione, in questo modo:

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

e

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

O

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

"Nest [f, expr, n] fornisce un'espressione con f applicata n volte a expr."

Nest accetta una funzione, un'espressione, un n di numeri interi positivi.

Ne più ne meno.

Nest è in qualche modo obsoleto.

È sostituito da Composition.

Compositionè il termine matematico elementare da con Nestè derivato.

C'è un esempio nella documentazione della composizione per una somma:

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

Ciò chiarisce che Sum e Nest sono piuttosto diversi.

Sumè derivato Plusnel modo sopra. La pagina della documentazione Plusmostra alcune alternative a Sum.

Per costruire prodotti complicati Mathematica offre il built-in Product. Non c'è né una linea con Nestnella pagina della documentazione Productné viceversa.

Cosa implica per la tua domanda? Adesso all'inizio niente. Ma è un forte suggerimento.

Sebbene Nestsia iterativa con n, la costante "tempi" alla posizione del terzo argomento, Productnon richiede una x "ma un iteratore i con inizio e fine. Questo è ciò che rappresentano i tuoi sommatori. Accetto gli esempi nella pagina della documentazione perché Productsono lontani da facile o molto specializzato.

Ci sono alcuni bei esempi e metodi, come renderlo più efficiente:

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

Questa domanda riguarda già la somma o il prodotto con esclusioni .

La somma è più essenziale per ottenere formulari chiusi come in questo esempio:

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

o

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

può essere fatto con un iteratore o un elenco. L'iteratore necessita che la lista dei coefficienti sia già definita e itera su di essa in modo lineare. Nelle versioni più moderne di Mathematica la seconda versione sarà più veloce nella maggior parte dei contesti.

I marchi formula utilizzano degli operatori differenti @, @@e @@@che sono diversi per Composition @*.

Questa è una risposta molto apprezzata su scansione, mappa e applicazione . Questa risposta spiega alcune differenze tra Composizione e Applica . Queste risposte vanno molto più in profondità negli argomenti correlati: i moduli operatore v10s a cosa servono?

Alcune idee sbagliate comuni sono affrontate in queste risposte: come designare argomenti in una mappa annidata .

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

Ma il risultato desiderato è questo

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

Se f non è elencabile, anche questo può essere scritto in questo modo:

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 prossima alternativa è

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

E questo, a sua volta, consente il desiderato Nest:

Nidifica [f, #, 1] e / @ tuple [{{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}]} )

Questa domanda su nest-fold-is-there-an-extension-for-more-than-2-arguments fa riferimento a un capitolo 5.5.3 La restrizione della funzione Fold-ed a due argomenti è falsa di un libro online di Leonid Shifrin e un esempio con tre slot:

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}

Questi sono molto speciali ma fanno il trucco e le estensioni sono già incluse.

Per ora finalmente, mi piace fare riferimento a questo articolo di panoramica

alternative-a-cicli-procedurali-e-iterazione-su-elenchi-in-matematica /

che include alcuni esempi di utilizzo di Fold e Nest e confrontarli in diverse situazioni con built-in alternativi. Tutto questo è molto carino e offre una conoscenza più approfondita di ciò che Nestfa e può fare e cosa no. Confronto il built-in Nestcon altri built-in e combinazioni Compositiones.

Cerca nella documentazione di Mathematica Iterator per ottenere questo come la migliore definizione per il valore di input ne qualche spiegazione per la selezione del paradigma di Mathematica su questo.

Esistono due definizioni per Expression nella documentazione di Mathematica, una per le celle e una per l'interprete del linguaggio Wolfram. Quindi una tale guida alla ricerca in input dedicati all'utilità di WolframAlpha

Dai un'occhiata a FixedPoint, un built-in storicamente raggruppato con Nest e per la generazione di utenti Mathematica come il limite incorporato di Nest per infinite iterazioni, applicazioni. Il famoso tutorial stava applicando le funzioni ripetutamente.

definisce gli intervalli per gli indici che possono far fronte a Mathematica basata sul linguaggio Wolfram.

Quindi questo è ciò che manca a Nest e simili e Prodcut ha.