1

I am using jama libarary for matrix. I used following matrix but when i tried to get S, it gave me error.

1.0    1.0    0.0    1.0    0.0    0.0    0.0    0.0    0.0   11.0    1.0
1.0    0.0    0.0    0.0    0.0    0.0    1.0    0.0    0.0   12.0    2.0
1.0    1.0    0.0    0.0    0.0    0.0    0.0    0.0    1.0   13.0    3.0

When I tried to get S it produce following error.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    at Jama.SingularValueDecomposition.getS(SingularValueDecomposition.java:507)
    at SVD2.main(SVD2.java:19)

Here is the code

public class SVD2 {
    public static void main(String[] args) {
        double[][] vals = {
              {1,1,0,1,0,0,0,0,0,11,1},
              {1,0,0,0,0,0,1,0,0,12,2},
              {1,1,0,0,0,0,0,0,1,13,3}
              };
        Matrix A = new Matrix(vals,3,11);
        System.out.println("The Matrix A is ");
        A.print(11, 2);
        System.out.println();

        System.out.println("The SVD of A is ");
        SingularValueDecomposition svd = A.svd();
        Matrix S = svd.getS();       
    }

}
durron597
  • 31,968
  • 17
  • 99
  • 158
user238384
  • 2,396
  • 10
  • 35
  • 36

3 Answers3

3

For Jama's singular value decomposition, the number of rows must not be less than the number of columns. Maybe you should try SVD on the transpose of the matrix you provided.

EDIT: Here's the relevant code from SingularValueDecomposition.java:

   public Matrix getS () {
      Matrix X = new Matrix(n,n);
      double[][] S = X.getArray();
      for (int i = 0; i < n; i++) {
         for (int j = 0; j < n; j++) {
            S[i][j] = 0.0;
         }
         S[i][i] = this.s[i];
      }
      return X;
   }

S is constructed to be an n x n array, so the only possible source of an ArrayIndexOutOfBoundsException is from the reference to this.s[i].

Space for s is initialized in the SingularValueDecomposition constructor (amd no where else) like this:

s = new double [Math.min(m+1,n)];

So the Jama implementation will work for a 2x3 input (contradicting what they say in the class javadoc). But I bet it won't work for a 2x4 input.

mob
  • 117,087
  • 18
  • 149
  • 283
  • I don't think so it is the problem. Because if i use 3 column and 2 rows array it work fine. YOu can even use the following array with my code it will work fine double[][] vals = { {1,1,0}, {1,0,1} }; – user238384 Jan 21 '10 at 22:32
  • Is there any way, I can make it work for m – user238384 Jan 21 '10 at 22:48
  • Transposing a matrix means to switch rows and columns, which would create an 11x3 matrix in your case. I think changing your 4th-to-last line to `SingularValueDecomposition svd = A.transpose().svd();` would work. It is a defect in Jama that the SVD operation doesn't already do something like this to handle wide (as opposed to tall) matrices. – mob Jan 21 '10 at 23:18
  • Thank you so much for your quick and very informatic reply. Can you please tell me how can i converet MATRIX to 2 dimensional double array? – user238384 Jan 21 '10 at 23:53
  • @agazerboy - see Matrix `getArray()` or `getArrayCopy()` methods in the javadoc - http://math.nist.gov/javanumerics/jama/doc/Jama/Matrix.html – mob Jan 21 '10 at 23:58
  • No, SVD isn't appropriate for "wide" matricies. That means something like least squares fitting, which is entirely different. – duffymo Jan 22 '10 at 00:53
  • What is least squares? my matrix will be around 1000x2000. Is SVD good for that big matrix? Also is there any good formula out there, that can help to select K value to reduce dimension? – user238384 Jan 22 '10 at 00:57
  • You need to get a much better understanding of exactly what SVD and least squares are before you do much more. Least squares is for that case where you have more points than equations (# rows > # columns); SVD is for fewer points than equations (# rows < # columns). You need SVD. As far as size goes, SVD can theoretically work on any size matrix. The capability of your particular case will depend on the implementation you choose. 2M doubles means ~64MB just to hold the entire matrix in memory. There's overhead for SVD as well. – duffymo Jan 22 '10 at 01:02
  • Thanks you so much for explaining. I think I can handle rows and columns to adjust it for SVD. I want to remove noise from data. But for doing this you should know some good formula to set K value. While i read some research papers and they said its still an open research question :). – user238384 Jan 22 '10 at 01:10
0

Could you show us the code that is accessing the matrix? The exception you get clearly indicates that you are trying to index outside of the legal bounds of the underlying array.

Peter Lillevold
  • 33,668
  • 7
  • 97
  • 131
0

It's a 3x11 array. The fact that you're getting an index out of bounds exception for i = 4 suggests to me that your row count is specified incorrectly somewhere.

Another library like Apache Commons Math might help, but I don't believe the library is the issue here. It's your lack of understanding of SVD that's the real problem.

duffymo
  • 305,152
  • 44
  • 369
  • 561