SVD and pseudoinverse


shwe
03-05-2007, 04:06 PM
Hi everyone,
I am trying to find pseudoinverse of a matrix and as a first step I am trying to use svdcmp.c to find the SVD of the matrix. But I am unsure about how to call the function svdcmp() in my main since it uses **A (pointer to pointer) as one of its arguments. I dunno how to use them. Can anyone give me an example for finding SVD of a small 4x2 matrix using svdcmp() ?
thanks
shwe

shwe
03-06-2007, 12:40 PM
Hey all,
I figured out the answer to my question and was also able to get the pseudoinverse using SVD.
Shwe

nofre
04-02-2008, 09:48 AM
when i use Matlab to find Pseudo-Inverse Matrix of a matrix A(mxn), use svd()....A=U*S*Vt,.... , it's ok:

[m,n]=size(A);
[U,S,V]=svd(A);
r=rank(S);
SR=S(1:r,1:r);
SRc=[SR^-1 zeros(r,m-r);zeros(n-r,r) zeros(n-r,m-r)];
A_pseu=V*SRc*U.';

But now move to C++, i have a little problem with svd() in C. Cause , in matlab , U (mxm),S(mxn),V(nxn) ; in C++, U(mxn),S(nxn),V(nxn). The different is the sizes of those matrix U,S,V.

How could you find A_pseu in C ? :eek:

help me...

davekw7x
04-02-2008, 01:39 PM
...in matlab , U (mxm),S(mxn),V(nxn) ; in C++, U(mxn),S(nxn),V(nxn).
How could you find A_pseu in C ?
Details are different; results are the same.

Example SVD problem http://en.wikipedia.org/wiki/Singular_value_decomposition. I'll find the pseudoinverse two ways.

I initialize A as follows, then use your matlab program. (Actually I use octave, since it's free.)


A = [ 1 0 0 0 2;0 0 3 0 0;0 0 0 0 0;0 4 0 0 0]
.
.
.
A_pseu =

0.20000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.25000
0.00000 0.33333 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000
0.40000 0.00000 0.00000 0.00000


Now, with Numerical Recipes SVD:

*****************Original Matrix****************
Matrix A:
1.000000 0.000000 0.000000 0.000000 2.000000
0.000000 0.000000 3.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 4.000000 0.000000 0.000000 0.000000

*******************After SVD********************
Matrix U:
0.000000 0.000000 1.000000 0.000000 0.000000
0.000000 -1.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 1.000000
-1.000000 0.000000 0.000000 0.000000 0.000000

Diagonal of Matrix W:
4.000000 3.000000 2.236068 0.000000 0.000000

Matrix V:
0.000000 0.000000 0.447214 0.000000 0.894427
-1.000000 0.000000 0.000000 0.000000 0.000000
0.000000 -1.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.894427 0.000000 -0.447214

************************************************
Matrix W
4.000000 0.000000 0.000000 0.000000 0.000000
0.000000 3.000000 0.000000 0.000000 0.000000
0.000000 0.000000 2.236068 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000

Matrix V-transpose:
0.000000 -1.000000 0.000000 0.000000 0.000000
0.000000 0.000000 -1.000000 0.000000 0.000000
0.447214 0.000000 0.000000 0.000000 0.894427
0.000000 0.000000 0.000000 1.000000 0.000000
0.894427 0.000000 0.000000 0.000000 -0.447214

*****Check product against original matrix******
Original matrix:
1.000000 0.000000 0.000000 0.000000 2.000000
0.000000 0.000000 3.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 4.000000 0.000000 0.000000 0.000000

Product of [U] * [W] * [V-Transpose]:
1.000000 0.000000 0.000000 0.000000 2.000000
0.000000 0.000000 3.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 4.000000 0.000000 0.000000 0.000000

************************************************
Matrix U-Transpose:
0.000000 0.000000 0.000000 -1.000000
0.000000 -1.000000 0.000000 0.000000
1.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000

Matrix W+:
0.250000 0.000000 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.000000 0.000000
0.000000 0.000000 0.447214 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000

***********This is the Pseudo-Inverse***********
Product of [V] * [W+] * [U-Transpose]:
0.200000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.250000
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.400000 0.000000 0.000000 0.000000


The first three items (U, Diagonal of W, and V) come from the Numerical Recipes SVD routine, everything else is from standard matrix manipulations. I showed the various intermediate results for my own amusement and edification.

Regards,

Dave

Footnote: The stuff I show in this post for the Numericsl Recipes solution came from the Numerical Recipes version 3 SVD class. Using the Numerical Recipes Version 2 C++ svdcmp() function had different (but equivalent) intermediate values but the same end results.

Bottom line: SVD decomposition itself is not unique (as mentioned in the text), but using it to obtain the pseudoinverse "works," the same way regardless of intermediate details.

Decomposition with different shapes of intermediate matrices still gives the same results. (When I say, "same results," from two different programs, I am glossing over the fact that implementation details may affect roundoff errors.)