2010-01-18 4 views
3

Я использую jama для расчета СВД. Он работает очень хорошо. Если я пройду квадратную матрицу. Например, матрица 2x2 или 3x3 и т. Д. Но когда я передаю что-то вроде этого 2x3 или 4x8, он дает ошибку . Я использовал все их примеры. У них есть другой конструктор для выполнения задания. Кроме того, мой второй вопрос, я Usded 3x3 матрицу, и это далоjava jama matrix problem

double[][] vals = {{1.,1.,0},{1.,0.,1.},{1.,3.,4.},{6.,4.,8.}}; 
    Matrix A = new Matrix(vals); 

Он произвел следующие ошибки:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 

После того, что я священник научил использовать другой конструктор, который, как следовать

double[][] vals = {{1.,1.,0,4},{1.,0.,1.,2},{1.,3.,4.,8},{1.,3.,4.,8}}; 
    Matrix A = new Matrix(vals,4,3); 

Произведено следующее:

A = 
1.0 1.0 0.0 
1.0 0.0 1.0 
1.0 3.0 4.0 
6.0 4.0 8.0 

A = U S V^T 

U = 
0.078 -0.115 -0.963 
0.107 -0.281 0.260 
0.402 0.886 -0.018 
0.906 -0.351 0.060 

Sigma = 
11.861881 0.000000 0.000000 
0.000000 2.028349 0.000000 
0.000000 0.000000 1.087006 

V = 
0.507705 -0.795196 -0.331510 
0.413798 0.562579 -0.715735 
0.755650 0.226204 0.614675 

rank = 3 
condition number = 10.912437186202627 
2-norm = 11.86188091889931 
singular values = 
11.861881 2.028349 1.087006 

Работала для не квадратной матрицы. Но это привело к неправильным результатам для svd, поскольку V и S не имеют одинаковых строк = 4 (извините, если я не смог правильно проанализировать результат, поскольку я новичок в SVD). Есть идеи? Что мне делать?

ответ

4

Будьте осторожны, JAMA поддерживает SVD в первую очередь для матриц с полным рангом, и если вы читаете «readme», вы заметите, что поведение не обязательно корректно для ранга (m < n).

В сущности, то, что вызывает ваш ArrayIndexOutOfBounds исключение линии 486 в SingularValueDecomposition:

return new Matrix(U,m,Math.min(m+1,n)); 

Изменение это:

return new Matrix(U); 

решит проблему.Окончательное, что происходит под обложками (по крайней мере, для примера Викатку), заключается в том, что вы вводите матрицу с m=4 и n=5, но уведомление в фактическом выводе U имеет размеры m=4 и n=4. Если вы читаете в верхней части SingularValueDecomposition класса говорится:

For an m-by-n matrix A with m >= n, the singular value decomposition is an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and an n-by-n orthogonal matrix V so that A = USV'.

Но это не имеет места в данном случае, потому что m=4 и n=5 означает m<n. Так что теперь, так как вы передаете ранг недостающую матрицу U имеет различные размеры, чем нормальный вызывающему случае класса СВД, и в качестве такого заявления:

new Matrix(U, m, Math.min(m+1,n)) 

создаст матрицу с предполагаемыми рядами m, здесь 4 (это правильно) и предполагаемые столбцы n, здесь Math.min(4+1,5)=5 (что неверно). Итак: когда вы отправляете распечатку матрицы, и процедура печати вызывает getColumnDimension, матрица U возвращает 5, что больше, чем фактическое измерение массива.

Короче говоря, переход на отмеченную выше строчку определит размеры U и, таким образом, вернет действительный результат независимо от ранга.

+0

Спасибо за решение. Я хочу запустить множественную регрессию с jama и иметь ту же проблему. может быть, мой вопрос странный, но я не могу редактировать класс SingularValueDecomposition. Это означает, что netbeans не позволяют мне редактировать jama-код. – MTT

1

Прочитать wiki article on SVD. Следующий код является представителем примера в разделе 2.

import Jama.Matrix; 
import Jama.SingularValueDecomposition; 

public class JAMATest { 

    static public void printMatrix(Matrix m){ 
     double[][] d = m.getArray(); 

     for(int row = 0; row < d.length; row++){ 
      for(int col = 0; col < d[row].length; col++){ 
       System.out.printf("%6.4f\t", m.get(row, col)); 
      } 
      System.out.println(); 
     } 
     System.out.println(); 
    } 

    public static void main(String[] args) { 
     double[][] vals = { {1., 0., 0., 0., 2.}, 
          {0., 0., 3., 0., 0.}, 
          {0., 0., 0., 0., 0.}, 
          {0., 4., 0., 0., 0.} 
          }; 
     Matrix A = new Matrix(vals);   
     SingularValueDecomposition svd = new SingularValueDecomposition(A); 

     System.out.println("A = "); 
     printMatrix(A); 

     System.out.println("U = "); 
     printMatrix(svd.getU()); 

     System.out.println("Sigma = "); 
     printMatrix(svd.getS()); 

     System.out.println("V = "); 
     printMatrix(svd.getV()); 
    } 
} 

и дает outputL:

A = 
1.0000 0.0000 0.0000 0.0000 2.0000 
0.0000 0.0000 3.0000 0.0000 0.0000 
0.0000 0.0000 0.0000 0.0000 0.0000 
0.0000 4.0000 0.0000 0.0000 0.0000 

U = 
0.0000 0.0000 -1.0000 0.0000 
0.0000 1.0000 -0.0000 0.0000 
0.0000 0.0000 -0.0000 1.0000 
1.0000 0.0000 -0.0000 0.0000 

Sigma = 
4.0000 0.0000 0.0000 0.0000 0.0000 
0.0000 3.0000 0.0000 0.0000 0.0000 
0.0000 0.0000 2.2361 0.0000 0.0000 
0.0000 0.0000 0.0000 0.0000 0.0000 
0.0000 0.0000 0.0000 0.0000 0.0000 

V = 
0.0000 -0.0000 -0.4472 -0.8944 -0.0000 
0.0000 -0.0000 -0.0000 -0.0000 -0.0000 
0.0000 1.0000 -0.0000 -0.0000 -0.0000 
0.0000 -0.0000 -0.0000 -0.0000 1.0000 
1.0000 -0.0000 -0.8944 0.4472 -0.0000 

Надеется, что это помогает. Кроме того, FWIW здесь выводится MatLab на одной и той же проблемой:

>> A = [1.0000, 0.0000, 0.0000, 0.0000, 2.0000; 0, 0, 3, 0, 0; 0, 0, 0, 0, 0; 0, 4, 0, 0, 0]; 
>> A 

A = 

    1  0  0  0  2 
    0  0  3  0  0 
    0  0  0  0  0 
    0  4  0  0  0 

>> [U, S, V] = svd(A); 
>> U 

U = 

    0  0  1  0 
    0  1  0  0 
    0  0  0 -1 
    1  0  0  0 

>> S 

S = 

    4.0000   0   0   0   0 
     0 3.0000   0   0   0 
     0   0 2.2361   0   0 
     0   0   0   0   0 

>> V 

V = 

     0   0 0.4472   0 -0.8944 
    1.0000   0   0   0   0 
     0 1.0000   0   0   0 
     0   0   0 1.0000   0 
     0   0 0.8944   0 0.4472 

Что касается первого вопроса, то следующий код не производит ошибку:

import Jama.Matrix; 

public class JAMATest { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     double[][] vals = {{1.,1.,0},{1.,0.,1.},{1.,3.,4.},{6.,4.,8.}}; 
     Matrix A = new Matrix(vals); 

    } 
} 

Так что-то еще, что вы делаете должно быть причиной у него есть исключение. Попробуйте использовать мой метод printMatrix вместо того, что вы используете, и посмотрите, помогает ли это.

+0

Извините, но я не мог понять ваш ответ. Вы думаете, что результат, который я написал в моем вопросе, верен? Сколько V и S имеет 3 строки? Не могли бы вы объяснить? Мне жаль, что я не эксперт по математике :( – user238384

+0

Изменения в моей предыдущей программе выше. Я включил функцию printMatrix. Обратите внимание, что у меня есть аналогичное исключение, как и при использовании m.getRowDimension() и m.getColumnDimension() как они не кажутся точными для метода svd.getU(). Преобразование матрицы в двойную [] [], похоже, делает трюк. – vicatcu

+0

Отдельное примечание: SVD матрицы не является уникальным. цитата из статьи в Википедии: «Следует также отметить, что эта конкретная декомпозиция особого значения не уникальна». Когда вы умножаете U * S * V, вы получите исходную матрицу назад. Размеры матричной сортировки «join», когда поэтому наша оригинальная матрица была [4 x 5] = [4 x 4] * [4 x 5] * [5 x 5], и вы остаетесь с внешними двумя измерениями ([4 ..x .. 5]). Кажется, вы должны * признать *, что только первые четыре строки Sigma являются фактической матрицей, основанной на этих свойствах. – vicatcu

0

Размеры U, S и V не обязательно должны быть того же размера, что и A. U будет иметь одинаковое количество строк, а V^T будет иметь одинаковое количество столбцов. Этого достаточно, чтобы воссоздать А по правилам матричного умножения.

Другое измерение (столбцы строк U, строк V^T и строк/столбцов S) будет «рангом» A (в вашем примере 3). Это, грубо говоря, размерность ваших данных ... сколько осей необходимо для однозначного представления столбца или строки в A. Это будет не более min(rows, cols), но часто может быть намного меньше. Все в порядке.

0

Jama не поддерживает полное SVD, но только уменьшает количество SVD. Это эквивалентно Matlab svd (B, 0) или svd (B, 'econ'). Bye

 Смежные вопросы

  • Нет связанных вопросов^_^