Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么Symphy不将(-x**3)**(2/3)简化为x**2?_Python_Sympy_Exponent - Fatal编程技术网

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

Python 为什么Symphy不将(-x**3)**(2/3)简化为x**2?,python,sympy,exponent,Python,Sympy,Exponent,我试图用Symphy来计算以下积分: 手工评估时,答案是−½ 日志(28) 我的工作与SymPy相匹配,直到我集成了x: 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.int

我试图用Symphy来计算以下积分:

手工评估时,答案是−½ 日志(28)

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

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
似乎是什么把辛皮甩了是
(-x**3)**(2/3)
。这应该简化为
x**2
,但SymPy不这么认为。手动简化,得到与我手工得到的答案相同的答案:

print( sp.integrate(-3*x**2/(2*(x**3 + 1)), (x, 0, 3)) )
# -log(28)/2

有更好的方法吗?

您的问题是默认情况下,
sympy.root
返回的是主根,而不是真正的根。为了避免这种情况,您可以使用第三个可选参数
sympy.root
来指定您想要的是真正的根。以下操作将产生所需的结果:

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.6666667
,因为这是一个Python分数。要获得更接近您想要的东西,您需要执行以下操作:

import sympy as sp
x = sp.symbols('x', positive=True)
solution = (-x**3)**sp.Rational(2,3)
print(solution)
# (-1)**(2/3)*x**2

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

在我的
isympy
课程:SymPy 1.6.2中

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\u root

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
我们得到了第三个解决方案:

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)
,大小相同

-1.66610225508760
0.833051127543801 - 1.4428868782084⋅ⅈ
0.833051127543801 + 1.4428868782084⋅ⅈ
如果我们在
z
中引入整数符号
k

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⎠
二重积分变成:

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})
etc,生成上述复杂的解决方案。

我快速查看了默认情况下未执行的简化,但不幸的是,它们都没有改变任何内容。您可能应该在github上查询
abs()
匹配项
iiz
有一个
(-1)**(2/3)
项,这使得结果很复杂。@hpaulj关于
abs()
的观察非常有趣。这是否意味着
-log(28)/2
0.833051127543801-1.442886882084*I
都是有效答案,因为它们在复平面中与原点的距离相同?@nvi:While−½ 对数(28)和0.83− 1.44 我是正确的答案,这不是因为它们有相同的绝对值(到原点的距离)。这只是一个必要的性质,来自于这个特殊方程的特殊性质。有无限多个具有该属性的数字,其中最多有三个是解(取决于该属性的定义)^⅓ 在你的等式中是,你是否允许复杂的解决方案等等)。此外,对于其他问题,解决方案可能有不同的绝对值。运行第一个代码片段显示sp.N(iiz)=-1.6661022550876+2.7105054312376e-20*I。这更接近我所期望的答案,因为sp.N(-sp.log(28)/2)=-1.66610225508760,但我不清楚这个微小的虚部来自何处。根据我的理解,复数没有等价的实数形式,所以我很困惑,对于同一个问题,我得到了两个不同的答案。@nvi:我无法重现。第一个代码向我返回
-log(28)/2
,它将
sympy.N
转换为
-1.66610225508760
。有趣的是,这可能与使用sympy版本1.1.1的Colab有关。我复制了你的代码。谢谢你的帮助。