public void SetupTestCases() { a = new DoubleMatrix(3); a[0, 0] = 1.91; a[0, 1] = 9.82; a[0, 2] = 2.73; a[1, 0] = 8.64; a[1, 1] = 3.55; a[1, 2] = 7.46; a[2, 0] = 4.37; a[2, 1] = 6.28; a[2, 2] = 5.19; svd = new DoubleSVDDecomp(a, true); wa = new DoubleMatrix(2, 4); wa[0, 0] = 1.91; wa[0, 1] = 9.82; wa[0, 2] = 2.73; wa[0, 3] = 8.64; wa[1, 0] = 3.55; wa[1, 1] = 7.46; wa[1, 2] = 4.37; wa[1, 3] = 6.28; wsvd = new DoubleSVDDecomp(wa, true); la = new DoubleMatrix(4, 2); la[0, 0] = 1.91; la[0, 1] = 9.82; la[1, 0] = 2.73; la[1, 1] = 8.64; la[2, 0] = 3.55; la[2, 1] = 7.46; la[3, 0] = 4.37; la[3, 1] = 6.28; lsvd = new DoubleSVDDecomp(la, true); }
/* * This function computes the pseudoinverse of a square matrix A * into B using SVD. A and B can coincide * * The function returns 0 in case of error (e.g. A is singular), * the rank of A if successfull * * A, B are mxm * */ static int LEVMAR_PSEUDOINVERSE(double[] A, double[] B, int m) { IROMatrix Amat = MatrixMath.ToROMatrix(A,m); DoubleSVDDecomp decomp = new DoubleSVDDecomp(Amat); DoubleVector s = decomp.S; DoubleMatrix u = decomp.U; DoubleMatrix v = decomp.V; /* compute the pseudoinverse in B */ for(int i=0; i<B.Length; i++) B[i]=0.0; /* initialize to zero */ double one_over_denom, thresh; int rank; for(rank=0, thresh=DoubleConstants.DBL_EPSILON*s[0]; rank<m && s[rank]>thresh; rank++) { one_over_denom=1.0/s[rank]; for(int j=0; j<m; j++) for(int i=0; i<m; i++) B[i*m+j]+=v[i,rank]*u[j,rank]*one_over_denom; } return rank; }