2015-02-25 2 views
2

По определению квадратная матрица с нулевым определителем не должна быть обратимой. Однако по какой-то причине, после генерации ковариационной матрицы, я делаю ее обратную, но взятие определителя ковариационной матрицы заканчивается выходом 0.0.numpy: Можно ли инвертировать матрицу нулевого детерминанта?

Что может быть потенциально не так? Должен ли я не доверять выходу определителя или не доверять обратной матрице ковариации? Или оба?

Отрывок из моего кода:

cov_matrix = np.cov(data) 
adjusted_cov = cov_matrix + weight*np.identity(cov_matrix.shape[0]) # add small weight to ensure cov_matrix is non-singular 
inv_cov = np.linalg.inv(adjusted_cov) # runs with no error, outputs a matrix 
det = np.linalg.det(adjusted_cov) # ends up being 0.0 
+0

Не могли бы вы показать нам пример ввода и вывода? Ваш комментарий подразумевает, что вы пытаетесь сделать матрицу неособой, что означало бы, что матрица должна иметь действительный обратный. – BobChao87

+0

Ошибки округления? –

+0

Хмм, мой набор данных состоит из 28х28 изображений, где я использую необработанные пиксели в качестве функций, поэтому входной вывод был бы слишком большим для копирования, я думаю, (784x487 ковариационных матриц). Я считаю, что добавление веса приводит к тому, что имеет действительный обратный - однако почему же тогда определяется детерминант? Если я не добавляю вес, я получаю ошибку сингулярной линейной алгебры. Будет ли ошибка округления применяться к определителю, где округляется до 0.0? – kk415kk

ответ

3

numerical inversion of matrices не предполагает вычисления определителя. (Cramer's formula для обратного нецелесообразно для больших матриц.) Таким образом, тот факт, что детерминант оценивает 0 (из-за недостаточной точности поплавков), не является препятствием для процедуры инверсии матрицы.

Вслед за комментариями по BobChao87, вот упрощенный тест (Python 3.4 консоли, NumPy импортируется как нп)

A = 0.2*np.identity(500) 
np.linalg.inv(A) 

Выход: матрица с 5 на главной диагонали, что является правильным обратный по А.

np.linalg.det(A) 

Выход: 0,0, поскольку определитель (0.2^500) слишком мал, чтобы быть представленным в двойной точности.

Возможное решение - это вид pre-conditioning (здесь, только перемасштабирование): перед вычислением определителя умножьте матрицу на коэффициент, который сделает его записи ближе к 1 в среднем. В моем примере np.linalg.det(5*A) возвращает 1.

Конечно, используя коэффициент 5 здесь, обман, но np.linalg.det(3*A) также возвращает ненулевое значение (около 1,19е-111). Если вы попробуете np.linalg.det(2**k*A) для k, проходящего через скромные положительные целые числа, вы, скорее всего, ударите тот, который будет возвращать ненулевое значение. Тогда вы узнаете, что детерминант исходной матрицы был примерно 2 ** (- k * n) по сравнению с выходом, где n - размер матрицы.