Sumas encadenadas con Nest

Aug 20 2020

Estoy buscando calcular una suma encadenada como esta $$ 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} $$ Por ejemplo, cuando $m=3$, esto se convierte en $$ 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 $$ Por supuesto que el punto es que quiero $m$permanecer sin especificar en el algoritmo. Ahora, sé cómo implementar esto haciendo manualmente las listas de iteradores (por ejemplo, con Tuples) y aplicándolas Sum. Pero para mí eso se siente más como un truco que un código elegante.

Como siempre trato de que mi código sea lo más elegante posible, veo esto como una buena oportunidad para aprender. Uno de los conceptos que siempre tengo difícil de entender (pero me encantaría dominar), es el uso de Nesty Fold. A esta suma se puede ver como una función anidada sobre sí misma$$ 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] $$Esperaría Nestser un candidato ideal. He intentado un poco, pero lo mejor que se me ocurrió es

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]

Me parece especialmente las dos definiciones particularmente feos, función que aún necesitan una dentro de la pura función F, así como el hecho de que necesito para envolver un adicional de falrededor Nest. Se pone aún más feo si trato de evitar la necesidad de definir fy 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 necesidad de usar Functiony &.

Entonces, aquí está mi pregunta: ¿hay una manera más ordenada de lograr esta suma encadenada usando Nest? Si no es así, ¿tal vez usando Foldu otra construcción funcional?

Respuestas

3 march Aug 20 2020 at 21:21

Tablehace esto automáticamente. Debería poder adaptar el siguiente código:

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
  ]

Así

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

y

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

Alternativamente, genere los índices directamente y aplíqueles la función, así:

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

y

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] da una expresión con f aplicada n veces a expr".

Nest toma una función, una expresión, una n de enteros positivos.

Ni mas ni menos.

Nest está de alguna manera desactualizado.

Es reemplazado por Composition.

Compositiones el término matemático elemental de con Nestse deriva.

Hay un ejemplo en la documentación de Composición para una suma:

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

Esto aclara que Sum y Nest son bastante diferentes.

Sumse deriva de Plusla manera anterior. La página de documentación de Plusmuestra alguna alternativa a Sum.

Para construir productos complicados, Mathematica ofrece el Product. No hay una línea con Nesten la página de documentación de Productni viceversa.

¿Qué implica eso para tu pregunta? Ahora al principio nada. Pero es una pista fuerte.

Si bien Nestes iterativo con n, la constante "tiempos" en la tercera posición de argumento, Productno requiere una x", pero un iterador i con inicio y final. Eso es lo que sus sumandos representan. Acepto los ejemplos en la página de documentación de Productdistan mucho de fácil o mucho el especializado.

Hay algunos buenos ejemplos y métodos, cómo hacer esto más eficiente:

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

Esta pregunta ya se refiere a suma o producto con exclusiones .

Sum es más esencial para obtener formuladores cerrados como en este ejemplo:

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

se puede hacer con un iterador o una lista. El iterador necesita que la lista de coeficientes ya esté definida e itera sobre ella de forma lineal. En versiones más modernas de Mathematica, la segunda versión será más rápida en la mayoría de los contextos.

Las marcas fórmula uso de diferentes operadores @, @@y @@@que son diferentes a Composition @*.

Esta es una respuesta altamente calificada sobre escanear vs mapa vs aplicar . Esta respuesta explica algunas diferencias entre Composición y Aplicar . Estas respuestas son mucho más profundas en los temas relacionados: formularios de operador v10s, ¿para qué sirven?

En estas respuestas se abordan algunos conceptos erróneos comunes: ¿cómo designo argumentos en un mapa anidado ?

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

Pero el resultado deseado es este

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 no se puede enumerar, esto también se puede escribir de esta manera:

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 siguiente alternativa es

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

Y esto, a su vez, permite lo deseado Nest:

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

Esta pregunta sobre nest-fold-is-there-an-extension-for-more-than-2-argumentos se refiere a un capítulo 5.5.3 La restricción de la función Fold-ed a dos argumentos es falsa de un libro en línea de Leonid Shifrin y un ejemplo con tres ranuras:

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}

Estos son muy especiales pero estos hacen el truco y las extensiones ya están incluidas.

Por ahora, finalmente, me gustaría referirme a este artículo de descripción general

alternativas-a-los-bucles-procedimentales-e-iterando-sobre-listas-en-mathica /

que incluye algunos ejemplos que utilizan Fold y Nest y compara esto en diferentes situaciones con incorporados alternativos. Todo esto es bastante agradable y ofrece un conocimiento más profundo de lo Nestque se puede hacer y lo que no se puede hacer. Comparo el integrado Nestcon otros integrados y combinaciones y Compositions.

Busque Iterator en la documentación de Mathematica para obtener esta como la mejor definición para el valor de entrada ny alguna explicación para la selección del paradigma de Mathematica sobre eso.

Hay dos definiciones para Expresión en la documentación de Mathematica, una para las celdas y otra para el intérprete de Wolfram Language. Entonces, tal guía de búsqueda en entradas dedicadas a la utilidad de WolframAlpha

Eche un vistazo a FixedPoint, un integrado históricamente agrupado con Nest y para la generación de usuarios de Mathematica como el elemento integrado limitante de Nest para aplicaciones de iteraciones infinitas. El famoso tutorial fue Aplicar funciones repetidamente.

define los rangos para los índices que Mathematica basado en Wolfram Language puede hacer frente.

Así que eso es lo que le falta a Nest y otros similares, y a Prodcut.