#python #numpy #matlab #scipy
Вопрос:
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. Как я могу получить аналогичные собственные векторы, заданные matlab, используя python, numpy?
Комментарии:
1. Я думаю, что эта разница обсуждалась в предыдущих статьях, хотя я не обращал на это особого внимания. Выглядит как векторы для обоих столбцов a, но является ли нормализация одинаковой? Как насчет порядка?
np.linalg.eig
похоже, у вас есть более полная документация.
Ответ №1:
Собственные векторы не уникальны; если x
это собственный вектор, то a * x
он по-прежнему является собственным вектором для любого ненулевого скаляра a
.
Посмотрите на два результата из python и matlab; первый столбец vec
из matlab выглядит как масштабированная версия третьего столбца vec
из python. Второй столбец из matlab, по-видимому, является масштабированной версией второго столбца из python (отзыв 1.88119544e-16
почти равен нулю). Третий столбец соответствует первому столбцу. Поэтому я предполагаю, что val
из matlab-это обратная версия val
из python; Я не могу это проверить, потому что у меня сейчас нет 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]]