/// <summary> /// Solves a linear equation system of the form AX = B. /// </summary> /// <param name="value">Parameter B from the equation AX = B.</param> /// <returns>The solution X from equation AX = B.</returns> public Single[,] Solve(Single[,] value) { // Additionally an important property is that if there does not exists a solution // when the matrix A is singular but replacing 1/Li with 0 will provide a solution // that minimizes the residue |AX -Y|. SVD finds the least squares best compromise // solution of the linear equation system. Interestingly SVD can be also used in an // over-determined system where the number of equations exceeds that of the parameters. // L is a diagonal matrix with non-negative matrix elements having the same // dimension as A, Wi ? 0. The diagonal elements of L are the singular values of matrix A. Single[,] Y = value; // Create L*, which is a diagonal matrix with elements // L*[i] = 1/L[i] if L[i] < e, else 0, // where e is the so-called singularity threshold. // In other words, if L[i] is zero or close to zero (smaller than e), // one must replace 1/L[i] with 0. The value of e depends on the precision // of the hardware. This method can be used to solve linear equations // systems even if the matrices are singular or close to singular. //singularity threshold Single e = this.Threshold; int scols = s.Length; var Ls = new Single[scols, scols]; for (int i = 0; i < s.Length; i++) { if (System.Math.Abs(s[i]) <= e) { Ls[i, i] = 0; } else { Ls[i, i] = 1 / s[i]; } } //(V x L*) x Ut x Y var VL = v.Multiply(Ls); //(V x L* x Ut) x Y int vrows = v.GetLength(0); int urows = u.GetLength(0); var VLU = new Single[vrows, scols]; for (int i = 0; i < vrows; i++) { for (int j = 0; j < urows; j++) { Single sum = 0; for (int k = 0; k < urows; k++) { sum += VL[i, k] * u[j, k]; } VLU[i, j] = sum; } } //(V x L* x Ut x Y) return(VLU.Multiply(Y)); }