Як оператор зворотної косої лінії MATLAB вирішує для квадратних матриць?


36

Я порівнював декілька своїх кодів із "запасними" кодами MATLAB. Я здивований результатами.

Я запустив зразок коду (розріджена матриця)

n = 5000;
a = diag(rand(n,1));
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('Inv(A)*B');
tic;inv(a)*b;toc;

Результати:

    For a\b
    Elapsed time is 0.052838 seconds.

    For LU
    Elapsed time is 7.441331 seconds.

    For Conj Grad
    Elapsed time is 3.819182 seconds.

    Inv(A)*B
    Elapsed time is 38.511110 seconds.

Для щільної матриці:

n = 2000;
a = rand(n,n);
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('For INV(A)*B');
tic;inv(a)*b;toc;

Результати:

For a\b
Elapsed time is 0.575926 seconds.

For LU
Elapsed time is 0.654287 seconds.

For Conj Grad
Elapsed time is 9.875896 seconds.

Inv(A)*B
Elapsed time is 1.648074 seconds.

Як чорт \ b такий дивовижний?


1
Вбудований зворотний проріз MATLAB, інакше кажучи, прямий розв'язувач для системи лінійних рівнянь використовує мультифронтальний метод для розрідженої матриці, тому A \ B настільки приголомшливий.
Shuhao Cao

1
Він використовує код Тіма Девіса, доступний на веб- сайті cise.ufl.edu/research/sparse . Також дивовижність зникає, коли у вас є нетривіальна проблема
stali

1
Що таке "LULU"? Чому, на вашу думку, це вдала реалізація LU-факторизації та наступне безпосереднє вирішення?
Джед Браун

3
@Nunoxic Яка реалізація? Ви це самі написали? Високопродуктивну щільну лінійну алгебру, хоча, як правило, добре розуміють алгоритмічно, непросто втілити в сучасне обладнання. Кращі реалізації BLAS / Lapack повинні наближатись до піку для матриці такого розміру. Також із ваших коментарів у мене складається враження, що ви вважаєте, що LU та Gaussian Elimination - це різні алгоритми.
Джед Браун

1
Він називає код Fortran, написаний за допомогою Intel MKL.
Запит

Відповіді:


37

У Matlab команда '\' викликає алгоритм, який залежить від структури матриці A і включає перевірки (невеликі накладні витрати) на властивості A.

  1. Якщо A є рідким і смуговим, використовуйте смуговий розв'язувач.
  2. Якщо A - це верхня або нижня трикутна матриця, використовують алгоритм заміщення назад.
  3. Якщо A симетричний і має реальні позитивні діагональні елементи, спробуйте факторизацію Холеського. Якщо A невеликий, спочатку виконайте переупорядкування, щоб мінімізувати заповнення.
  4. Якщо жоден із наведених вище критеріїв не виконаний, зробіть загальну трикутну факторизацію, використовуючи гауссова елімінація з частковим поворотом.
  5. Якщо A рідкий, використовуйте бібліотеку UMFPACK.
  6. Якщо A не квадратний, використовуйте алгоритми, засновані на QR-факторизації для невизначених систем.

Для зменшення накладних витрат можна скористатися командою linsolve в Matlab і вибрати підходящий вирішувач серед цих параметрів самостійно.


Якщо припустити, що я маю справу з неструктурованою щільною матрицею 10000x10000 з усіма елементами ненульовими (Високий рівень щільності), що було б найкращим? Я хочу виділити той алгоритм, який працює для щільних матриць. Це LU, QR або Гауссова елімінація?
Запит

1
Звучить як крок 4, де викликається Гауссова елімінація, що відповідає найбільш загальному випадку, коли жодна структура A не може бути використана для підвищення продуктивності. Отже, в основному це LU-факторизація та подальший перехід вперед з подальшим етапом заміщення.
Аллан П. Енгсіг-Каруп

Спасибі! Я думаю, що це дає мені напрямок думати. Наразі ліквідація Гаусса - це найкраще, що ми маємо для вирішення таких неструктурованих проблем, це правильно?
Запит

37

Якщо ви хочете побачити, що a\bстосується вашої конкретної матриці, ви можете встановити spparms('spumoni',1)та зрозуміти, який саме алгоритм вас вразив. Наприклад:

spparms('spumoni',1);
A = delsq(numgrid('B',256));
b = rand(size(A,2),1);
mldivide(A,b);  % another way to write A\b

виведе

sp\: bandwidth = 254+1+254.
sp\: is A diagonal? no.
sp\: is band density (0.01) > bandden (0.50) to try banded solver? no.
sp\: is A triangular? no.
sp\: is A morally triangular? no.
sp\: is A a candidate for Cholesky (symmetric, real positive diagonal)? yes.
sp\: is CHOLMOD's symbolic Cholesky factorization (with automatic reordering) successful? yes.
sp\: is CHOLMOD's numeric Cholesky factorization successful? yes.
sp\: is CHOLMOD's triangular solve successful? yes.

тож я можу побачити, що "\" в цьому випадку закінчився використанням "CHOLMOD".


3
+1 для нових налаштувань MATLAB, про які я ніколи не чув. Добре зіграно, сер.
Джефф Оксберрі

2
Гей, дякую! Це в help mldivide.
dranxo

16

Для розріджених матриць Matlab використовує UMFPACK для \операції " ", яка, у вашому прикладі, в основному проходить через значення a, інвертує їх і помножує їх на значення b. Для цього прикладу, однак, вам слід скористатися b./diag(a), що набагато швидше.

Для щільних систем оператор зворотної косої риски трохи складніше. Короткий опис того , що зроблено , коли дається тут . Згідно з цим описом, у вашому прикладі Matlab вирішив би a\bза допомогою зворотної заміни. Для загальних квадратних матриць використовується LU-розкладання.


Регд. Рідкість, інверсія діагностичної матриці буде просто зворотною діагональними елементами, тому b./diag(a) буде працювати, але \ b працює приголомшливо і для загальних рідких матриць. Чому в цьому випадку не linsolve чи LULU (моя оптимізована версія LU) не швидше, ніж \ b для щільних матриць.
Запит

@Nunoxic Чи робить ваш LULU щось для виявлення діагональності чи трикутності щільної матриці? Якщо ні, то це займе стільки ж часу, як і кожна матриця, незалежно від її вмісту чи структури.
Педро

Дещо. Але, з прапорами linsolve OPT, я визначив усе, що є для визначення структури. І все ж, a \ b швидше.
Запит

@Nunoxic, щоразу, коли ви викликаєте функцію користувача, ви викликаєте накладні витрати. Matlab робить все для зворотної косої риски внутрішньо, наприклад, розкладання та подальше застосування правої частини, з дуже невеликими накладними витратами, і, таким чином, буде швидшим. Крім того, у своїх тестах ви повинні використовувати більше ніж один дзвінок, щоб отримати надійні таймінги, наприклад tic; for k=1:100, a\b; end; toc.
Педро

5

Як правило, якщо у вас розріджена матриця розумної складності (тобто, вона не повинна бути 5-кратним трафаретом, але насправді може бути дискретизацією рівнянь Стокса, для яких число ненульових значень у рядку набагато більший, ніж 5), тоді рідкісний прямий вирішувач, такий як UMFPACK, зазвичай перемагає ітеративний вирішувач Крилова, якщо проблема не більша за, можливо, близько 100 000 невідомих.

Іншими словами, для більшості розріджених матриць, що виникають внаслідок 2d дискретизацій, прямий вирішувач є найшвидшою альтернативою. Тільки для 3d-проблем, коли ви швидко отримуєте понад 100 000 невідомих, стає обов'язковим використання ітеративного рішення.


3
Мені незрозуміло, як це дає відповідь на питання, але я також сприймаю передумови. Це правда, що прямі розв’язувачі, як правило, добре працюють при 2D-проблемах скромного розміру, але прямі розв'язувачі, як правило, страждають у 3D задовго до 100k невідомостей (роздільники вершин набагато більше, ніж у 2D). Крім того, я стверджую, що в більшості випадків (наприклад, еліптичні оператори) ітеративні розв'язувачі можуть бути зроблені швидше, ніж прямі розв'язувачі, навіть для 2D проблем середнього розміру, але для цього знадобиться значні зусилля (наприклад, використання правильних інгредієнтів для того, щоб зробити багаторешітку) .
Джед Браун

1
Якщо ваших проблем досить мало, і ви не хочете замислюватися над розробкою неявних вирішувачів, або якщо ваші проблеми дуже важкі (як високочастотний Maxwell), і ви не хочете присвячувати свою кар'єру розробці хороших вирішувачів, то я погоджуєтесь, що рідкісні прямі вирішувачі - чудовий вибір.
Джед Браун

Насправді моя проблема полягає в розробці хорошого щільного вирішувача. У мене немає такої конкретної програми (Отже, немає структури). Я хотів налаштувати кілька моїх кодів і зробити їх конкурентоспроможними з тим, що зараз використовується. Мені було просто цікаво про \ b і про те, як воно завжди вибиває лайно з мого коду.
Запит

@JedBrown: Так, можливо, при значній кількості зусиль можна отримати ітеративні розв'язувачі, щоб перемогти прямий вирішувач навіть для невеликих проблем з 2d. Але навіщо це робити? Для проблем з <100k невідомими, рідкісні прямі розв'язувачі в 2d досить швидко. Що я хотів сказати: для таких невеликих проблем не витрачайте часу на роздуми і з'ясування найкращого поєднання параметрів - просто візьміть blackbox.
Вольфганг Бангерт

Вже існує різниця у величині часу виконання між розрідженою географічною мультисетиною Холеського та (на основі матриці) для "легких" двовимірних задач із 100-кфітними даними, використовуючи 5-кратний трафарет (~ 0,5 секунди порівняно з ~ 0,05 секунди). Якщо ваш трафарет використовує другого сусіда (наприклад, дискретизацію четвертого порядку, Ньютон для деяких варіантів нелінійної реології, стабілізації тощо), розмір розділювачів вершин приблизно вдвічі збільшується, тому вартість прямого вирішення зростає приблизно на 8 разів (вартість більше залежно від проблеми для MG). За багатьох кроків часу або циклів оптимізації / UQ ці відмінності суттєві.
Джед Браун
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.