python - 为什么 SymPy 的积分有时会产生非常长的反导数?

标签 python sympy symbolic-math

这是在 SymPy 1.1.1 上使用 Python 3.6.5。

在 SymPy 中,我总是不得不在被积函数周围使用 S('...') 以使其不返回使用 float 的结果,有时使其实际计算积分.这样做的一个副作用是 SymPy 有时会返回一个非常长的整数结果,例如,

z=symbols('z')
integrate(S('1/(cos(z)+sin(z)+2**(1/2))'),z)

返回

-221108036964586978124740847487718783991180811173992192658
5647118334188786/(-2669010107947987550795474273552499757111
367990811651140108173443831125763*tan(z/2) + 
18872751463854612207095892554955468385336360233408060517004
98501499110078*sqrt(2)*tan(z/2) - 7817349615625263300858850180
569529185777319674708450884076749
42332015685*sqrt(2) + 110554018482293489062370423743859391995
5904055869960963292823559167094393) + 
1563469923125052660171770036113905837155463934941690176815349
884664031370*sqrt(2)/(-2669010107947987550795474273552499757
111367990811651140108173443831125763*tan(z/2) + 
18872751463854612207095892554955468385336360233408060517004985
01499110078*sqrt(2)*tan(z/2) - 78173496156252633008588501805695
29185777319674708450884076749
42332015685*sqrt(2) + 11055401848229348906237042374385939199559
04055869960963292823559167094393)

我验证了上面的结果,是正确的。在上面执行 simplify() 没有帮助。我起初以为结果需要简化,仅此而已。

如果我不将 S'(....)' 与 sympy 一起使用,它不会评估 这个例子。

>>> integrate(1/(cos(z)+sin(z)+2**(1/2)),z)
1.0*Integral(1/(1.0*sin(z) + 1.0*cos(z) + 1.4142135623731), z)

但与 fricas 1.3.3 的小输出相比

integrate(1/(cos(z)+sin(z)+2^(1/2)),z)
((-1)*2^(1/2)*sin(z)+((-1)*2^(1/2)*cos(z)+2))/(2*sin(z)+(-2)*cos(z))

数学 11.3

ClearAll[z]
FullSimplify[Integrate[1/(Cos[z] + Sin[z] + 2^(1/2)), z]]
-(((1 + I) + (2*I + Sqrt[2])*E^(I*z))/((1 + I) + Sqrt[2]*E^(I*z)))

枫叶2018

int(1/(cos(z)+sin(z)+2^(1/2)),z);
-2/((2^(1/2)-1)*(tan((1/2)*z)+2^(1/2)+1))

问题:SymPy 的积分算法中有什么有时 使其输出如此长的数字,而其他 CAS 系统 不求同一个积分? SymPy 中有什么技巧可以使 与其他 CAS 系统相比,它产生更小的叶尺寸结果?

同样,SymPy 的结果是正确的。我只是问为什么这个例子的结果有这么长的数字。如果知道原因,可能会有助于更好地理解事物。

最佳答案

我可以猜到答案来自“启发式 Risch 算法”,该算法在某个步骤匹配许多(拆开的)表达式的系数,并以完成这项工作的大系数结束。实际上,简化表达式 before integration happens:

>>> integrate(trigsimp(1/(cos(z)+sin(z)+sqrt(2))), z)
-sqrt(2)/(tan(z/2 + pi/8) + 1)

(可以在此处使用 simplify 来达到相同的效果,但如果您知道此处需要三角简化,则可以使用 trigsimp。)一旦表达式简化为

sqrt(2)/(2*(sin(z + pi/4) + 1))

只剩下一个三角函数,比处理两个容易多了。

(另外:使用 sqrt(2) 代替 2**(1/2) 是避免过早评估 1/的更好方法2 到 float 而不是将整个公式字符串化。)

关于python - 为什么 SymPy 的积分有时会产生非常长的反导数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50904546/

相关文章:

python - 编辑字符串列表中的项目

python - numba 的表现(我做错了什么吗?)

python - 对于列表中的每个二元组,打印它在其他列表中出现的次数 - python NLTK

python:在 easy_install 期间会发生什么?

python - 在Python中求解非线性方程: the answer is the same as initial guess

python - 如何在通过求解另一个分段函数获得的分段函数中对 ExprCondPair 进行排序?

python - 如何在 Sympy 中求解非线性方程?

python - 如何简化sympy中的指数对数?

matlab - 打印 syms/matlabFunction 慢

python - 是否可以强制 SymPy 计算积分,或者告诉我为什么它无法计算积分?