给定 N x N 对称矩阵C
和 N x N 对角矩阵I
,找到等式{{的解1}}。换句话说,要找到det(λI-C)=0
的(广义)特征值。
我知道如何使用内置函数在MATLAB中解决这个问题:
第一路:
C
第二路:
function lambdas=eigenValues(C,I)
syms x;
lambdas=sort(roots(double(fliplr(coeffs(det(C-I*x))))));
但是,我需要使用Python。在NumPy和SymPy中有类似的功能,但是,根据文档(numpy,sympy),它们只需要一个矩阵 C 作为输入。但是,结果与Matlab产生的结果不同。而且,SymPy制作的符号解决方案也没有用。也许我做错了什么?如何找到解决方案?
%INPUT
[V,D]=eig(C,I);
%RESULT
I =
2 0 0
0 6 0
0 0 5
C =
4 7 0
7 8 -4
0 -4 1
[v,d]=eig(C,I)
%INPUT
v =
-0.3558 -0.3109 -0.5261
0.2778 0.1344 -0.2673
0.2383 -0.3737 0.0598
d =
-0.7327 0 0
0 0.4876 0
0 0 3.7784
%RESULT
I=np.matrix([[2,0,0],
[0,6,0],
[0,0,5]])
C=np.matrix([[4,7,0],[7,8,-4],[0,-4,1]])
np.linalg.eigh(C)
答案 0 :(得分:1)
至少如果I
具有正对角线条目,您可以简单地解决转换后的系统:
# example problem
>>> A = np.random.random((3, 3))
>>> A = A.T @ A
>>> I = np.identity(3) * np.random.random((3,))
# transform
>>> J = np.sqrt(np.einsum('ii->i', I))
>>> B = A / np.outer(J, J)
# solve
>>> eval_, evec = np.linalg.eigh(B)
# back transform result
>>> evec /= J[:, None]
# check
>>> A @ evec
array([[ -1.43653725e-02, 4.14643550e-01, -2.42340866e+00],
[ -1.75615960e-03, -4.17347693e-01, -8.19546081e-01],
[ 1.90178603e-02, 1.34837899e-01, -1.69999003e+00]])
>>> eval_ * (I @ evec)
array([[ -1.43653725e-02, 4.14643550e-01, -2.42340866e+00],
[ -1.75615960e-03, -4.17347693e-01, -8.19546081e-01],
[ 1.90178603e-02, 1.34837899e-01, -1.69999003e+00]])
OP的例子。重要提示:必须使用np.array
I
和C
,np.matrix
将无效。
>>> I=np.array([[2,0,0],[0,6,0],[0,0,5]])
>>> C=np.array([[4,7,0],[7,8,-4],[0,-4,1]])
>>>
>>> J = np.sqrt(np.einsum('ii->i', I))
>>> B = C / np.outer(J, J)
>>> eval_, evec = np.linalg.eigh(B)
>>> evec /= J[:, None]
>>>
>>> evec
array([[-0.35578356, -0.31094779, -0.52605088],
[ 0.27778714, 0.1343625 , -0.267297 ],
[ 0.23826117, -0.37371199, 0.05975754]])
>>> eval_
array([-0.73271478, 0.48762792, 3.7784202 ])
如果I
有正面和负面条目,请使用eig
代替eigh
,然后再将平方根转换为complex
dtype
。
答案 1 :(得分:1)
与其他答案不同,我假设通过符号 I 表示单位矩阵, Ix = x 。
您要解决的问题 Cx =λIx,是所谓的标准特征值问题,
并且大多数特征值求解器解决了该格式中描述的问题,因此
Numpy函数具有签名eig(C)
。
如果您的 C 矩阵是对称矩阵,并且您的问题确实是一个标准的特征值问题,我建议使用numpy.linalg.eigh
,这是针对此类问题进行优化的。 / p>
相反,如果你的问题确实是一个广义的特征值问题,例如,频率方程 Kx =ω²Mx你可以使用scipy.linalg.eigh
,它支持那种类型的问题陈述对称矩阵。
eigvals, eigvecs = scipy.linalg.eigh(C, I)
关于特征值的差异,Numpy实现不对它们的排序提供保证,因此它可能只是一个不同的排序,但如果你的问题确实是一个普遍的问题( I 不是身份矩阵......)解决方案当然是不同的,你必须使用eigh
的Scipy实现。
如果差异在特征向量内,请记住特征向量在任意比例因子中是已知的,并且再次排序可能是未定义的(但是,当然,它们的顺序与您具有特征值的顺序相同) ) - scipy.linalg.eigh
的情况略有不同,因为在这种情况下,特征值被排序,特征向量相对于第二个矩阵参数(在您的示例中为 I )进行归一化。
Ps:scipy.linalg.eigh
行为(即,排序的特征值和归一化的特征向量)非常方便 my 用例,我用它来解决标准的特征值问题。
答案 2 :(得分:0)
使用SymPy:
>>> from sympy import *
>>> t = Symbol('t')
>>> D = diag(2,6,5)
>>> S = Matrix([[ 4, 7, 0],
[ 7, 8,-4],
[ 0,-4, 1]])
>>> (t*D - S).det()
60*t**3 - 212*t**2 - 77*t + 81
计算完全根:
>>> roots = solve(60*t**3 - 212*t**2 - 77*t + 81,t)
>>> roots
[53/45 + (-1/2 - sqrt(3)*I/2)*(312469/182250 + sqrt(797521629)*I/16200)**(1/3) + 14701/(8100*(-1/2 - sqrt(3)*I/2)*(312469/182250 + sqrt(797521629)*I/16200)**(1/3)), 53/45 + 14701/(8100*(-1/2 + sqrt(3)*I/2)*(312469/182250 + sqrt(797521629)*I/16200)**(1/3)) + (-1/2 + sqrt(3)*I/2)*(312469/182250 + sqrt(797521629)*I/16200)**(1/3), 53/45 + 14701/(8100*(312469/182250 + sqrt(797521629)*I/16200)**(1/3)) + (312469/182250 + sqrt(797521629)*I/16200)**(1/3)]
计算根的浮点近似值:
>>> for r in roots:
... r.evalf()
...
0.487627918145732 + 0.e-22*I
-0.73271478047926 - 0.e-22*I
3.77842019566686 - 0.e-21*I
请注意,根是真实的。