Отладка: необычное время выполнения в вычислениях линейной алгебры с использованием Java, ojalgo

У меня умеренно большой Ax = b проблема, которую я хочу решить. Матрица А есть 600x600,

Мой код решает проблему, но занимает необычно много времени. Итак, я попытался проверить (с System.currentTimeMillis()), чтобы увидеть, где мой код замедляется.

Оказывается, что во время расчетов А я выполняю команду A = L1 * A0 * L1.transpose(), Процесс занимает почти 100% своего общего времени в этой линии.

Странная вещь, L1 является 600x600 единичная матрица (то есть A[i,j] = 1, если i == j а также 0, иначе). Таким образом, эта строка не должна занимать так много времени для выполнения. Также должно быть легко обойти эту проблему

Даже более странная вещь произойдет, если я попытаюсь обойти эту строку, закомментировав ее и заменив ее A = A0, Затем выполнение кода занимает слишком много времени (после 10-кратного первоначального времени, когда я его убил). Также загрузка процессора достигает 100%.

Я проверил, и получается, что A а также L1 * A0 * L1.transpose() идентичны

Подводя итог, используя часть моего Java-кода (я использую библиотеку ojalgo для обработки матриц):

// PrimitiveMatrix A0, L1, b are already calculated.

long startTime = System.currentTimeMillis();
System.out.println((System.currentTimeMillis() - startTime0) / 1000.0); // this prints about 2 seconds, concerning calculations of A0, L1, b.

PrimitiveMatrix A = L1.multiply(A0).multiply((L1).transpose());
System.out.println((System.currentTimeMillis() - startTime0) / 1000.0);  // this prints about 67 seconds    

// PrimitiveMatrix A = A0; // if this is NOT a comment, then the code has not run after (10+)x my "normal" time 

final PrimitiveMatrix x = (A.invert()).multiply(b);

System.out.println((System.currentTimeMillis() - startTime0) / 1000.0);  // this prints about 69 seconds  

// I checked that
// A0.equals(L1.multiply(A0).multiply((L1).transpose())
// returns true

Весь этот процесс занимает около 69 секунд, и 65 из них потребляются в тривиальном расчете, который я не смог обойти. Та же самая процедура успешно выполнялась в прошлом для меньших матриц (60x60).

Я не совсем уверен, как продолжить мои попытки отладки. Любая помощь будет принята с благодарностью.

Кажется, проблема немного глубже, чем я предполагал. Я попытался распечатать эти матрицы, чтобы загрузить их, но затем появилась другая проблема. Я обнаружил, что мой код падает при первом запуске System.out.println(A0.get(aRow,aColumn));, A0 был создан путем добавления чисел типа double к каждой позиции нулевой матрицы с размерами 600x600, Кроме того, появляются следующие сообщения:

       Exception in thread "main" java.lang.StackruError
    at org.ojalgo.matrix.store.SuperimposedStore.get(SuperimposedStore.java:84)
    at org.ojalgo.matrix.store.SuperimposedStore.get(SuperimposedStore.java:84)
    at org.ojalgo.matrix.store.SuperimposedStore.get(SuperimposedStore.java:84)
...

Опять же, я хочу подчеркнуть, что тот же процесс работает нормально, когда эти матрицы 60x60,

1 ответ

Я предполагаю, что вы используете BasicMatrix#add(int,int,Number)

Вы вызывали этот метод 600x600 раз, чтобы построить свою матрицу? Вы не должны этого делать!

В более новых версиях ojAlgo этот метод был удален, потому что его часто неправильно понимали / неправильно использовали.

Вы должны прочитать это: https://github.com/optimatika/ojAlgo/wiki/Getting-Started

Другие вопросы по тегам