Есть ли быстрый способ инвертировать матрицу в Matlab?

У меня есть много больших (около 5000 x 5000) матриц, которые мне нужно инвертировать в Matlab. Мне действительно нужен обратный, поэтому я не могу использовать вместо него mldivide, который намного быстрее решает Ax = b только для одного b.

Мои матрицы возникли из-за проблемы, которая означает, что у них есть несколько хороших свойств. Во-первых, их определитель равен 1, поэтому они определенно обратимы. Однако они не поддаются диагонализации, иначе я бы попытался их диагонализировать, перевернуть, а затем вернуть обратно. Все их записи - действительные числа (на самом деле рациональные).

Я использую Matlab для получения этих матриц и для всего этого, что мне нужно делать с их инверсиями, поэтому я бы предпочел способ ускорить Matlab. Но если я могу использовать другой язык, который будет быстрее, то, пожалуйста, дайте мне знать. Я не знаю много других языков (немного, кроме C, и немного, кроме Java), поэтому, если это действительно сложно на каком-то другом языке, я, возможно, не смогу его использовать. Пожалуйста, предложите это на всякий случай.


person Daniel    schedule 28.06.2011    source источник
comment
Подпрограммы линейной алгебры Matlab обычно довольно оптимизированы, поэтому вы можете не получить никакого улучшения скорости от повторной реализации чего-либо вручную на другом языке. Однако вы можете взглянуть на Eigen (c ++). Для Matlab вы можете попробовать инструментарий параллельной обработки.   -  person Jonas    schedule 28.06.2011
comment
Кроме того, может помочь, если вы сообщите нам какие свойства есть у вашей матрицы или как вы их получаете. Возможно, некоторые манипуляции с линейной алгеброй перед подключением ее к MATLAB могут помочь вам больше, чем любая библиотека.   -  person abcd    schedule 28.06.2011
comment
Возможно, вы захотите подробнее рассказать о вашем конкретном случае. Вы на 100% уверены, что вам нужно обратное? Спасибо   -  person eat    schedule 28.06.2011
comment
Я предполагаю, что они редкие, поскольку большинство реальных проблем не связаны с полными матрицами 5000 x 5000. Предполагая, что это так, можете ли вы каким-то образом использовать разреженную структуру? Вы изучили это?   -  person Chris A.    schedule 28.06.2011
comment
Насколько разрежена матрица? Есть ли у матрицы какая-то особая форма или взаимосвязь между записями?   -  person nibot    schedule 28.06.2011
comment
А как насчет L-U-разложения, если вы сказали, что вам нужна каждая матрица несколько раз для решения уравнения? mathworks.com/help/techdoc/ref/lu.html   -  person Luka Rahne    schedule 28.06.2011
comment
Вам действительно нужно обратное? Не инвертируйте эту матрицу, Я бы сказал, что, вероятно, есть другие способы решить проблему, которую вы действительно хотите решить.   -  person HelloGoodbye    schedule 25.05.2016


Ответы (3)


Мне действительно нужен обратный, поэтому я не могу использовать вместо него mldivide, ...

Это неправда, потому что вы все еще можете использовать mldivide, чтобы получить обратное. Обратите внимание, что A-1 = A-1 * I. В MATLAB это эквивалентно

invA = A\speye(size(A));

На моей машине это занимает около 10,5 секунд для 5000x5000 матрицы. Обратите внимание, что в MATLAB есть функция inv для вычисления обратной матрицы . Хотя это займет примерно столько же времени, это менее эффективно с точки зрения числовой точности (подробнее см. Ссылку).


Во-первых, их определитель равен 1, поэтому они определенно обратимы.

Вместо det(A)=1, это номер условия вашей матрицы, который определяет, насколько точным или стабильным обратное будет. Обратите внимание, что det(A)=∏i=1:n λi. Таким образом, просто установив λ1=M, λn=1/M и λi≠1,n=1, вы получите det(A)=1. Однако, как M → ∞, cond(A) = M2 → ∞ и λn → 0, это означает, что ваша матрица приближается к сингулярности, и при вычислении обратного будут большие числовые ошибки.


Мои матрицы возникли из-за проблемы, которая означает, что у них есть несколько хороших свойств.

Конечно, есть и другие более эффективные алгоритмы, которые можно использовать, если ваша матрица разреженная или имеет другие благоприятные свойства. Но без какой-либо дополнительной информации о вашей конкретной проблеме сказать больше не о чем.


Я бы предпочел способ ускорить Matlab

MATLAB использует исключение Гаусса для вычисления обратной матрицы общей матрицы (полный ранг, не разреженный, без каких-либо специальных свойств) с использованием mldivide, и это Θ(n3), где n - размер матрицы. Итак, в вашем случае n=5000 и есть 1.25 x 1011 операций с плавающей запятой. Итак, на разумной машине с вычислительной мощностью около 10 Гфлопс вам потребуется не менее 12,5 секунд для вычисления обратного, и выхода из этого нет, если только вы не воспользуетесь «специальными свойствами» (если они пригодны для использования )

person abcd    schedule 28.06.2011
comment
Действительно ли это дает какую-то пользу? - person nibot; 28.06.2011
comment
@yoda: Вы утверждаете, что ваш метод занимает 10,5 секунд. Мне любопытно узнать, сколько времени inv занимает один и тот же ввод. - person PengOne; 28.06.2011
comment
@PengOne: inv занимает примерно такое же время (~ 10 секунд), но менее точно. См. inv, где они говорят об этом. - person abcd; 28.06.2011
comment
@yoda: Ваш ответ (который мне нравится, кстати) подразумевает, что использование mldivide быстрее, когда на самом деле вы имеете в виду, что это более точно и не менее быстро. Об этом стоит упомянуть. - person PengOne; 28.06.2011
comment
@PengOne: Я только что отредактировал свой ответ и обязательно добавил его. - person abcd; 28.06.2011
comment
Общее руководство - использовать A\b вместо inv(A)*b для решения Ax=b , когда b вектор. Когда b является матрицей - в частности, тождественной матрицей, как предлагает йода - я думаю, что форма mldivide не имеет никакой пользы. - person nibot; 28.06.2011
comment
@nibot: Я не проводил всестороннего тестирования, но mldivide по-прежнему имеет немного лучшую числовую точность, чем inv, и в этом случае, хотя это не так резко, как при решении линейной системы уравнений. Мы можем обсуждать, насколько «хорошо» достаточно хорошо для инженера, но пока я принимаю вашу точку зрения (хотя я бы не назвал это бесполезным). Кроме того, моим первоначальным намерением было исправить утверждение OP о том, что это невозможно сделать с помощью mldivide. Использование inv в MATLAB почти повсеместно запрещено, и его присутствие предназначено исключительно для обратной совместимости и для игрушечных примеров. - person abcd; 29.06.2011
comment
@nibot, @yoda: процедуры решения обычно выполняют 1) декомпозицию матрицы (обычно это некоторая форма LU или QR или Холецкого для симметричных матриц) 2) обратная подстановка (решение треугольных или ортогональных систем) 3) полировку решения. Стандартные процедуры обращения матрицы обычно пропускают шаг 3 (или выполняют полное исключение Гаусса). Поскольку системы решения гораздо чаще, чем инвертирование матриц, процедуры инверсии матриц имеют тенденцию быть менее оптимизированными, и вполне может быть, что 1 + 2 + 3 с n правыми сторонами (1 нужно выполнить один раз) быстрее, чем подпрограмма инверсии общего назначения, которую никто не использует. - person Alexandre C.; 29.06.2011
comment
Я сомневаюсь, что это лучше, чем вычисление обратной величины A напрямую. В противном случае это означало бы, что вы придумали лучший способ вычисления обратной матрицы, чем Mathworks. - person HelloGoodbye; 25.05.2016

Инвертировать произвольную матрицу размером 5000 x 5000 непросто с вычислительной точки зрения, независимо от того, какой язык вы используете. Я бы порекомендовал посмотреть на приближения. Если ваши матрицы имеют низкий ранг, вы можете попробовать приближение низкого ранга M = USV '

Вот еще несколько идей из math-overflow:

https://mathoverflow.net/search?q=matrix+inversion+approximation

person BlessedKey    schedule 28.06.2011
comment
шмех. Тот факт, что матрица имеет det (A) == 1, не означает, что приближение низкого ранга недостаточно для инженерных целей. См., Например, A = diag ([1e5,1,1e-5]). Определитель A по-прежнему равен 1, но A также может быть diag ([1e5 0 0]), если вы используете его для некоторых целей. - person BlessedKey; 28.06.2011
comment
Тот факт, что det A = 1 не означает, что A численно обратима. Для больших матриц шансы того, что число обусловленности велико, достаточно велики, чтобы большинство матриц необратимы (если они не получены, например, из дискретизации обратимого оператора). Подход SVD, вероятно, является единственным разумным, если OP не предоставит нам предысторию проблемы. - person Alexandre C.; 28.06.2011
comment
@AlexandreC .: Что такое подход СВД? Что означает СВД? - person HelloGoodbye; 25.05.2016
comment
@hellogoodbye: это подход M = USV из сообщения (Разложение по сингулярным значениям) - person Alexandre C.; 25.05.2016

Сначала предположим, что все собственные значения 1. Пусть A будет жордановой канонической формой вашей матрицы. Затем вы можете вычислить A^{-1}, используя только матричное умножение и сложение на

A^{-1} = I + (I-A) + (I-A)^2 + ... + (I-A)^k

где k < dim(A). Почему это работает? Потому что генерирующие функции - это здорово. Напомним расширение

(1-x)^{-1} = 1/(1-x) = 1 + x + x^2 + ...

Это означает, что мы можем инвертировать (1-x), используя бесконечную сумму. Вы хотите инвертировать матрицу A, поэтому вы хотите взять

A = I - X

Решение для X дает X = I-A. Следовательно, путем подстановки имеем

A^{-1} = (I - (I-A))^{-1} = 1 + (I-A) + (I-A)^2 + ...

Здесь я использовал единичную матрицу I вместо числа 1. Теперь у нас есть проблема конвергенции, но на самом деле это не проблема. Исходя из предположения, что A находится в жордановой форме и имеет все собственные значения, равные 1, мы знаем, что A является верхним треугольником со всеми 1 на диагонали. Следовательно, I-A является верхним треугольником со всеми 0 по диагонали. Следовательно, все собственные значения I-A равны 0, поэтому его характеристический полином равен x^dim(A), а его минимальный полином равен x^{k+1} для некоторого k < dim(A). Поскольку матрица удовлетворяет своему минимальному (и характеристическому) многочлену, это означает, что (I-A)^{k+1} = 0. Следовательно, приведенный выше ряд конечен с самым большим ненулевым членом (I-A)^k. Так что сходится.

Теперь для общего случая поместите свою матрицу в форму Жордана, чтобы у вас была блочно-треугольная матрица, например:

A 0 0
0 B 0
0 0 C

Где каждый блок имеет одно значение по диагонали. Если это значение равно a для A, используйте описанный выше трюк, чтобы инвертировать 1/a * A, а затем умножить a обратно. Поскольку полная матрица блочно-треугольная, обратная матрица будет

A^{-1} 0      0
0      B^{-1} 0
0      0      C^{-1}

В наличии трех блоков нет ничего особенного, так что это работает независимо от того, сколько у вас есть.

Обратите внимание, что этот трюк работает всякий раз, когда у вас есть матрица в жордановой форме. Вычисление обратного в этом случае будет очень быстрым в Matlab, потому что оно включает только умножение матриц, и вы даже можете использовать уловки, чтобы ускорить это, поскольку вам нужны только степени одной матрицы. Однако это может не помочь вам, если преобразование матрицы в форму Джордана действительно дорого.

person PengOne    schedule 28.06.2011
comment
Почему собственные значения должны быть ±1, если определитель 1 и записи действительны? Попробуйте A=[1,3;2,7]. Характеристический полином 1 - 8*x + x^2. Его корни 4±sqrt(15), а не ±1. - person abcd; 28.06.2011
comment
@Yoda: Как-то я думал о целых числах ... хороший момент. Отредактирую свой ответ. - person PengOne; 28.06.2011
comment
@Alexandre C: Какая его часть? Возможно, я поторопился с общим случаем, но когда все собственные значения равны 1, это решение действительно работает. - person PengOne; 28.06.2011
comment
@PengOne: вы тем временем редактировали ответ. Вы сказали, что, поскольку det (A) = 1, собственные значения равны + -1. Кроме того, вычисление жордановой формы намного медленнее, чем вычисление обратной матрицы. Я не знаю о стабильности формы Жордана, но подозреваю, что она сильно зависит от числа обусловленности A, которое, вероятно, будет очень большим, поскольку матрица велика. Но если все собственные значения - одно, то A = I + N с N нильпотентными, и трюк с сериями работает (хотя и с 5000 членами в худшем случае, что дает ту же сложность O (N ^ 3), что и простая инверсия). - person Alexandre C.; 28.06.2011
comment
@Alexandre C: Ваш комментарий появился после моего редактирования и заявляет, что весь ответ (это) ложный. Да, вычисление формы Джордана может быть дорогостоящим, но на основе линии они не поддаются диагонализации, иначе я бы попытался их диагонализовать, инвертировать, а затем вернуть обратно. в вопросе я подумал, что этот подход стоит упомянуть. - person PengOne; 28.06.2011
comment
@PengOne: Достаточно честно. Я сомневаюсь, что здесь сокращение превзойдет простую инверсию, и могут возникнуть проблемы со стабильностью (для больших матриц наличие det A = 1 не гарантирует, что A численно обратимо, поскольку это зависит от числа обусловленности). Imho, правильный подход здесь - SVD, но это зависит от того, что хочет сделать OP. - person Alexandre C.; 28.06.2011