Sumas encadenadas con Nest
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 Nest
y 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 Nest
ser 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 f
alrededor Nest
. Se pone aún más feo si trato de evitar la necesidad de definir f
y 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 Function
y &
.
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 Fold
u otra construcción funcional?
Respuestas
Table
hace 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}]}]
"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.
Composition
es el término matemático elemental de con Nest
se 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.
Sum
se deriva de Plus
la 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 Nest
en la página de documentación de Product
ni viceversa.
¿Qué implica eso para tu pregunta? Ahora al principio nada. Pero es una pista fuerte.
Si bien Nest
es iterativo con n, la constante "tiempos" en la tercera posición de argumento, Product
no 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 Product
distan 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 Nest
que se puede hacer y lo que no se puede hacer. Comparo el integrado Nest
con otros integrados y combinaciones y Composition
s.
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.

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