如果每个参数都是线性的,则展开任意数量参数的函数

时间:2018-05-16 03:08:25

标签: python sympy multiple-arguments

有没有办法为函数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)
  4. 使用“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”或“replace”中。例如,Mathematica有“通配符”,如“a ___,b ___,A ___,B ___”,这意味着“a ___”可以是空序列,也可以是单个参数,也可以是多个参数的序列。例如,在Mathematica中,

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

    会正确地简化两个测试用例,并且f包含任意数量的参数。

    是否有类似的东西,或者这是否接近,因为有同情心?

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

1 个答案:

答案 0 :(得分:0)

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

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,)],其中最后一个参数产生1个元素元组,因为它不是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)