sympy:用二项式和二次补码简化更大的表达式

时间:2016-11-17 10:46:37

标签: 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并且(这很重要)激进因素。

我可以通过添加二次补码

来变换radicant
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,该变量应该被分解。但是我得到了许多稍微不同的特征值作为输出,我不想手动指定因子()的每个参数(如果这个解决方案甚至可行)。

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

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

提前谢谢

亚历

1 个答案:

答案 0 :(得分:1)

这种事情被要求很多(例如,参见这个问题:JohnnyHK),但在SymPy中做这件事并不是一个好方法。问题是这样的&#34;局部&#34;分解不是唯一的(可能有多种方法将多项式转换为乘积之和)。

我在SymPy问题跟踪器中打开了Expression simplification in 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从剩余的条件中分解出来。)