Методы инверсии больших матриц - PullRequest
3 голосов
/ 29 июля 2010

Привет, я проводил некоторые исследования по матричной инверсии (линейной алгебре) и хотел использовать шаблонное программирование на C ++ для алгоритма, но я обнаружил, что существует ряд методов, таких как: исключение Гаусса-Джордана или разложение LU и я нашел функцию LU_factorize (библиотека C ++ Boost)

  1. Я хочу знать, есть ли другие методы, какой из них лучше (преимущества / недостатки), с точки зрения программистов или математиков?

  2. Если нет других более быстрых методов, есть ли уже (матричная) функция инверсии в библиотеке буста? потому что я много искал и не нашел.

Ответы [ 5 ]

5 голосов
/ 29 июля 2010

Как вы упоминаете, стандартный подход состоит в том, чтобы выполнить факторизацию LU, а затем решить для идентичности.Это может быть реализовано с использованием библиотеки LAPACK, например, с dgetrf (коэффициент) и dgetri (обратное вычисление).Большинство других библиотек линейной алгебры имеют примерно эквивалентные функции.

Есть некоторые более медленные методы, которые ухудшаются более изящно, когда матрица является единственной или почти единственной, и используются по этой причине.Например, псевдообратная Мура-Пенроуза равна обратной, если матрица обратима, и часто полезна, даже если матрица не обратима;это может быть вычислено, используя Разложение Сингулярного значения.

3 голосов
/ 29 июля 2010

Я бы посоветовал вам взглянуть на Eigen исходный код.

2 голосов
/ 02 августа 2010

Пожалуйста, Google или Википедия для модных слов ниже.

Во-первых, убедитесь, что вы действительно хотите обратное.Решение системы не требует обращения матрицы.Матричная инверсия может быть выполнена путем решения n систем с единичными векторами базисов в качестве правых частей.Поэтому я сосредоточусь на решении систем, потому что это обычно то, что вы хотите.

Это зависит от того, что означает «большой».Методы, основанные на декомпозиции, обычно должны хранить всю матрицу.После того, как вы разложили матрицу, вы можете решить для нескольких правых частей одновременно (и, таким образом, легко инвертировать матрицу).Я не буду обсуждать здесь методы факторизации, поскольку вы, вероятно, уже знаете их.

Обратите внимание, что когда матрица велика, ее номер условия очень вероятно будет близок кноль, что означает, что матрица является «численно необратимой».Помощь: Предварительное кондиционирование .Проверьте Википедию для этого.Статья хорошо написана.

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

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

Методыявляются:

  • Для симметричных определенных положительных матриц: метод сопряженных градиентов .Короче говоря, решение Ax = b сводится к минимуму 1/2 x ^ TA x - x ^ T b.
  • Метод двухконъюгатного градиента для общих матриц.Нестабильный, хотя.
  • Минимальные остаточные методы, или лучше всего, GMRES.Пожалуйста, проверьте статьи в Википедии для деталей.Вы можете поэкспериментировать с количеством итераций перед перезапуском алгоритма.

И, наконец, вы можете выполнить некоторую факторизацию с разреженными матрицами, с помощью специально разработанных алгоритмов, чтобы минимизировать число ненулевыхэлементы для хранения.

1 голос
/ 14 февраля 2011

В зависимости от размера матрицы на самом деле, вам, вероятно, нужно хранить только небольшое подмножество столбцов в памяти в любой момент времени. Это может потребовать переопределения низкоуровневых операций записи и чтения для элементов матрицы, что я не уверен, если Eigen, в противном случае довольно приличная библиотека, позволит вам.

Для этих очень узких случаев, когда матрица действительно большая , существует StlXXL библиотека, предназначенная для доступа к памяти массивов, которые в основном хранятся на диске

РЕДАКТИРОВАТЬ Если быть точным, если у вас есть матрица, которая не фиксируется в доступной ОЗУ, предпочтительным подходом является блочная инверсия . Матрица рекурсивно разбивается, пока каждая матрица не помещается в ОЗУ (это, конечно, параметр настройки алгоритма). Сложность в том, чтобы не допустить инвертирования ЦП матриц при их извлечении и извлечении из диска. Это может потребовать исследования подходящих параллельных файловых систем, поскольку даже с StlXXL это, вероятно, является основным узким местом. Хотя позвольте мне повторить мантру; Преждевременная оптимизация - корень всего зла программирования . Это зло может быть изгнано только с помощью очищающего ритуала Кодирование, Выполнение и Профиль

0 голосов
/ 29 июля 2010

Возможно, вы захотите использовать оболочку C ++ вокруг LAPACK.LAPACK - очень зрелый код: хорошо протестированный, оптимизированный и т. Д.

Одной из таких оболочек является Intel Math Kernel Library .

...