在 Sympy 中创建一个正式的线性函数 [英] Create a formal linear function in Sympy
问题描述
我在 Sympy 中有一个表达式(比如
-M - n + x(n)
) 我会喜欢创建一个形式线性函数,说 f,并将其应用到我的表达式中,以便在简化后得到:
-f(M) - f(n) + f(x(n))
是否可以告诉 sympy 已验证诸如线性之类的属性?
一种非常hacky的方法是将函数f应用于求和中的每个子表达式.例如,当给出一个像我给出的第一个表达式一样的表达式时,只需访问出现在总和中的项(这里是
[-M, -n , x(n)]
然后在列表上映射 f 并将其求和以获得预期的结果.
是否有一种简单的方法可以做到这一点,或者我必须遍历表达式的句法树?
这有效:
<预><代码>>>>x,f = map(Function, 'xf');n,M = 符号('n,M');expr = -M - n + x(n)>>>Add(*[f(a) for a in Add.make_args(expr)])f(-M) + f(-n) + f(x(n))如果你有一个像 f(n*(M + 1))
这样的表达式并且你展开它,你会得到 f(n*M + n)
.你能告诉 SymPy 把函数应用到 f
的参数的参数上吗?是:
如果你调用这样的替代linapp
,你可以将它用于任何你想要的功能:
def linapp(expr, *f):返回 expr.expand().replace(lambda x: x.func in f,lambda x: Add(*[x.func(a) for a in Add.make_args(x.args[0])]))>>>打印(linapp(cos(x + y)+ sin(x + y),cos,sin))sin(x) + sin(y) + cos(x) + cos(y)
(并不是说这是一个真实的结果,只是说你可以做到.如果你用别的东西替换了一个变量并且你想重新应用线性化,你可以:
<预><代码>>>>linapp(_.subs(y, z + 1), cos)sin(x) + sin(z + 1) + cos(x) + cos(z) + cos(1)I have an expression in Sympy (like
-M - n + x(n)
) and I would like to create a formal linear function, says f, and apply it to my expression, in order to get, after simplification:
-f(M) - f(n) + f(x(n))
Is it possible to tell sympy that a property such as linearity is verified?
A very hacky way to do it would be to apply the function f to every subexpression which is in a sum. For instance when given an expressions like the first one I gave, it would be nice to simply access the terms appearing in the sum (here it would be
[-M, -n , x(n)]
Then mapping f on the list and sum it to get what is expected.
Is there an easy way to do so, or have I necessarily to go trough the syntactic tree of the expression ?
This works:
>>> x,f = map(Function, 'xf'); n,M = symbols('n,M'); expr = -M - n + x(n)
>>> Add(*[f(a) for a in Add.make_args(expr)])
f(-M) + f(-n) + f(x(n))
If you have an expression like f(n*(M + 1))
and you expand it you will get f(n*M + n)
. Can you tell SymPy to apply the function to the args of f
's args? Yes:
>>> expr = f(n*(M + 1))
>>> expr.expand().replace(lambda x: x.func == f,
... lambda x: Add(*[f(a) for a in Add.make_args(x.args[0])]))
f(n) + f(M*n)
If you call such a replacement linapp
you can use it for any function that you want:
def linapp(expr, *f):
return expr.expand().replace(
lambda x: x.func in f,
lambda x: Add(*[x.func(a) for a in Add.make_args(x.args[0])]))
>>> print(linapp(cos(x+y) + sin(x + y), cos, sin))
sin(x) + sin(y) + cos(x) + cos(y)
(Not saying that it's a true result, just that you can do it. And if you replace a variable with something else and you want to reapply the linearization, you can:
>>> linapp(_.subs(y, z + 1), cos)
sin(x) + sin(z + 1) + cos(x) + cos(z) + cos(1)
这篇关于在 Sympy 中创建一个正式的线性函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!