【问题标题】:Expand a function of an arbitrary number of arguments if it is linear in each argument如果它在每个参数中是线性的,则展开任意数量参数的函数
【发布时间】:2018-05-16 03:08:25
【问题描述】:

有没有办法为具有任意数量参数的函数 f 编写替换规则,使其在所有参数中都是线性的? 当 f 具有三个参数时的示例:

  1. f( x1+x4 , x2 , x3 ) = f(x4,x2,x3) + f(x1,x2,x3)
  2. f( x1 , x2+x4 , x3 ) = f(x1,x2,x3) + f(x1,x4,x3)
  3. f( x1 , x2 , x3+x4 ) = f(x1,x2,x3) + f(x1,x2,x4)

使用“Wild”部分有效:

from sympy import *
f=Function('f')
var("x1:5")
a=Wild("a")
b=Wild("b")
A=Wild('A', exclude=[0])
B=Wild('B', exclude=[0])
expr=f(x1,x2+x4,x3);
print("This one works")
print expr , '->' , expr.replace(f(a,Add(A,B),b),f(a,A,b)+f(a,B,b))
# f(x1, x2 + x4, x3) -> f(x1, x2, x3) + f(x1, x4, x3)
print("This one doesn't on the last entry")
expr=f(x1,x2,x3+x4);
print f(x1,x2,x3+x4) , '->' , expr.replace(f(a,Add(A,B),b),f(a,A,b)+f(a,B,b))
# f(x1, x2, x3 + x4) -> f(x1, x2, x3 + x4)

我知道我可以在更改替换时以多种方式迭代函数的参数,但我希望该功能已经内置到“Wild”或“替换”中。例如,Mathematica 具有“a___,b___,A___,B___”之类的“通配符”,这意味着“a___”可以是一个空序列、单个参数或多个参数的序列。例如,在 Mathematica 中,

expr /. f[a__,A_Plus,b__] :> f[a,A[[1]],b]+f[a,A[[2;;]],b]

将正确地简化这两个测试用例,以及带有任意数量参数的f

有没有类似的东西,还是和 sympy 一样接近?

或者,这可能与从 def f(*args): 之类的递归定义开始的参数解包有关吗?

【问题讨论】:

    标签: python sympy multiple-arguments


    【解决方案1】:

    我会检测 f 的哪些参数是 Add 并使用 itertools.product 扩展这些参数,而不是 Wild 匹配

    import itertools
    term_groups = [term.args if term.func is Add else (term,) for term in expr.args]
    expanded = Add(*[expr.func(*args) for args in itertools.product(*term_groups)])
    

    例如,如果exprf(x1+x2+x4, x2+x4, x3*x1),那么term_groups[(x1, x2, x4), (x2, x4), (x1*x3,)],其中最后一个参数产生一个单元素元组,因为它不是一个Add。而expanded

    f(x1, x2, x1*x3) + f(x1, x4, x1*x3) + f(x2, x2, x1*x3) + f(x2, x4, x1*x3) + f(x4, x2, x1*x3) + f(x4, x4, x1*x3)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 2017-12-18
      相关资源
      最近更新 更多