Zrobiłem to po raz pierwszy niedawno, korzystając z sugestii z matematyki.
Myślę, że SVD było zalecane przez większość, ale zdecydowałem się na prostotę Cholesky:
Jeśli macierz , to rozkładam na trójkątną macierz za pomocą Cholesky'ego, tak że . Następnie używam podstawienia w tył lub w przód (w zależności od tego, czy wybiorę L, aby był trójkątem górnym czy dolnym), aby odwrócić , tak że mam . Na tej podstawie mogę szybko obliczyć . M L M =M=AA⊤MLM=LL⊤LL−1M−1=(LL⊤)−1=L−⊤L−1
Zacząć od:
M=AA⊤ , gdzie jest znane i jest domyślnie symetryczne, a także dodatnio określone.M
Rozkład na czynniki chłodnicze:
M→LL⊤ , gdzie jest kwadratowe i nieparzysteL
Podstawienie wsteczne:
L→L−1 , prawdopodobnie najszybszy sposób na odwrócenie (choć nie cytuję tego)L
Mnożenie:
M−1=(LL⊤)−1=L−⊤L−1
Zastosowana notacja:
dolne indeksy to wiersze, górne indeksy to kolumny, a to transpozycjaL−⊤L−1
Mój algorytm Cholesky'ego (prawdopodobnie z przepisów numerycznych lub Wikipedii)
Lji=Mji−Mi⋅MjMii−Mi⋅Mi
Można to prawie zrobić na miejscu (potrzebujesz tylko tymczasowego przechowywania elementów ukośnych, akumulatora i niektórych iteratorów liczb całkowitych).
Mój algorytm zastępowania wstecznego (z Numerycznych przepisów sprawdź ich wersję, ponieważ mogłem pomylić się ze znacznikiem LaTeX)
(L−1)ji=⎧⎩⎨1/Lii(−Li⋅(L−T)j)/Liiif i=jotherwise
Ponieważ w wyrażeniu pojawia się , kolejność iteracji po macierzy jest ważna (niektóre części macierzy wynikowej zależą od innych jej części, które należy wcześniej obliczyć). Sprawdź kod Przepisy numeryczne, aby znaleźć pełny przykład w kodzie. [Edytuj]: W rzeczywistości po prostu sprawdź przykład Przepisy numeryczne. Za bardzo uprościłem, używając produktów kropkowych, do tego stopnia, że powyższe równanie ma cykliczną zależność bez względu na to, w jakiej kolejności iterujesz ...L−T