Я сделал это впервые за последнее время, используя предложения mathSE.
Я думаю, что SVD было рекомендовано большинством, но я остановился на простоте Cholesky:
Если матрица , то я разлагаю на треугольную матрицу используя Холецкого, так что . Затем я использую обратную замену или прямую замену (в зависимости от того, выбираю ли я L в качестве верхнего или нижнего треугольника), чтобы инвертировать , чтобы у меня было . Из этого я могу быстро вычислить .M=AA⊤MLM=LL⊤LL−1M−1=(LL⊤)−1=L−⊤L−1
Начните с:
M=AA⊤ , где известно и неявно симметрично, а также положительно определено.M
Холесская факторизация:
M→LL⊤ , где квадратное и неособоеL
Back-замена:
L→L−1 , вероятно, самый быстрый способ инвертировать (не цитируйте меня об этом, хотя)L
Умножение:
M−1=(LL⊤)−1=L−⊤L−1
Используемая запись:
нижние индексы - это строки, верхние индексы - это столбцы, а - транспонированиеL−⊤L−1
Мой алгоритм Холецкого (возможно, из Numeric Recipes или Wikipedia)
Lji=Mji−Mi⋅MjMii−Mi⋅Mi
Это почти можно сделать на месте (вам нужно только временное хранилище для диагональных элементов, аккумулятор и несколько целочисленных итераторов).
Мой алгоритм обратной замены (из Числовых Рецептов, проверьте их версию, поскольку я, возможно, допустил ошибку с разметкой LaTeX)
(L−1)ji=⎧⎩⎨1/Lii(−Li⋅(L−T)j)/Liiif i=jotherwise
Поскольку появляется в выражении, важен порядок, в котором вы выполняете итерацию по матрице (некоторые части матрицы результата зависят от других ее частей, которые должны быть вычислены заранее). Проверьте код Числовые рецепты для полного примера в коде. [Изменить]: На самом деле, просто посмотрите пример Числовые рецепты. Я слишком сильно упростил, используя точечные продукты, до такой степени, что вышеприведенное уравнение имеет циклическую зависимость, независимо от того, в каком порядке вы итерируете ...L−T