![]() |
В некоторых случаях надо решить такую задачу: есть матрица A, которую мы обратили, получив A -1. Затем мы изменили несколько элементов матрицы A, получив матрицу B, и нам требуется обратить матрицу B.
Разумеется, эта задача может быть решена "в лоб" путем применения алгоритма обращения к матрице B. Однако есть более эффективный алгоритм, позволяющий использовать тот факт, что у нас уже есть матрица A -1, а матрица B лишь незначительно отличается от матрицы A.
В основе алгоритма лежит формула Шермана-Моррисона:
![]()
Здесь A - квадратная матрица размером NxN, чья обратная матрица нам известна, а u и v - столбцы высоты N, задающие модификацию матрицы A (к элементу ai,j добавляется ui vj ). Можно видеть, что для обновления обратной матрицы по этой формуле требуется порядка N 2 операций с вещественными числами, что в N раз лучше, чем обращение более общим алгоритмом.
В зависимости от выбора векторов u и v возможны различные варианты модификации матрицы A и обновления матрицы A -1, выполняющиеся с различной трудоемкостью. Рассмотрим основные варианты:
Различные варианты обновления могут быть осуществлены с разной эффективностью, учитывая особую структуру векторов u и v. Самым быстрым является обновление обратной матрицы при модификации только одного элемента исходной матрицы, поэтому имеет смысл выбрать его эталоном.
Обновление обратной матрицы при модификации строки или столбца исходной матрицы всего лишь в два раза медленее (так что при модификации трех и более элементов, расположенных в одном столбце или строке, оно является более выгодным, чем многократный вызов предыдущего алгоритма). Обновление обратной матрицы при произвольном выборе векторов u и v в три раза медленее, чем обновление при модификации только одного элемента.
Замечание #1
Устойчивость алгоритма находится под вопросом, но как минимум один шаг алгоритма достаточно устойчив, если матрицы A и B хорошо обусловлены.
Модуль содержит несколько подпрограмм, позволяющих эффективно проводить обновление матрицы A -1 как в общем случае, заданном векторами u и v, так и в описанных выше специальных случаях.
Подпрограмма RMatrixInvUpdateSimple обновляет матрицу A -1 при добавлении числа UpdVal к элементу матрицы A, расположенному в строке UpdRow, столбце UpdColumn.
Подпрограммы RMatrixInvUpdateRow и RMatrixInvUpdateColumn позволяют обновить матрицу при добавлении вектора к указанной строке или столбцу.
Подпрограмма RMatrixInvUpdateUV обрабатывает более общий случай, задаваемый векторами U и V.
| C++ | inverseupdate.h | |
| C# | inverseupdate.cs | |
| MPFR | inverseupdate.h | |
| Delphi | inverseupdate.pas | |
| FreePascal | inverseupdate.pas | |
| VBA | inverseupdate.bas |
This article is intended for personal use only.
Исходный код на C#
Исходный код на C++
Исходный код на C++, использующий библиотеки MPFR/GMP.
Исходный код GMP доступен на сайте gmplib.org. Исходный код MPFR доступен на сайте www.mpfr.org.
Исходный код на Free Pascal.
Исходный код на Delphi.
Исходный код на VBA.
|
ALGLIB project, 1999-2010 |