Nestとの連鎖合計
私はこのような連鎖合計を計算しようとしています $$ 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} $$ たとえば、 $m=3$、これは $$ 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 $$ もちろん要点は欲しい $m$アルゴリズムで指定されないままにします。これで、イテレータリストを手動で作成して(たとえば、を使用してTuples
)適用Sum
することにより、これを実装する方法がわかりました。しかし、私にとっては、それはエレガントなコードというよりはハックのように感じます。
私はいつもできるだけエレガントとしての私のコードを取得しようとして、私は常に把握することは困難持っている(しかし、マスターするのが大好きだ)概念のlearn.Oneに良い機会としてこれを参照してください、の使用であるNest
とFold
。この合計は、それ自体に入れ子関数として見ることができます$$ 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] $$Nest
理想的な候補になると思います。私は少し試しましたが、私が思いつくことができる最高のものは
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]
私はまだ、純粋な関数の内部を必要とするこの特に醜い、特に2つの関数の定義を見つけるF
だけでなく、私は追加のラップする必要があるという事実f
の周りをNest
。私は定義する必要を回避しようとすると、それも醜い取得f
とをF
:
c[m_] := Sum[
Nest[ Function[var,Sum[var[k]A[k],{k,#+1,5}]&], 1&, m-1][l] A[l]
, {l,1,n}]
を使用する必要がFunction
あり&
ます。
だからここに私の質問があります:この連鎖した合計を使用して達成するためのより良い方法はありNest
ますか?そうでない場合は、Fold
または別の機能構造を使用することによってですか?
回答
Table
これは自動的に行われます。次のコードを適応させることができるはずです。
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
]
したがって、
f[2, 3]
(* A[1] A[2] + A[1] A[3] + A[2] A[3] *)
そして
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] *)
または、インデックスを直接生成し、次のように関数をインデックスに適用します。
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] *)
そして
f[3, 5] - f2[3, 5]
(* 0 *)
または
f3[n_, m_] := Sum[Times @@ A /@ is, {is, Subsets[Range[m], {n}]}]
「Nest [f、expr、n]は、fがexprにn回適用された式を提供します。」
Nest
関数、式、正の整数のnを取ります。
それ以上でもそれ以下でもありません。
Nest
どういうわけか時代遅れです。
に取って代わられCompositionます。
Composition
withからの数学的な基本用語Nest
が導出されます。
合計の構成のドキュメントに例があります。
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]\)
これにより、SumとNestがかなり異なることがわかります。
Sum
Plus
上記の方法で派生します。のドキュメントページにPlusは、の代替案がいくつか示されていSum
ます。
複雑な製品を構築するために、Mathematicaは組み込みを提供しますProduct。Nest
のドキュメントページにとの行はなく、Product
その逆もありません。
それはあなたの質問に何を意味しますか?今は最初は何もありません。しかし、それは強いヒントです。
一方でNest
nは反復している、第三引数の位置に「回」の定数は、Product
X」が、開始と終了とイテレータ私を必要としません。それはあなたの加数が表すものです。私はのためのドキュメントページに例を受け入れるProduct
遠くにあります簡単または多くの専門。
これをより効率的にする方法について、いくつかの良い例と方法があります。
∑𝑖=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]
この質問は、除外された合計または積についてすでに懸念しています。
この例のように、閉じた数式を取得するには、合計がより重要です。
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}]
または
With[{n = 6}, Times @@ f /@ Subtract @@@ Subsets[Array[a, n], {2}]]
イテレータまたはリストのいずれかを使用して実行できます。イテレータは、係数リストがすでに定義されている必要があり、線形に反復します。最近のMathematicaバージョンでは、ほとんどのコンテキストで2番目のバージョンの方が高速です。
数式は@
、@@
とは異なるさまざまな演算子を使用@@@
しComposition
@*
ます。
これは、スキャンvsマップvs適用についての高い評価の回答です。この回答は、CompositionとApplyのいくつかの違いを説明しています。この回答は、関連するトピックでさらに深く掘り下げられます。v10sオペレーターは、何に適しているのでしょうか。
いくつかの一般的な誤解は、この回答で対処されています:ネストされたマップで引数を指定するにはどうすればよいですか。
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
しかし、望ましい結果はこれです
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]}} *)
fがリストできない場合、これは次のように書くこともできます。
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]}}
*)
次の選択肢は
タプル[{{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]})
そして、これは、順番に、望ましいを可能にしますNest
:
Nest [f、#、1]&/ @タプル[{{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}]})
nest-fold-is-there-an-extension-for-more-than-2引数に関するこの質問は、5.5.3章を参照しています。折り畳まれた関数を2つの引数に制限することは、LeonidShifrinによるオンラインブックの偽物です。 3つのスロットがある例:
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}
これらは非常に特別ですが、これらはトリックを作り、拡張機能はすでに含まれています。
とりあえず最後に、この概要記事を参照したいと思います
手続き型ループの代替案と数学のリストを反復する/
これには、FoldとNestを使用したいくつかの例が含まれており、さまざまな状況でこれを代替の組み込みと比較します。これはすべて非常に素晴らしく、何Nest
ができるか、何ができるか、何ができないかについてのより深い知識を提供します。ビルトインNest
を他のビルトインおよび組み合わせと比較しますComposition
。
MathematicaのドキュメントでIteratorを検索して、これを入力値nのより良い定義として取得し、それに関するMathematicaパラダイムの選択についての説明を入手してください。
Mathematicaドキュメントには、セル用とWolfram言語インタプリタ用の2つの式の定義があります。したがって、WolframAlphaの有用性に特化した入力へのそのような検索ガイド
歴史的にNestとグループ化されたFixedPointと、無限の反復、アプリケーションのためのNestの制限ビルトインとしてのMathematicaユーザーの生成をご覧ください。有名なチュートリアルは、関数を繰り返し適用することでした。

これがNestなどに欠けているものであり、Prodcutにはあります。