2015-07-02 9 views
0

Я хочу диагонализации матрицы с Python, вот мой сценарий:питона: проверить, если diagonalisable матрица

import scipy.linalg as lg 
vp = lg.eig(A)  # eigen values and vectors 
D = N.diag(vp[0]) # diagonalisation of A from its eigen values 
P=vp[1]   # such as A = P.D.P(-1) 
Pm1=lg.inv(P) 

Однако я подозреваю, что в не diagonalisable, но это не мешает Python из расчета D, P и P (-1) без каких-либо проблем ... Более того, коэффициенты в D являются комплексными числами, нормальны ли они в A реальными? Нет ли способа проверить, является ли этот массив диагонализируемым или нет?

Большое спасибо заранее

ответ

0

Если A не были диагонализуемыми, векторы в P были бы линейно зависимыми. Однако из-за численных ошибок они могут быть очень близки к линейной зависимости.

Например, рассмотрим

P = array([[1, 0],[1, 0.001]]) 

пусть

Pm1 = inv(P) 

Тогда P * Pm1 - eye(2) будет далеко от нуля

[[ 0.  0.] 
[-1000.  0.]] 

Всегда смотрите на обусловленности матрицы при вычислении обратный. Например, cond(P) = 2000.5, который является очень большим числом.

Также для некоторых матриц вывод eig() снова из-за числовых ошибок может быть очень далек от истинного списка собственных значений.

Что касается комплексных собственных значений, напомним, что вещественная матрица может иметь комплексные собственные значения, хотя они будут иметь комплексно сопряженные пары. Поскольку поле вещественных чисел не является алгебраически замкнутым, вы не можете ожидать, что собственные значения всегда будут вещественными, если только матрица A не симметрична.

2

Вы можете использовать SymPy. Он имеет функцию is_diagonalizable.

Он проверяет, является ли матрица диагонализируемой.

+0

Это нормально с целыми и рациональными записями матрицы, но обратите внимание, что в плавающей точке он имеет обычные проблемы с плавающей запятой (а алгоритмы, используемые в sympy, не являются оптимальными для этого случая, намного медленнее, чем np.linalg.eig). Рассмотрим 'sympy.Matrix ([[1, 1], [1e-100, 1]]). Is_diagonalizable() == False'. –

+0

from sympy import Matrix as Mx if Mx (A) .is_diagonalizable() == False: print «A not diago» – Neko

+0

жаль, что я отправил его, прежде чем закончил. Я добавил код чуть выше, чтобы попытаться получить ошибку: «Файл» /usr/lib/pymodules/python2.6/sympy/matrices/matrices.py », строка 1477, в __getattr__ поднять AttributeError()" из раздела " if "line ... – Neko

3

Диагонализируемые матрицы плотны в C^nxn. То, что это означает для вычислений с плавающей точкой, состоит в том, что ошибка округления делает диагонализируемые матрицы --- результат для eig(A) равен eig(Ap), где |A - Ap| <= floating point error и Ap диагонализуемо. Такие результаты дают стандартные числовые алгоритмы, которые вычисляют собственные значения.

Собственные значения реальной матрицы могут быть сложными, например. для [1 -2; 1 1].

Полностью надежное обнаружение недиагонализируемых матриц может быть выполнено, если вы используете точную арифметику; в плавающей точке вы можете, возможно, рассмотреть диагонализируемые матрицы, которые «близки» к недиагонализируемым, как недиагонализируемые (см., например, https://dl.acm.org/citation.cfm?id=355912).

РЕДАКТИРОВАТЬ: одна мера близости к не-диагонализируемости в плавающей точке может быть получена путем вычисления условия числа матрицы собственных векторов, w, V = np.linalg.eig(A); c = np.linalg.cond(V). Если c большой, около 1/eps ~ 10**16, матрица численно близка к недиагонализируемой.