Sympy 表达式简化

Sympy expression simplification

我正在求解矩阵和特征向量随时间变化的特征值问题。该矩阵的维度为 8x8,并且是埃尔米特矩阵。时间相关矩阵的形式为:

import sympy as sp
t, lbd = sp.symbols(r't,\lambda', real=True)

Had = ...
print(repr(Had))

Matrix([[2*t,0, 0, 0, 0, 0, 0,0],
[ 0,-2*t, 2*t*(1 - t), 0, 0, 0,0,0],
[0, 2*t*(1 - t),0,0, 2 - 2*t, 0,0,0],
[0,0,0,0, 0, 2 - 2*t, 0,0],
[0,0,2 - 2*t,0,0,0,0,0],
[0,0,0, 2 - 2*t,0,0, 2*t*(1 - t),0],
[0,0,0,0,0, 2*t*(1 - t),-2*t,0],
[0,0,0,0,0,0,0,2*t]])

现在特征多项式有以下:

 P = p.simplify(sp.collect(sp.factor(Had.charpoly(lbd).as_expr()),lbd))

并得到

然后我选择第二项并找到 lambda 的解决方案:

P_list = sp.factor_list(P)
a,b = P_list[1]
eq,exp = sp.simplify(b)
sol = sp.solve(eq)

有了这个,我得到了一个列表中的根:

r_list = []
for i in range(len(sol)):
    a = list(sol[i].values())
    r_list.append(a[0]) 

使用sp.eigenvecs解决问题:

val_mult_vec = Had.eigenvects()
e_vals = []
mults = []
e_vecs = []
for i in range(len(val_mult_vec)):
    val, mult, [vec_i, vec_j] = val_mult_vec[i]
    e_vals.append(val)
    e_vals.append(val)
    mults.append(mult)
    e_vecs.append(vec_i)
    e_vecs.append(vec_j)

求解特征向量我得到像这样的复杂表达式:

但我知道这个复杂的表达式可以用特征多项式中第二项的解来表示,如下所示:

其中 r1 是该方程的根之一。有了特征多项式的解决方案,我怎样才能像使用 sympy 的最后一张图像那样以简化的方式重写特征向量?根据 r_list[j]

重写 e_vec[i]

您似乎想要获得特征向量的紧凑版本。

接收:

  1. 我们可以创建与特征值数量一样多的符号。每个符号代表一个特征值。
  2. 遍历特征向量,并为其每个元素用相应的符号替换长特征值表达式。
r_symbols = symbols("r0:%s" % len(e_vals))
final_evecs = []
for vec, val, s in zip(e_vecs, e_vals, r_symbols):
    final_evecs.append(
        vec.applyfunc(lambda t: t.subs(val, s))
    )

final_evecs 是一个包含紧凑符号的特征向量的列表。

让我们测试一个输出:

final_evecs[7]