为什么 matlab 和 python 中的特征向量计算不匹配?

问题描述 投票:0回答:2

Matlab:

m1 = [ 333.33333333  83.33333333   0. ;  83.33333333 333.33333333  83.33333333 ;  0.   3.33333333 166.66666667]
k1 = [ 800. -400.    0.; -400.  800. -400.;   0. -400.  400.]
[vec, val] = eig(m1, k1)

vec =

   -0.0106   -0.0289    0.0394
    0.0183   -0.0000    0.0683
   -0.0211    0.0289    0.0789

蟒蛇:

import scipy
import numpy as np
m1 = np.array[[333.33333333,  83.33333333,  0.], [ 83.33333333, 333.33333333, 83.33333333], [0., 83.33333333, 166.66666667]]
k1 = np.array[[800., -400.,  0.], [-400.,  800., -400.], [0., -400.,  400.]]
val, vec = scipy.linalg.eig(m1, k1)

vec = 
[[ 3.53553391e-01, -7.07106781e-01,  3.53553391e-01], 
[ 6.12372436e-01,  1.88119544e-16, -6.12372436e-01], 
[ 7.07106781e-01,  7.07106781e-01,  7.07106781e-01]]

所以 matlab 和 python 特征向量

vec
不匹配。 Matlab 文档

[V,D] = eig(A,B) 返回广义特征值的对角矩阵 D 和全矩阵 V,其列是相应的权利 特征向量,所以

A*V = B*V*D
.

m1 * vec = k1 * vec * val
满足matlab输出但不满足python输出。我如何使用 python、numpy 获得与 matlab 给出的相似特征向量?

python numpy matlab scipy
2个回答
3
投票

特征向量不是唯一的;如果

x
是特征向量,则
a * x
仍然是任何非零标量
a
.

的特征向量

看python和matlab的两个结果;来自 matlab 的

vec
的第一列看起来像来自 python 的
vec
第三列的缩放版本。 matlab 的第二列似乎是 python 的第二列的缩放版本(召回
1.88119544e-16
几乎为零)。第三列对应于第一列。所以我的猜测是来自matlab的
val
是来自python的
val
的反转版本;我无法验证这一点,因为我现在没有 matlab,但你可以验证这一点。

同样在 python 中,请记住

*
是逐元素乘法(即 matlab 中的
.*
)。您可以使用
@
进行矩阵乘法。

import scipy.linalg
import numpy as np
m1 = np.array([[333.33333333,  83.33333333,  0.], [ 83.33333333, 333.33333333, 83.33333333], [0., 83.33333333, 166.66666667]])
k1 = np.array([[800., -400.,  0.], [-400.,  800., -400.], [0., -400.,  400.]])
val, vec = scipy.linalg.eig(m1, k1)

print(m1 @ vec)
print(k1 @ vec * val)

正如你在下面的输出中看到的,我们有相同的输出(虚部是

0.j
,所以你可以忽略它)。

输出:

[[ 1.68882167e+02 -2.35702260e+02  6.68200939e+01]
 [ 2.92512493e+02 -3.14270210e-09 -1.15735798e+02]
 [ 1.68882167e+02  1.17851130e+02  6.68200939e+01]]
[[ 1.68882167e+02+0.j -2.35702260e+02+0.j  6.68200939e+01+0.j]
 [ 2.92512493e+02+0.j -3.14263578e-09+0.j -1.15735798e+02+0.j]
 [ 1.68882167e+02+0.j  1.17851130e+02+0.j  6.68200939e+01+0.j]]

0
投票

首先,如果您的模型是具有

m1
质量矩阵和
k1
刚度矩阵的弹簧质量系统,您应该将您的 matlab eig 调用修复为

[vec, val] = eig(k1, m1)

那么,上面已经说过,特征向量不是唯一的,所以你可以用你想要的任何值对它们进行归一化。例如,您可以对每个特征向量进行归一化,使其按其最大值进行归一化,以便每个向量的最大向量值为 1.0。 Matlab 进行 2 范数归一化。 scipy 可能会进行不同的标准化。你仍然可以得到matlab的结果。在谷歌中检查本征向量和 2 范数归一化,你可以找到如何做到这一点。我现在不记得了,但我以前做过。 另外,您的代码中可能已经正确了,但是在上面的问题中,您忘记了

np.array
之后的括号。应该是
np.array([[800., -400.,  0.], [-400.,  800., -400.], [0., -400.,  400.]])

© www.soinside.com 2019 - 2024. All rights reserved.