Problems with SVD


madanr
04-16-2002, 07:00 PM
Hi there, I'm writing a program in Java, and I'm trying to port svdcmp over with very little success.

When I try a test matrix, say, the 1x1 identity matrix or the 2x2 identity matrix, U seems to be calculated correctly (the identity matrix), S seems to be correct (the identity matrix), but V ends up being -1 * the identity matrix (so while it obeys V*V' = I, USV' = -A, not A as it should).

I've thoroughly checked and rechecked the port; at this point, I've not changed anything other than to make it compile in java (I even made all my arrays 1 row and column larger, so there's no chance I've made a mistake going from arrays indexed from 1..n to 0..n-1).

I've gone so far as to hand evaluate every line in svdcmp, and this is the result I keep on getting; is there something wrong with the code, am I making a bonehead mistake, or is there some limitation to svdcmp that I'm simply unaware of?

I would appreciate any help anyone can give me; perhaps certain checkpoints in the code where I can test intermediary values, so that I can pinpoint the exact location of the problem.

Thank you,
Madan R.

Sherlock
04-18-2002, 08:39 AM
Hi Mandan,

I have implemented the same function in Java, starting from the C++ version of the code, and I am not getting the same results.

When decomposing a small identity matrix I into U*W*V', it gives me U=-I, W=I and V=-I, which is a correct result. It agrees with your result except for the sign of one of the matrices. This suggests a sign error somewhere in your translation. A particularly subtle place for such an error to exist and escape detection would be inside the utility function SIGN(). (At least, that is where I made a sign error when I first translated the routine!)

Sherlock

madanr
04-18-2002, 11:36 AM
I think my sign function is correct, unless there's some hidden "gotcha" somewhere

public static final float sign(float a, float b) {
return ((b) >= 0 ? (float) Math.abs(a) : (float) -Math.abs(a));
}

Just to make sure, I went ahead and reversed the minus signs to see if that fixed the problem, but that makes every entry in every output matrix NaN.

I ported my code from the C code, not the C++ code; could the C++ code be working and the C code not be?

I don't suppose you'd be interested in sending me a copy of your working SVD procedure?

Thanks,
Madan R.

madanr
04-18-2002, 01:33 PM
I went ahead and ported it from the C++ code; that helped a lot, and it's working for m >= n, but it's still not working for m < n. Does this function not work for that case?

Thanks for all your help,
Madan R.

madanr
04-18-2002, 07:34 PM
The 2x2 matrix
[0 1]
[0 0]

returns V =
[1 0]
[0 -1]

U =
[1 0]
[0 1]

and W =
[0 0]
[0 0]

Clearly W is wrong; I also believe V is wrong (it should be
[0 1]
[1 0] or something similar (depends on U values and particular permutation of W.

I don't mind too much if my port is buggy; I'll eventually fix those problems -- I'm concerned, however, if other people are getting the same bugs I'm getting.

Madan R.