首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么SymPy不将(-x**3)**(2/3)简化为x**2?

为什么SymPy不将(-x**3)**(2/3)简化为x**2?
EN

Stack Overflow用户
提问于 2020-09-12 03:53:17
回答 2查看 93关注 0票数 3

我尝试使用SymPy来计算以下积分:

手动评估时,答案是−² log(28)。

我的工作与SymPy相匹配,直到我集成了x

代码语言:javascript
运行
复制
x, y = sp.symbols('x y', real=True)
z = 1 / (sp.root(y, 3)*(x**3+1))
iz = z.integrate((y, -x**3, 0)) # integrate with respect to y
print(iz)
# -3*(-x**3)**(2/3)/(2*(x**3 + 1))
iiz = iz.integrate((x, 0, 3)) # integrate with respect to x
print(iiz)
# -3*Integral((-x**3)**(2/3)/(x**3 + 1), (x, 0, 3))/2
print(sp.N(iiz))
# 0.833051127543801 - 1.4428868782084*I

看起来抛弃SymPy的是(-x**3)**(2/3)。这应该简化为x**2,但SymPy不这么认为。手动简化,产生与我手动获得的答案相同的答案:

代码语言:javascript
运行
复制
print( sp.integrate(-3*x**2/(2*(x**3 + 1)), (x, 0, 3)) )
# -log(28)/2

有没有更好的方法来解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-12 17:40:48

您的问题是sympy.root在默认情况下返回主体根,而不是真正的根。为了避免这种情况,您可以使用sympy.root的第三个可选参数来指定您希望使用真正的根目录。下面的代码会产生所需的结果:

代码语言:javascript
运行
复制
import sympy as sp

x, y = sp.symbols('x y', real=True)
z = 1 / (sp.root(y,3,1)*(x**3+1))
iz = z.integrate((y, -x**3, 0))
iiz = iz.integrate((x, 0, 3))
print(iiz)
# -log(28)/2

为了在某种程度上解决您的标题问题,(-x**3)**(2/3)实际上是(-x**3)**0.666666666666667,因为这是Python的一部分。要想得到更接近你想要的东西,你需要做:

代码语言:javascript
运行
复制
import sympy as sp
x = sp.symbols('x', positive=True)
solution = (-x**3)**sp.Rational(2,3)
print(solution)
# (-1)**(2/3)*x**2

一般来说,我会建议避免使用rational powers,除非你真的需要考虑它们的多重解决方案、复杂性等。

票数 4
EN

Stack Overflow用户

发布于 2020-09-13 04:56:41

在我的isympy会话中: SymPy 1.6.2

代码语言:javascript
运行
复制
In [131]: z = 1 / (root(y,3)*(x**3+1))

In [132]: iz = z.integrate((y, -x**3, 0))

In [133]: iiz = iz.integrate((x,0,3))

In [134]: iiz
Out[134]: 
     2/3         
-(-1)   ⋅log(28) 
─────────────────
        2        

In [135]: N(iiz)
Out[135]: 0.833051127543801 - 1.4428868782084⋅ⅈ

In [136]: abs(iiz)
Out[136]: 
log(28)
───────
   2   

root文档谈到了返回主体根,除了提供k参数之外,还建议使用real_root

代码语言:javascript
运行
复制
In [137]: z = 1 / (real_root(y,3)*(x**3+1))

In [138]: iz = z.integrate((y, -x**3, 0))

In [139]: iiz = iz.integrate((x,0,3))

In [140]: iiz
Out[140]: 
-log(28) 
─────────
    2    

In [141]: N(iiz)
Out[141]: -1.66610225508760

很明显,二重积分有多个解,取决于根。看起来它们都有相同的震级。这听起来很合理,但我复杂的数学学习是在遥远的过去,所以我不能提供理论上的理由。

有了k=2,我们得到了第三种解决方案:

代码语言:javascript
运行
复制
In [146]: z = 1 / (root(y,3,2)*(x**3+1))

In [147]: iz = z.integrate((y, -x**3, 0))

In [148]: iiz = iz.integrate((x,0,3))

    In [149]: iiz
    Out[149]: 
    3 ____        
    ╲╱ -1 ⋅log(28)
    ──────────────
          2     

所以在复平面上有3个解,有乘数,-1, (-1)**(1/3), -(-1)**(2/3),和相同的大小。

代码语言:javascript
运行
复制
-1.66610225508760
0.833051127543801 - 1.4428868782084⋅ⅈ
0.833051127543801 + 1.4428868782084⋅ⅈ

如果我们在z中引入一个整数符号k

代码语言:javascript
运行
复制
In [158]: z = 1 / (root(y,3,k)*(x**3+1))

In [159]: z
Out[159]: 
      -2⋅k    
      ─────   
        3     
  (-1)        
──────────────
3 ___ ⎛ 3    ⎞
╲╱ y ⋅⎝x  + 1⎠

二重积分变成:

代码语言:javascript
运行
复制
In [164]: iiz =z.integrate((y, -x**3,0)).integrate((x,0,3))

In [165]: iiz
Out[165]: 
             -2⋅k          
             ─────         
     2/3       3           
-(-1)   ⋅(-1)     ⋅log(28) 
───────────────────────────
             2             

并进行iiz.subs({k:0})等操作,生成上述复杂的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63853499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档