Nestとの連鎖合計

Aug 20 2020

私はこのような連鎖合計を計算しようとしています $$ 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に良い機会としてこれを参照してください、の使用であるNestFold。この合計は、それ自体に入れ子関数として見ることができます$$ 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または別の機能構造を使用することによってですか?

回答

3 march Aug 20 2020 at 21:21

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}]}]
SteffenJaeschke Aug 22 2020 at 18:48

「Nest [f、expr、n]は、fがexprにn回適用された式を提供します。」

Nest 関数、式、正の整数のnを取ります。

それ以上でもそれ以下でもありません。

Nest どういうわけか時代遅れです。

に取って代わられCompositionます。

Compositionwithからの数学的な基本用語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がかなり異なることがわかります。

SumPlus上記の方法で派生します。のドキュメントページにPlusは、の代替案がいくつか示されていSumます。

複雑な製品を構築するために、Mathematicaは組み込みを提供しますProduct。Nestのドキュメントページにとの行はなく、Productその逆もありません。

それはあなたの質問に何を意味しますか?今は最初は何もありません。しかし、それは強いヒントです。

一方でNestnは反復している、第三引数の位置に「回」の定数は、ProductX」が、開始と終了とイテレータ私を必要としません。それはあなたの加数が表すものです。私はのためのドキュメントページに例を受け入れる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ユーザーの生成をご覧ください。有名なチュートリアルは、関数を繰り返し適用することでした。

Wolfram言語に基づくMathematicaが対処できるインデックスの範囲を定義します。

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