コードが期待する結果をもたらさない理由を説明するのではなく、速度の問題に対処します。あなたはあなたのコードにあります
parameters += SamArray<T>::MatrixProduct(SamArray<T>::Inverse(JTJ + combinationMatrix),J);
これは、最初に逆行列を計算し、次に、を乗算しJ
ます。これは別の行列であると推測されます。A X = I
これは、最初に解いてから計算するのと基本的に同じであるため、非効率的ですA^-1 B
。ここで、A
およびX
は行列でI
あり、は単位行列です。代わりに、A X = B
を直接解決することをお勧めします。QRやLUなど、これを可能にするいくつかの分解スキームがあります。LU分解では、行列A
は上三角部分U
と下L
三角部分に分割され、次のように別々に効率的に反転されます。
A X = L U X = B
U X = L^-1 B
X = U^-1 L^-1 B
これは、アルゴリズム自体の一部として実行されます。逆を直接必要とする場合は、に置き換えますB
がI
、ご覧のとおり、必要はありません。Levenberg–Marquardtアルゴリズムを見ると、MathematicaTranspose[J].J + DiagonalMatrix[Diagonal@J]
表記法を使用すると、正定値である可能性があり、コレスキー分解が利用可能であり、大幅に高速化されます。しかし、私はアルゴリズムを詳しく調べていないので、この場合、コレスキー分解は使用できない可能性があります。
\ begin{edit} chの1.5秒で
。3、スチュワートは2つのアルゴリズムの相対速度について説明します:反転してから乗算v。LU分解。どちらも漸近的な複雑さは同じO(n^3)
ですが、係数が異なります。具体的には、方程式を解くときA X == B
、invert-then-multiplyの操作カウントはですが5 n^3 /6 + l n^2
、LUの操作数はですn^3 /3 + l n^2
。ここで、n
は行数、は列数です。2つの比率は常に1より大きく、たとえ、LU分解が反転してから乗算するよりも30%高速です。
\ end {edit}B
l
l == n
次に、パラメーターのセットごとにカイ2乗を2回計算します。1回は最初に決定されたとき、もう1回は次の反復と比較したときです。この値は、以前に受け入れられたパラメーターと一緒にキャッシュする必要があります。
最後に、妥当な速度でフィッティングを処理するMathematicaの能力を軽視するつもりはありません。