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.

a \ b到底有多棒?


1
MATLAB的内置反斜杠(换句话说,是线性方程组的直接求解器)对稀疏矩阵使用多边线方法,这就是A \ B如此出色的原因。
曹书豪2012年

1
它使用cise.ufl.edu/research/sparse上的 Tim Davis代码。当您
遇到非凡的

1
什么是“ LULU”?您为什么认为这是LU分解和随后直接求解的良好实现?
杰德·布朗

3
@Nunoxic 什么实现?你自己写的吗?高性能的稠密线性代数,虽然通常在算法上已广为人知,但要在现代硬件上高效实现并不容易。对于该大小的矩阵,最佳的BLAS / Lapack实现应接近峰值。另外,从您的评论中,我得到的印象是您认为LU和高斯消除法是不同的算法。
杰德布朗(Jed Brown)

1
它调用使用英特尔MKL编写的Fortran代码。
Inquest 2012年

Answers:


37

在Matlab中,“ \”命令调用一个算法,该算法取决于矩阵A的结构,并包括对A属性的检查(开销很小)。

  1. 如果A稀疏且带状,请使用带状求解器。
  2. 如果A是上三角矩阵或下三角矩阵,请使用向后替换算法。
  3. 如果A是对称的并且具有真实的正对角元素,请尝试进行Cholesky分解。如果A稀疏,请首先进行重新排序以最小化填充。
  4. 如果没有满足以上条件,则使用带有部分枢轴的高斯消去法进行一般的三角分解。
  5. 如果A稀疏,则使用UMFPACK库。
  6. 如果A不为平方,则对不确定的系统采用基于QR分解的算法。

为了减少开销,可以在Matlab中使用linsolve命令,然后自己在这些选项中选择一个合适的求解器。


假设我正在处理一个所有元素都不为零(高密度级别)的10000x10000非结构化密集矩阵,那么我最好的选择是什么?我想隔离适用于密集矩阵的那一种算法。是LU,QR还是高斯消除?
Inquest 2012年

1
听起来像第4步,其中调用了高斯消去法,这对应于最普遍的情况,即无法利用A的结构来提高性能。因此,基本上,这是LU分解和随后的一个正向转换,然后是反向转换步骤。
艾伦·恩格西格·卡鲁普

谢谢!我认为这给了我思考的方向。当前,高斯消除法是解决此类非结构化问题的最佳方法,对吗?
Inquest 2012年

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设置。先生,打得好。
Geoff Oxberry 2012年

2
嘿,谢谢!在help mldivide
dranxo 2012年

16

对于稀疏矩阵,Matlab使用UMFPACK进行“ \”运算,在您的示例中,该运算基本上遍历了的值a,将它们取反,然后将它们与的值相乘b。但是,对于本示例,您应该使用b./diag(a),速度要快得多。

对于密集的系统,反斜杠运算符要复杂一些。一个什么样的简要说明中给出时,做这里。根据该描述,在您的示例中,Matlab将解决a\b使用向后替换的问题。对于一般的平方矩阵,使用LU分解。


Regd。稀疏性,diag矩阵的inv只是对角元素的倒数,因此b./diag(a)可以工作,但a \ b对于一般稀疏矩阵也非常有用。在这种情况下,对于密集型矩阵,为什么linsolve或LULU(我的LU的优化版本)没有比a \ b快。
Inquest

@Nunoxic您的LULU是否会执行任何操作来检测密集矩阵的对角线或三角形?如果不是,则不管其内容或结构如何,每个矩阵都将花费相同的时间。
2012年

有些。但是,使用linsolve OPT标志,我定义了有关该结构的所有定义。但是,a \ b更快。
Inquest 2012年

@Nunoxic,每次调用用户函数都会造成开销。Matlab内部执行所有反斜杠操作,例如右手边的分解和后续应用,而开销很小,因此速度更快。另外,在测试中,您应该使用多个呼叫来获得可靠的计时,例如tic; for k=1:100, a\b; end; toc
Pedro

5

根据经验,如果您有一个具有复杂度的稀疏矩阵(即,它不一定是5点模板,但实际上可以是斯托克斯方程的离散化,对于该方程,每行非零数为如果问题不大于约100,000个未知数,则稀疏直接求解器(例如UMFPACK)通常会胜过迭代Krylov求解器。

换句话说,对于大多数由2D离散化产生的稀疏矩阵,直接求解器是最快的选择。仅对于快速获得超过100,000个未知数的3d问题,才有必要使用迭代求解器。


3
我不清楚这如何回答问题,但我也对此前提表示怀疑。的确,直接求解器通常适用于中等大小的2D问题,但是直接求解器在3D方面早于100k未知数(顶点分隔符比2D大得多)之前就遭受苦难。此外,我声称在大多数情况下(例如椭圆运算符),即使对于中等大小的2D问题,迭代求解器也可以比直接求解器更快,但是这样做可能会花费很多精力(例如,使用正确的成分来使多网格执行) 。
杰德·布朗

1
如果您的问题相当小,并且您不想考虑设计隐式求解器,或者您的问题非常困难(例如高频Maxwell),并且您不想将自己的职业用于设计好的求解器,那么我同意稀疏的直接求解器是一个不错的选择。
杰德·布朗

实际上,我的问题是设计一个好的密集求解器。我没有这样的特定应用程序(因此,没有结构)。我想调整一些代码,使它们与当前使用的代码竞争。我只是对a \ b以及它总是如何击败我的代码感到好奇。
审讯2012年

@JedBrown:是的,也许即使付出很大的努力,即使对于较小的二维问题,也可以使迭代求解器击败直接求解器。但是为什么呢?对于未知数小于10万的问题,稀疏直接求解器在2d中足够快。我想说的是:对于这么小的问题,不要花时间修改和弄清楚参数的最佳组合-只需选择黑盒即可。
Wolfgang Bangerth,2012年

稀疏的Cholesky和(基于矩阵的)几何多重网格之间的运行时差异已经存在一个数量级,用于使用5点模具的100k自由度的“轻松” 2D问题(〜0.5秒,而〜0.05秒)。如果您的模板使用第二邻居(例如,四阶离散化,牛顿用于非线性流变学,稳定性的某些选择),则顶点分隔符的大小大约增加一倍,因此直接求解的成本将增加大约8倍(成本更高)对于MG,取决于问题)。在许多时间步长或优化/ UQ循环中,这些差异非常明显。
杰德·布朗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.