python - sympy:使用二项式公式和二次补数简化较大的表达式

标签 python sympy

我得到了矩阵的一些特征值

import sys
import mpmath
from sympy import *

X,Y,Z = symbols("X,Y,Z")
Rxy,Rxz, Ry,Ryx,Ryz, Rz,Rzy,Rzz = symbols("Rxy,Rxz,  Ry,Ryx,Ryz, Rz,Rzy,Rzz")


J = Matrix([
       [      -1,        0,        0],
       [       0,    -Ry*Y, Ry*Rzy*Y],
       [Rxz*Rz*Z, Ryz*Rz*Z,    -Rz*Z]])

如下:

{-Ry*Y/2 - Rz*Z/2 + sqrt(Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2)/2: 1,
 -Ry*Y/2 - Rz*Z/2 - sqrt(Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2)/2: 1,
 -1: 1}

让我们看看特征值一:

In [25]: J.eigenvals().keys()[0]
Out[25]: -Ry*Y/2 - Rz*Z/2 + sqrt(Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2)/2

我想将这个术语简化如下:分解 1/2 和(这很重要)根。

我可以通过添加二次补来将根式变换如下

Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2     | + 4*Ry*Rz*Y*Z -4*Ry*Rz*Y*Z

这导致

Ry**2*Y**2 + Rz**2*Z**2 + 2*Ry*Rz*Y*Z - 4*Ry*Rz*Y*Z + 4*Ry*Ryz*Rz*Rzy*Y*Z

可以因式分解为

(Ry*Y + Rz*Z)**2 - 4*Ry*Rz*Y*Z*(1 - Ryz*Rzy)

通过这些评估,完整的特征值应如下所示

-1/2*(Ry*Y + Rz*Z - sqrt((Ry*Y + Rz*Z)**2 - 4*Ry*Rz*Y*Z*(1 - Ryz*Rzy)))

这个计算对我来说非常重要,因为我必须评估特征值是否<0。最后一种形式要容易得多。

让我向您展示到目前为止我做了什么。

In [24]: J.eigenvals().keys()[0]
Out[24]: -Ry*Y/2 - Rz*Z/2 + sqrt(Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2)/2

In [25]: J.eigenvals().keys()[0].factor() 
Out[25]: -(Ry*Y + Rz*Z - sqrt(Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2))/2

In [26]: J.eigenvals().keys()[0].simplify()
Out[26]: -Ry*Y/2 - Rz*Z/2 + sqrt(Ry**2*Y**2 + 4*Ry*Ryz*Rz*Rzy*Y*Z - 2*Ry*Rz*Y*Z + Rz**2*Z**2)/2

所以 .simplify() 根本不会改变结果。 .factor() 只是分解出-1/2。 如果我没记错的话,我可以向 .factor() 传递一个参数,比如 Y 或 Z,哪个变量应该被分解。但是我得到了很多略有不同的特征值作为输出,并且我不想手动指定 Factor() 的每个参数(如果这个解决方案有效的话)。

我还尝试通过计算行列式并解决行列式==0来自己计算特征值... 我还使用了 definat.factor() 并随后解决了它,但这种方法的最佳结果与 J.eigenvals().keys()[0].factor() 相同。

你知道如何解决这个问题吗?

提前谢谢

亚历克斯

最佳答案

这类事情被要求很多(例如,另请参见这个问题: Expression simplification in SymPy ),但 SymPy 中并没有真正的好方法来做到这一点。问题在于这种“部分”因式分解不是唯一的(可能有多种方法可以将多项式转换为乘积之和)。

我打开了this issue有关它的信息,请参见 SymPy 问题跟踪器。我向您展示了一种可以接近的方法(这里 a 是平方根下的项)

In [92]: collect(expand(a.subs(Ry*Y, x - Rz*Z)), x, func=factor).subs(x, Ry*Y + Rz*Z)
Out[92]:
      2  2                                                                   2
- 4⋅Rz ⋅Z ⋅(Ryz⋅Rzy - 1) + 4⋅Rz⋅Z⋅(Ry⋅Y + Rz⋅Z)⋅(Ryz⋅Rzy - 1) + (Ry⋅Y + Rz⋅Z)

在这里,我暂时将 Ry*Y + Rz*Z 替换为变量 x,以便获得您想要的平方项。

我无法找到一种方法来更接近您想要的结果(即,从其余项中分解 Ryz*Rzy - 1)。

关于python - sympy:使用二项式公式和二次补数简化较大的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40652810/

相关文章:

python - 通过排列python中的元素来最小化矩阵中的列总和

python - 为什么 unicodecsv 不能正常写入?

sympy - 使用 SymPy 的项目?

python - 在 SymPy 中一次求解非线性方程组和不等式

python - 如何绘制给定参数曲线在某个点的法线

python - 可以在 sympy 中为符号添加描述吗?

python - 如何配置配方 zope2instance 以记录到主管

python - 多子集和计算

sympy - 积分 SymPy 数组

python - 使用 Python 将文件上传到 Google Cloud Storage Bucket 子目录