这是我在处理Generalized Distributive Law的实施时遇到的一个设计问题。假设您需要自动生成以下表单的表达式
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 Janus的解决方案,为了便于阅读而重写
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]
答案 0 :(得分: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]+....
这就是你追求的目标吗?