ฉันทำสิ่งนี้เป็นครั้งแรกเมื่อเร็ว ๆ นี้โดยใช้คำแนะนำจาก mathSE
SVD ถูกแนะนำโดยส่วนใหญ่ฉันคิดว่า แต่ฉันเลือกที่จะใช้ความเรียบง่ายของ Cholesky:
หากเมทริกซ์แล้วฉันสลายMไปยังสามเหลี่ยมเมทริกซ์Lใช้ Cholesky เช่นว่าM = L L ⊤ จากนั้นผมก็ใช้ backsubstitution หรือ forwardsubstitution (ขึ้นอยู่กับว่าฉันเลือก L จะเป็นรูปสามเหลี่ยมบนหรือล่าง) เพื่อสลับLเช่นที่ฉันมีL - 1 จากนี้ฉันสามารถคำนวณM - 1 = ( L L ⊤ ) - 1 = L - ⊤ L - 1 ได้อย่างรวดเร็วM=AA⊤MLM=LL⊤LL−1M−1=(LL⊤)−1=L−⊤L−1ได้อย่างรวดเร็ว
เริ่มกับ:
ที่เอ็มเป็นที่รู้จักและมีความสมมาตรโดยปริยายและยังเป็นบวกแน่นอนM=AA⊤M
Cholesky factorisation:
โดยที่ Lเป็นรูปสี่เหลี่ยมและไม่เป็นเอกพจน์M→LL⊤L
กลับเปลี่ยนตัว:
อาจเป็นวิธีที่เร็วที่สุดในการกลับด้าน L (อย่าอ้างว่าเป็นแบบนั้น)L→L−1L
คูณ:
M−1=(LL⊤)−1=L−⊤L−1
L−⊤L−1
อัลกอริทึมของฉัน Cholesky (อาจมาจากสูตรตัวเลขหรือวิกิพีเดีย)
Lji=Mji−Mi⋅MjMii−Mi⋅Mi
This can almost be done in-place (you only need temporary storage for the diagonal elements, an accumulator and some integer iterators).
My back-substitution algorithm (from Numerical Recipes, check their version as I may have made a mistake with the LaTeX markup)
(L−1)ji=⎧⎩⎨1/Lii(−Li⋅(L−T)j)/Liiif i=jotherwise
As L−T appears in the expression, the order that you iterate over the matrix is important (some parts of the result matrix depend on other parts of it that must be calculated beforehand). Check the Numerical Recipes code for a complete example in code.
[Edit]: Actually, just check the Numerical Recipes example. I've over-simplified too much by using dot-products, to the point that the above equation has a cyclic dependency no matter what order you iterate...