【问题标题】:sympy: simplify a larger expression with Binomial formula and quadratic complementsympy:使用二项式公式和二次补码简化更大的表达式
【发布时间】:2016-11-18 03:24:48
【问题描述】:

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

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)))

这个计算对我来说真的很重要,因为我必须评估特征值是否

让我告诉你我到现在为止做了什么。

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... 我也使用了determinat.factor() 并在之后解决了它,但这种方法的最佳结果与J.eigenvals().keys()[0].factor() 相同。

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

提前谢谢你

亚历克斯

【问题讨论】:

  • factor 在 SymPy 中的意思是“分解多项式的乘积”。所以它只有在你给它提供一个产品的术语子集时才会起作用。

标签: python sympy


【解决方案1】:

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

我在 SymPy 问题跟踪器中打开了 this issue 关于它的信息。我展示了一种可以接近的方法(这里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 排除在其余条款之外)。

【讨论】:

  • 好的,谢谢您的回答。不幸的是,我正在编写一个脚本,结果表达式有时会有所不同。好吧,我想我必须手动简化我的表达方式。 --感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 2020-11-28
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
相关资源
最近更新 更多