forum.alglib.net http://forum.alglib.net/ |
|
Pseudoinverse with svd http://forum.alglib.net/viewtopic.php?f=2&t=409 |
Page 1 of 1 |
Author: | pers3 [ Fri Aug 05, 2011 8:02 pm ] |
Post subject: | Pseudoinverse with svd |
Hello, i implemented a method to process the pseudoinverse of a real matrix. This is the code: Code: #include <iostream> #include <stdlib.h> //abs #include "ap.h" #include "ap.cpp" #include "linalg.h" #include "linalg.cpp" #include "alglibinternal.h" #include "alglibmisc.h" #include "alglibinternal.cpp" #include "alglibmisc.cpp" using namespace std; void svd(alglib::real_2d_array& a, alglib::real_2d_array& pseudoi, int m, int n) { alglib::real_1d_array w; alglib::real_2d_array u, vt; alglib::rmatrixsvd(a, m, n, 2, 2, 2, w, u, vt); //create E_invers alglib::real_2d_array ei; ei.setlength(n, m); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) ei(i, j) = 0; for(int i = 0; i < w.length(); i++) if(abs(w(i)) > 10. * std::numeric_limits<double>::epsilon() ) ei(i, i) = 1. / w(i); //pseudoinverse alglib::real_2d_array ei_ut; ei_ut.setlength(n, m); rmatrixgemm(n, m, m, 1, ei,0,0,0, u,0,0,1, 0, ei_ut,0,0); rmatrixgemm(n, m, n, 1, vt,0,0,1, ei_ut,0,0,0, 0, pseudoi,0,0); } Can somebody double-check this routine? I tried it with Code: void test() { int m = 5; int n = 5; alglib::real_2d_array a; double _r2[] ={ 10,1,0,0,0, 0,10,1,0,0, 0,0,10,1,0, 0,0,0,10,1, 0,0,0,0,1}; a.setcontent(m, n,_r2); alglib::real_2d_array pseudoi; pseudoi.setlength(n, m); svd(a, pseudoi, m, n); //test alglib::real_2d_array eye; eye.setlength(n, n); rmatrixgemm(n, n, m, 1, pseudoi,0,0,0, a,0,0,0, 0, eye,0,0); cout << " eye: " << endl << eye.tostring(1) << endl; } But the result is not convincing. Other examples are very good! It is hard to test, because some examples have a bad condition. Thankyou for your help!!! |
Author: | Erumai [ Sat Aug 13, 2011 3:31 pm ] |
Post subject: | Re: Pseudoinverse with svd |
Hi, Sometime back I had written a small helper routine for the pseudo inverse of real matrices..and here it is..and I think it works pretty well.. I have been using it for some specific kind of image reconstructions and have even compared it with the results from matlab..they seem to agree well.. void rmatrix_pinv(alglib::real_2d_array &A,const alglib::ae_int_t m,const alglib::ae_int_t n,alglib::real_2d_array &B); //------------------------------------------------------------------------------- // Routine to add find the pseudoinverse of a normal matrix with linearly independent columns // The inverse is obtained by using the LU decomposition results of ALGLIB's LU decomposition routine, // and using the same in another routine of ALGLIB's densesolver package to solve an equation of the // form MX=N for X, by setting N as identity matrix // Pseudoinverse is obtained from the general formulation using inverse // (A' . A)^-1 * A' where A' is the hermitian transpose // // Input Variables: A - 2D real array // m - Number of rows in matrix A // n - Number of columns in matrix A // B - 2D real array to store the result // // On Output: B - B=pinv(A) // // Note: The matrix has to have linearly independent columns //------------------------------------------------------------------------------- void rmatrix_pinv(alglib::real_2d_array &A,const alglib::ae_int_t m,const alglib::ae_int_t n,alglib::real_2d_array &B) { //get the transpose and multiply it by the original matrix alglib::real_2d_array A_tr,tmp1,tmp2; A_tr.setlength(n,m); tmp1.setlength(n,n); tmp2.setlength(n,n); alglib::rmatrixtranspose(m,n,A,0,0,A_tr,0,0); // just a transpose int i,j; alglib::rmatrixgemm(n,n,m,1.0,A_tr,0,0,0,A,0,0,0,0,tmp1,0,0); alglib::ae_int_t info; alglib::matinvreport rep; //tmp1 has to be inverted - same as the one before alglib::integer_1d_array pivots; pivots.setlength(n); rmatrixlu(tmp1,n,n,pivots); //alglib::ae_int_t info; alglib::densesolverreport rep_1; alglib::real_2d_array I; I.setlength(n,n); eye_real(n,I); alglib::rmatrixlusolvem(tmp1,pivots,n,I,n,info,rep_1,tmp2); //tmp2 is the inverted matrix*/ //multiply the hermitian transpose with tmp2 to get the pseudoinverse alglib::rmatrixgemm(n,m,n,1.0,tmp2,0,0,0,A_tr,0,0,0,0,B,0,0); } cheers Erumai |
Author: | Alarmod [ Wed May 23, 2012 3:07 pm ] |
Post subject: | Re: Pseudoinverse with svd |
What is the function eye_real(n,I) in last topic? |
Page 1 of 1 | All times are UTC |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |