2010-11-11 40 views
2

這是我在實現Generalized Distributive Law時遇到的一個設計問題。假設你需要自動生成如下形式在Mathematica中自動生成總和

http://yaroslavvb.com/upload/sum-prod-formula.png

條款之和,固定變量和「求和」變量內自動爲每一個這樣的表達式所產生的表達,和「f」的功能是分別定義的。爲了產生上述表達式中,我可能需要調用

sumProduct(factors,fixedVariables,fixedValues,freeVariables,freeRanges) 

其中

factors={{1,4},{3,4},{3,4,5}} 
fixedVariables={1,3} 
fixedValues={-1,9} 
freeVariables={4,5} 
freeRanges={Range[5],Range[6]} 

和該函數的輸出將相當於

Total[{f14[-1,1]f34[9,1]f345[9,1,1],f14[-1,2]f34[9,2]f345[9,2,1],....}] 

F條件的表示可以是不同的,即f [{1,4},{ - 1,1}]而不是f14 [-1,1]。同樣使用Integer來引用每個變量只是一種設計選擇。

任何人都可以提出一個優雅的方法來實現sumProduct?

編輯11/11 劍鋒的解決方案,改寫可讀性

factors = {{1, 4}, {3, 4}, {3, 4, 5}}; 
vars = {{1, {-1}}, {3, {9}}, {4, Range[5]}, {5, Range[6]}}; 

(* list of numbers => list of vars *) 
arglist[factor_] := Subscript[x, #] & /@ factor; 

(* list of factors => list of functions for those factors *) 
terms = Apply[f[#], arglist[#]] & /@ factors; 

(* {var,range} pairs for each variable *) 
args = {Subscript[x, #1], #2} & @@@ vars; 

Sum[Times @@ terms, Sequence @@ args] 

回答

3

我會幫在一起的固定和自由變量,並指定所有在列表中的

variables={{1,{-1}},{3,{9}},{4,Range[5]},{5,Range[6]}}; 

然後您的sumProduct可以非常簡潔地實現

sumProduct[f_, factors_, vars_] := Module[{x}, Sum[ 
    Times @@ ((Subscript[f, ##] @@ (Subscript[x, #] & /@ {##}) &) @@@ factors), 
    Sequence @@ ({Subscript[x, #1], #2} & @@@ vars)]] 

將其稱作sumProduct[f,factors,variables]吐出一個長期的事情:

Subscript[f, 1,4][-1,1] Subscript[f, 3,4][9,1] Subscript[f, 3,4,5][9,1,1]+.... 

了這你是什麼之後?

+0

這也適用於變量的符號,例如, 'sumProduct [f,{{a,b}},{{a,{1,2}},{b,{0}}}]'。 – Janus 2010-11-11 09:22:51

+0

+1以這種方式指定固定和自由變量使事情變得更容易。 – 2010-11-11 11:38:56

+0

謝謝,這很整潔! – 2010-11-11 20:23:37