if size(A,1) == size(A,2) % A is square
if isequal(A,tril(A)) % A is lower triangular
x = A \ b; % This is a simple forward substitution on b
elseif isequal(A,triu(A)) % A is upper triangular
x = A \ b; % This is a simple backward substitution on b
else
if isequal(A,A') % A is symmetric
[R,p] = chol(A);
if (p == 0) % A is symmetric positive definite
x = R \ (R' \ b); % a forward and a backward substitution
return
end
end
[L,U,P] = lu(A); % general, square A
x = U \ (L \ (P*b)); % a forward and a backward substitution
end
else % A is rectangular
[Q,R] = qr(A);
x = R \ (Q' * b);
end
1条答案
按热度按时间yr9zkbsy1#
对于
x = A\b
,backslash运算符包含许多算法来处理不同类型的输入矩阵。因此,诊断矩阵A
,并根据其特性选择执行路径。下面的page在伪代码中描述了当
A
是全矩阵时:对于非正方形矩阵,使用QR decomposition。对于正方形三角矩阵,它执行简单的向前/向后替换。对于正方形对称正定矩阵,使用Cholesky decomposition。否则LU decomposition用于一般的方阵。
**更新:**MathWorks更新了
mldivide
文档页面中的算法部分,并添加了一些漂亮的流程图。参见here和here(完整和稀疏情况)。所有这些算法在LAPACK中都有相应的方法,实际上这可能就是MATLAB正在做的事情(注意,MATLAB的最新版本提供了优化的Intel MKL实现)。
使用不同方法的原因是它试图使用最具体的算法来求解方程组,该算法利用了系数矩阵的所有特性(因为它会更快或更稳定)。所以你当然可以使用通用求解器,但它不是最有效的。
事实上,如果你事先知道
A
是什么样的,你可以通过调用linsolve
并直接指定选项来跳过额外的测试过程。如果
A
是矩形或奇异的,你也可以使用PINV来找到一个最小范数最小二乘解(使用SVD decomposition实现):上面所有的都适用于稠密矩阵,稀疏矩阵是一个完全不同的故事。在这种情况下,通常使用迭代求解器。我相信MATLAB使用SuiteSpase包中的UMFPACK和其他相关库来进行直接求解。
使用稀疏矩阵时,您可以打开诊断信息并查看使用
spparms
执行的测试和选择的算法:更重要的是,反斜杠运算符也适用于gpuArray,在这种情况下,它依赖于cuBLAS和MAGMA在GPU上执行。
它也适用于在分布式计算环境中工作的distributed arrays(在计算机集群中分配工作,其中每个工作者仅拥有阵列的一部分,可能整个矩阵不能同时存储在内存中)。底层实现使用ScaLAPACK。
如果你想自己实现所有这些,这是一个非常高的要求:)