2015-02-25 3 views
2

Я использую numpy для вычисления собственных значений и собственных векторов симметричного квадратного массива. Мой массив:Как вычисляются числовые значения собственных чисел и собственные векторы

L = [[ 2. -1. -1. 0. 0. 0.] 
    [-1. 3. 0. -1. 0. -1.] 
    [-1. 0. 2. -1. 0. 0.] 
    [ 0. -1. -1. 3. -1. 0.] 
    [ 0. 0. 0. -1. 2. -1.] 
    [ 0. -1. 0. 0. -1. 2.]] 

Результаты при выполнении numpy.linalg.eig(L) показаны ниже

собственные:

[ 5.00000000e+00, 
    3.96872205e-16, 
    1.00000000e+00, 
    2.00000000e+00, 
    3.00000000e+00, 
    3.00000000e+00 ] 

собственные векторы:

[[ -2.88675135e-01 4.08248290e-01 -5.00000000e-01 4.08248290e-01 -4.36632863e-01 4.44614891e-01] 
[ 5.77350269e-01 4.08248290e-01 -3.34129212e-16 4.08248290e-01 -1.08813217e-01 -5.41271705e-01] 
[ 2.88675135e-01 4.08248290e-01 -5.00000000e-01 4.08248290e-01 5.45446080e-01 9.66568140e-02] 
[ -5.77350269e-01 4.08248290e-01 1.06732810e-16 4.08248290e-01 -1.08813217e-01 -5.41271705e-01] 
[ 2.88675135e-01 4.08248290e-01 5.00000000e-01 4.08248290e-01 -4.36632863e-01 4.44614891e-01] 
[ -2.88675135e-01 4.08248290e-01 5.00000000e-01 -4.08248290e-01 5.45446080e-01 9.66568140e-02]] 

Результаты близки (если нормированы) к те, которые вы получаете, когда вы analytically вычислите их, но некоторые ошибки кажутся мне вносят как в собственные значения, так и в собственные векторы. Есть ли способ обойти эти ошибки с помощью numpy?

Откуда берутся эти ошибки? Какой алгоритм использует numpy?

+0

Это выглядит довольно точно для меня – Fabricator

+0

второе собственное значение равно 3.96872205e-16 вместо 0. Также в 3-м собственном векторе должно быть два нуля, вместо этого есть -3.34129212e-16 и 1.06732810e-16. – igavriil

+0

Это ошибки округления, которые почти равны нулю. Если 'x' - ваш результат, вы можете избавиться от всех этих ошибок округления с помощью' np.where (x <1e-15, 0, x) ' – mty

ответ

8

Если вы хотите, точность аналитического вывода, вам нужно будет использовать symbolic computation, который является то, что Wolfram Alpha, Mathematica, и связанной с ними использования систем. Например, в Python вы можете посмотреть на SymPy.

numerical computation, который встроен в пакет NumPy, который вы используете, по своей сути подвержен малым ошибкам и превратностям floating point numerical representations. Такие ошибки и приближения неизбежны при численных вычислениях.

Вот пример:

from sympy import Matrix, pretty 

L = Matrix([[ 2, -1, -1, 0, 0, 0,], 
    [-1, 3, 0, -1, 0, -1,], 
    [-1, 0, 2, -1, 0, 0,], 
    [ 0, -1, -1, 3, -1, 0,], 
    [ 0, 0, 0, -1, 2, -1,], 
    [ 0, -1, 0, 0, -1, 2,]]) 

print "eigenvalues:" 
print pretty(L.eigenvals()) 
print 
print "eigenvectors:" 
print pretty(L.eigenvects(), num_columns=132) 

Урожайность:

eigenvalues: 
{0: 1, 1: 1, 2: 1, 3: 2, 5: 1} 

eigenvectors: 
⎡⎛0, 1, ⎡⎡1⎤⎤⎞, ⎛1, 1, ⎡⎡-1⎤⎤⎞, ⎛2, 1, ⎡⎡1 ⎤⎤⎞, ⎛3, 2, ⎡⎡1 ⎤, ⎡0 ⎤⎤⎞, ⎛5, 1, ⎡⎡1 ⎤⎤⎞⎤ 
⎢⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥ ⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟⎥ 
⎢⎜  ⎢⎢1⎥⎥⎟ ⎜  ⎢⎢0 ⎥⎥⎟ ⎜  ⎢⎢1 ⎥⎥⎟ ⎜  ⎢⎢-1⎥ ⎢-1⎥⎥⎟ ⎜  ⎢⎢-2⎥⎥⎟⎥ 
⎢⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥ ⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟⎥ 
⎢⎜  ⎢⎢1⎥⎥⎟ ⎜  ⎢⎢-1⎥⎥⎟ ⎜  ⎢⎢-1⎥⎥⎟ ⎜  ⎢⎢0 ⎥ ⎢1 ⎥⎥⎟ ⎜  ⎢⎢-1⎥⎥⎟⎥ 
⎢⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥ ⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟⎥ 
⎢⎜  ⎢⎢1⎥⎥⎟ ⎜  ⎢⎢0 ⎥⎥⎟ ⎜  ⎢⎢-1⎥⎥⎟ ⎜  ⎢⎢-1⎥ ⎢-1⎥⎥⎟ ⎜  ⎢⎢2 ⎥⎥⎟⎥ 
⎢⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥ ⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟⎥ 
⎢⎜  ⎢⎢1⎥⎥⎟ ⎜  ⎢⎢1 ⎥⎥⎟ ⎜  ⎢⎢-1⎥⎥⎟ ⎜  ⎢⎢1 ⎥ ⎢0 ⎥⎥⎟ ⎜  ⎢⎢-1⎥⎥⎟⎥ 
⎢⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥ ⎢ ⎥⎥⎟ ⎜  ⎢⎢ ⎥⎥⎟⎥ 
⎣⎝  ⎣⎣1⎦⎦⎠ ⎝  ⎣⎣1 ⎦⎦⎠ ⎝  ⎣⎣1 ⎦⎦⎠ ⎝  ⎣⎣0 ⎦ ⎣1 ⎦⎦⎠ ⎝  ⎣⎣1 ⎦⎦⎠⎦ 

Хотя ASCII довольно-принтер, гм, прилагает все усилия, чтобы обеспечить даже квази-красивый вывод, вы можете увидеть, что вы получают символически вычисленный, точный вывод. Если вы используете IPython и настроили его для вывода LaTeX, вы получите get a nicer display.

4

Похоже, что он использует итеративный метод из LAPACK. Он сходится к решению. Если он не сходится, он генерирует исключение.

Поскольку вы знаете, что матрица симметрична, вы можете сделать лучше с помощью eigh. http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.eigh.html

Документация Страница: http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.eig.html

Исходный код: https://github.com/numpy/numpy/blob/v1.9.1/numpy/linalg/linalg.py#L982

+0

Да, похоже, что это семейство LAPACK * geev для' eig' и * syevd и * heevd для реального значения 'eigh'. См. Https://github.com/numpy/numpy/blob/v1.9.1/numpy/linalg/umath_linalg.c.src – IanH

+0

numpy.linalg.eigh не изменяет результат. Кажется, что использует тот же численный метод – igavriil

+0

@igavriil, проблемы, которые вы видите, являются следствием того, что это численный метод вообще.Вычисления с плавающей точкой приводят к некоторым неточностям. Если вам нужна точная арифметика, вам придется использовать sympy, как предложено в другом ответе. Это отвечает «как numpy вычисляет собственные значения и собственные векторы?» 'eigh' должен быть более точным, когда он применим, но он по-прежнему является числовым методом с ошибкой с плавающей запятой. – IanH

Смежные вопросы