C++ 如何实现Matlab';s mldivide(也称为反斜杠运算符“\”)

C++ 如何实现Matlab';s mldivide(也称为反斜杠运算符“\”),c++,matlab,matrix,linear-algebra,equation-solving,C++,Matlab,Matrix,Linear Algebra,Equation Solving,我目前正在尝试开发一个小型的面向矩阵的数学库(用于矩阵数据结构和运算),我想实现一些方便的Matlab函数,例如广泛使用的反斜杠运算符(相当于),以便计算线性系统的解(以矩阵形式表示) 对于如何实现这一点,是否有详细的解释?(我已经用经典SVD分解实现了Moore-Penrose伪逆函数,但我在某个地方读到,a\b并不总是pinv(a)*b,至少Matalb不只是这样做) 感谢对于x=A\b,运算符包含许多用于处理不同类型输入矩阵的函数。因此,诊断矩阵A,并根据其特征选择执行路径 当A是完整矩阵

我目前正在尝试开发一个小型的面向矩阵的数学库(用于矩阵数据结构和运算),我想实现一些方便的Matlab函数,例如广泛使用的反斜杠运算符(相当于),以便计算线性系统的解(以矩阵形式表示)

对于如何实现这一点,是否有详细的解释?(我已经用经典SVD分解实现了Moore-Penrose伪逆函数,但我在某个地方读到,
a\b
并不总是
pinv(a)*b
,至少Matalb不只是这样做)


感谢对于
x=A\b
,运算符包含许多用于处理不同类型输入矩阵的函数。因此,诊断矩阵
A
,并根据其特征选择执行路径

A
是完整矩阵时,以下内容在伪代码中描述:

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
对于非平方矩阵,使用。对于正方形三角形矩阵,它执行简单的运算。对于平方对称正定矩阵,使用。否则用于一般平方矩阵

更新:MathWorks已经在
mldivide
的文档页面中用一些漂亮的流程图更新了。请参见和(完整和稀疏案例)

所有这些算法在中都有相应的方法,事实上,这可能是MATLAB正在做的事情(请注意,最新版本的MATLAB附带了优化的实现)

采用不同方法的原因是,它试图使用最具体的算法来求解方程组,该算法利用系数矩阵的所有特征(因为它会更快或更稳定)。因此,您当然可以使用通用解算器,但它不是最有效的

事实上,如果您事先知道
A
是什么样子,您可以通过直接调用和指定选项跳过额外的测试过程

如果
A
为矩形或单数,还可以使用来找到最小范数最小二乘解(使用以下方法实现):


所有这些都适用于密集矩阵,稀疏矩阵则完全不同。通常在这种情况下使用。我相信MATLAB使用SuiteCase包中的其他相关库来直接求解

使用稀疏矩阵时,您可以打开诊断信息,并查看使用以下方法执行的测试和选择的算法:


更重要的是,反斜杠操作符也适用于的,在这种情况下,它依赖于GPU并在GPU上执行

它还可以在分布式计算环境中实现(工作在计算机集群中分配,其中每个工作人员只有阵列的一部分,可能整个矩阵不能一次存储在内存中)。底层实现正在使用


如果你想自己实现所有这些,这是一个相当高的要求:)

这并不简单,我强烈建议不要尝试。只需将其连接到LAPACK的DGEMV。很多聪明人花了很多时间微调
mldivide
。类似的问题:表明矩形的QR方法是拉帕克DGEL。谢谢你,阿姆罗,这是一个非常有建设性的回答。“A”很可能是非方矩阵,因此,如果我理解正确,最适合使用的方法是QR分解。是的,我愿意(至少尝试)实现所需的功能,以创建一个自包含的库,因此我真的不想使用其他数学软件包(目前,算法的效率不是我的主要目标;)。这是一个个人项目,目前还不严重…@M4XMX:是的,你可以使用QR分解:
Ax=b-->QRx=b-->Rx=Q'b-->x=R\(Q'b)
(最后一步是简单的反向替换过程)。请参阅以获取解释。这里还有一个相关的例子,展示了如何使用各种库求解Ax=b的问题:GSL、Armadillo、Eigen。不需要重新发明轮子:)我认为MATLAB也可以用来提高数值精度。也就是说,分解是:
AP=QR
其中
P
是一个置换矩阵多么漂亮的答案。我一直想知道“使用”了什么算法1.@tommsch我们使用
A'
的QR分解,并求解
(QR)*x=b
x = pinv(A)*b
spparms('spumoni',2)
x = A\b;