2015-07-24 3 views
0

В рамках проекта java, который я разработал, мне нужно вычислить обратную матрицу. Для согласования с другими проектами и другими разработчиками я использую эффективную библиотеку матриц Java (orj.ejml).Java: обратная матрица с использованием EJML не работает должным образом

Для инвертирования Матрицы я использую инвертировать от org.ejml.ops.CommonOps, и я не работал нормально до сих пор, что я получаю неожиданный результат

Я изолировал дело, что Безразлично» т работа быть:

DenseMatrix64F X = new DenseMatrix64F(3, 3); 
    X.setData(new double[]{77.44000335693366,-24.64000011444091,-8.800000190734865, -24.640000114440916,7.839999732971196,2.799999952316285, -8.800000190734865,2.799999952316285,1.0000000000000004}); 
    DenseMatrix64F invX = new DenseMatrix64F(3, 3); 
    boolean completed = CommonOps.invert(X, invX); 
    System.out.println(X); 
    System.out.println(invX); 
    System.out.println(completed); 

выход я получаю от этого теста:

Type = плотные, NumRows = 3, numCols = 3
77,440 -24,640 -8,800
-24,640 7,840 2,800
-8,800 2,800 1,000

Тип = плотные, NumRows = 3, numCols = 3
NaN -Infinity бесконечность
NaN бесконечность -Infinity
NaN -Infinity бесконечность

верно

Моя первая мысль заключалась в том, что это может быть сингулярная матрица и поэтому не обратима, но после тестирования той же матрицы с di Я нашел, что он не является единственным.

Итак, я вернулся к документации EJML и узнал следующую информацию для этой конкретной функции.

Если алгоритм не может инвертировать матрицу, возвращается false. Если он возвращает true, это означает, что алгоритм завершен. Результаты все равно могут быть плохими, потому что матрица является сингулярной или почти сингулярной.

И в этом конкретном случае матрица не является единственной, но мы можем сказать, что она близка к единице.

Единственным решением, которое я мог придумать, было найти инвертированную матрицу для NaN или Infinites после вычисления ее, и если я найду что-то смешное, то я просто заменил инвертированную матрицу на исходную матрицу, хотя она не кажется очень чистая практика дает разумные результаты.

Мой вопрос:

  • Не могли бы вы подумать о какой-либо решения этой ситуации? Что-то умнее и мудрее, чем просто использовать исходную матрицу в качестве собственной обратной матрицы.

  • В случае, если это не так, знаете ли вы о какой-либо другой библиотеке Java Matrix, которая имеет некоторое решение этой ситуации, я не собираюсь вводить новую библиотеку, но это может быть единственное решение, если это становится реальной проблемой.

С уважением и благодарностью за входные данные!

+0

Похоже, что это не функция качества продукции. Вы можете применить его ** дважды **, чтобы узнать, достигнута ли исходная матрица. –

+0

Это звучит как более прочный подход, чем поиск Infinites/Nan; хотя потребуется больше, чем в два раза больше вычислительных. Это будет проблемой, так как эта функция называется очень часто, и, несмотря на то, что я использовал ее в течение нескольких месяцев, у меня было только одно неожиданное поведение, поэтому я понимаю, что это угловой случай. Спасибо за ваш вход @JoopEggen. Я буду следить за нашей функцией лучшего качества. – Julian

ответ

1

Вы должны попробовать использовать SVD, если у вас есть обратный. Также рассмотрите псевдо-обратное. В принципе, любая библиотека, использующая LU-разложение, будет иметь серьезные проблемы. Вот результат от Octave. Обратите внимание, что два из сингулярных значений почти равны нулю. Octave даст вам обратное значение с реальными числами, но оно плохое ...

octave:7> cond(B) 
ans = 8.5768e+17 
octave:8> svd(B) 
ans = 

    8.6280e+01 
    3.7146e-15 
    1.0060e-16 

inv(B)*B 
warning: inverse: matrix singular to machine precision, rcond = 4.97813e-19 
ans = 

    0.62500 0.06250 0.03125 
    0.00000 0.00000 0.00000 
    0.00000 0.00000 4.00000 
Смежные вопросы