这是在 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/