Я сравнивал несколько своих кодов с «стандартными» кодами 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.
Как, черт возьми, это так круто?
linear-algebra
performance
matlab
расследование
источник
источник
Ответы:
В Matlab команда '\' вызывает алгоритм, который зависит от структуры матрицы A и включает проверки (небольшие накладные расходы) на свойства A.
Чтобы уменьшить накладные расходы, можно использовать команду linsolve в Matlab и выбрать подходящий решатель среди этих вариантов самостоятельно.
источник
Если вы хотите увидеть, что
a\b
подходит для вашей конкретной матрицы, вы можете установитьspparms('spumoni',1)
и точно определить , какой алгоритм вас впечатлил. Например:будет выводить
так что я вижу, что "\" в конечном итоге использовало "CHOLMOD" в этом случае.
источник
help mldivide
.Для разреженных матриц Matlab использует UMFPACK для
\
операции " ", которая, в вашем примере, в основном пробегает значенияa
, инвертирует их и умножает их на значенияb
. Для этого примера, однако, вы должны использоватьb./diag(a)
, что намного быстрее.Для плотных систем оператор обратной косой черты немного сложнее. Краткое описание того, что делается, когда дается здесь . Согласно этому описанию, в вашем примере Matlab решит,
a\b
используя обратную подстановку. Для общих квадратных матриц используется LU-разложение.источник
tic; for k=1:100, a\b; end; toc
.Как правило, если у вас есть разреженная матрица разумной сложности (т. Е. Это не обязательно должен быть шаблон из 5 точек, но на самом деле это может быть дискретизация уравнений Стокса, для которых число ненулевых элементов в строке равно намного больше, чем 5), тогда разреженный прямой решатель, такой как UMFPACK, обычно побеждает итеративный решатель Крылова, если проблема не превышает приблизительно 100 000 неизвестных.
Другими словами, для большинства разреженных матриц, полученных в результате двумерных дискретизаций, прямой решатель является самой быстрой альтернативой. Только для трехмерных задач, когда вы быстро получаете более 100 000 неизвестных, становится необходимым использовать итеративный решатель.
источник