0

当我使用 Sympy 进行符号集成时,我想沿特定符号扩展表达式,以便稍后我可以收集和集成该符号。有没有办法在不改变其他(不相关)符号形式的情况下进行这种“扩展”?

例如,考虑这个 Python 代码并运行结果:

>>> from sympy import *
>>> var('x,a,b,c')
(x, a, b, c)
>>> f = (a + 1) * a + x * (b + exp(-c*x))
>>> collect(f, (exp(-c*x), x))
a*(a + 1) + x*(b + exp(-c*x))
>>> collect(expand(f), (exp(-c*x), x))
a**2 + a + b*x + x*exp(-c*x)

输出都是预期的。如果没有先“扩展”,“收集”只会让我回到原来的形式。如果我们先使用“扩展”,我会得到我想要的。想象一下,如果我们有许多上面'f'的和,并且符号b和c是复杂的表达式,如果我们使用f的原始形式,积分将需要很长时间。事实上,如果首先应用“扩展”,我需要几秒钟才能完成集成,但在运行近一个小时后无法完成。

“扩展”的问题在于“完全扩展”表达式可能很昂贵。在上面的例子中,我们看到 a*(a+1) 也被扩展了(并且花费了计算时间)。

我有表达式(稍后会集成),每个表达式扩展为大约 4 万个术语。作为 x 的函数,展开的结果类似于上面例子中的形式——我知道它一定是那种形式。大部分时间(如果它会完成的话)都花在扩展那些与“x”无关的术语上。我可以避免那些不必要的扩展吗?

4

1 回答 1

0

您可以尝试屏蔽不包含 x 的术语,如下所示:

>>> def ex(e,x):
...  m = [i for i in e.atoms(Mul) if not i.has(x)]
...  reps = dict(zip(m,[Dummy() for i in m]))
...  return expand(e.xreplace(reps)).subs([(v,k) for k,v in reps.items()])
...
>>> f = (a + 1) * a + x * (b + exp(-c*x))
>>> ex(f,x)
a*(a + 1) + b*x + x*exp(-c*x)

请注意,仅扩展了包含 x 的术语。

此外,您可能只想使用 expand_mul,而不是使用 expand;expand 执行几种类型的扩展(请参阅文档字符串)。

于 2014-12-01T17:32:01.337 回答