python - Solve for eigenvectors "manually" using Sympy
问题描述
Setup
from sympy import Matrix, symbols, eye, factor, solve, simplify, solveset
from fractions import Fraction
_lambda = symbols("lambda")
x1, x2 = symbols("x_1, x_2")
Here's the matrices I'm working with
S = Matrix([[5,4],[4,5]])
M = Matrix([[1,0],[0,4]])
H = M**Fraction(-1,2)*S*M**Fraction(-1,2)
The next step I'd like to do is something like this
eigen = []
for eigenvalue in solve((S-_lambda*M).det()):
eigen.append((
eigenvalue,
solve((S-_lambda*M).subs(_lambda,eigenvalue) * Matrix([x1,x2]))
))
But sympy can't find the answer... It probably just doesn't understand what I'm asking for but I'm not sure how to tell it more clearly.
print(eigen)
> [(25/8 - sqrt(481)/8, {x_1: nan, x_2: nan}),
(sqrt(481)/8 + 25/8, {x_1: nan, x_2: nan})]
解决方案
I'm not sure I quite understand what you are trying to do. The matrix H
is unused. It looks like you want the eigenvalues and eigenvectors of the matrix S
but I'm not sure what the M
matrix is doing. I'll assume that you want to find the eigenvalues and eigenvectors of S
.
We have the matrix S
:
In [60]: S = Matrix([[5,4],[4,5]])
In [61]: S
Out[61]:
⎡5 4⎤
⎢ ⎥
⎣4 5⎦
We first find its eigenvalues:
In [62]: l = Symbol('lambda')
In [63]: det(S - l*eye(2))
Out[63]:
2
(5 - λ) - 16
In [64]: l1, l2 = roots(_, l)
In [65]: l1
Out[65]: 9
In [66]: l2
Out[66]: 1
Now each of these eigenvalues has a corresponding eigenvector. Actually it's not a single eigenvector but rather a 1D family of vectors. If the vector is [x1, x2]
then we can't uniquely solve for x1
and x2
because there is an infinite family of solutions. Using solve
therefore gives a parametrised solution for x1
in terms of x2
:
In [67]: x1, x2 = symbols('x1, x2')
In [68]: solve((S - l1*eye(2)) * Matrix([x1, x2]), [x1, x2])
Out[68]: {x₁: x₂}
This tells us that a vector [x1, x2]
will be a solution provided x1 == x2
. Hence we have the family of eigenvectors [a, a]
with eignevalue l1
(9):
In [69]: S*Matrix([1, 1])
Out[69]:
⎡9⎤
⎢ ⎥
⎣9⎦
More directly what we actually want is the nullspace of S - l*I
which we can compute as
In [70]: (S - l1*eye(2)).nullspace()
Out[70]:
⎡⎡1⎤⎤
⎢⎢ ⎥⎥
⎣⎣1⎦⎦
In [71]: (S - l2*eye(2)).nullspace()
Out[71]:
⎡⎡-1⎤⎤
⎢⎢ ⎥⎥
⎣⎣1 ⎦⎦
The nullspace
method returns a list of vectors that are a basis for the nullspace. In this context that means that they are a basis for the eigenspace of the given eigenvalue. Since we have only one vector it is a 1D eigenspace consisting of all scalar multiples of [1, 1]
(or [-1, 1]
for l2
). If there were repeated eigenvalues then it would be possible that the nullspace could have greater dimension.
推荐阅读
- node.js - 如何根据选择键结果从 iso 中搜索数据并触发新功能?
- r - ggplot2 跳过 x 轴上的刻度值
- javascript - 粘贴(图像)文件大小比原始文件大得多
- typescript - 测试期间的Vue无限循环
- mysql - 为什么 MySQL begin-while-end while-end 语句在 Navicat 中不起作用?
- tensorflow - 为什么线性和逻辑回归的系数不同?
- mysql - 如何存储用户统计数据,如力量、活力(mysql、视频游戏)
- python - 您如何在 MacOS 上突出显示蓝色的 tkinter 按钮
- java - 骆驼
发送字符串 - r - 在使用 R 突变和替换 NA 时分配自定义数字