MATLAB中的mrdivide函数:它在做什么,我怎么能在Python中做到这一点?

Emi*_*lyS 8 python matlab numpy linear-algebra

我有这行MATLAB代码:

a/b
Run Code Online (Sandbox Code Playgroud)

我正在使用这些输入:

a = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]   
b = ones(25, 18)
Run Code Online (Sandbox Code Playgroud)

这是结果(1x25矩阵):

[5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
Run Code Online (Sandbox Code Playgroud)

MATLAB在做什么?我试图在Python中复制此行为,并且mrdivideMATLAB中的文档无益.5来自哪里,为什么其余值为0?

我已尝试使用其他输入并接收类似的结果,通常只是一个不同的第一个元素和零填充矩阵的其余部分.在Python中,当我使用时linalg.lstsq(b.T,a.T),返回的第一个矩阵中的所有值(即不是单数矩阵)都是0.2.我已经在Python中尝试了正确的划分,并且它提供了完全错误的维度.

我理解最小二乘近似是什么,我只需要知道mrdivide正在做什么.

有关:

gev*_*ang 8

MRDIVIDE/操作员实际上解决了xb = a线性系统,而不是MLDIVIDE\将解决系统的操作员bx = a.

要求一个xb = a具有非对称,不可逆矩阵的系统b,你可以依靠mridivide(),通过b高斯消元的分解,或者pinv()通过奇异值分解完成,并且对下面的奇异值进行归零. a(默认)容差级别.

这是差异(对于这种情况mldivide):当我解决A*x = b时,PINV和MLDIVIDE之间有什么区别?

当系统超定时,两种算法都提供相同的答案.当系统未确定时,PINV将返回解x,其具有最小范数(min NORM(x)).MLDIVIDE将选择具有最少数量的非零元素的解决方案.

在你的例子中:

% solve xb = a
a = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9];
b = ones(25, 18);
Run Code Online (Sandbox Code Playgroud)

系统不确定,两种不同的解决方案将是:

x1 = a/b; % MRDIVIDE: sparsest solution (min L0 norm) 
x2 = a*pinv(b); % PINV: minimum norm solution (min L2)

>> x1 = a/b
Warning: Rank deficient, rank = 1,  tol = 2.3551e-014.
ans =

    5.0000 0 0 ... 0 

>> x2 = a*pinv(b)
ans =

    0.2 0.2 0.2 ... 0.2 
Run Code Online (Sandbox Code Playgroud)

在这两种情况下的逼近误差xb-a是不可忽略的(非精确解)和相同的,即,norm(x1*b-a)norm(x2*b-a)将返回相同的结果.

MATLAB在做什么?

bscicomp.stackexchange.com中的这篇文章中给出了 由'\'运算符调用的算法(和属性检查)的一个很好的细分,具体取决于矩阵的结构.我假设类似的选项适用于/运营商.

对于你的例子,MATLAB最有可能进行高斯消元法,在无限的情况下给出最稀疏的解决方案(这就是5来自的地方).

Python在做什么?

Python,linalg.lstsq使用伪逆/ SVD,如上所示(这就是为什么你得到0.2的向量).实际上,下面的内容将给出与MATLAB相同的结果pinv():

from numpy import *

a = array([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9])
b = ones((25, 18))

# xb = a: solve b.T x.T = a.T instead 
x2 = linalg.lstsq(b.T, a.T)[0]
x2 = dot(a, linalg.pinv(b)) 
Run Code Online (Sandbox Code Playgroud)


Nat*_*yle 7

长话短说:A/B = np.linalg.solve(B.conj().T, A.conj().T).conj().T

我没有找到早期的答案来创建令人满意的替代品,因此我进一步深入研究了 Matlab 的 mrdivide 参考文档并找到了解决方案。我无法在这里解释实际的数学原理,也无法因提出答案而获得荣誉。我只是按照Matlab的解释。此外,我想发布 Matlab 的实际细节以给予认可。如果这是版权问题,有人告诉我,我会删除实际的文本。

%/   Slash or right matrix divide.
%   A/B is the matrix division of B into A, which is roughly the
%   same as A*INV(B) , except it is computed in a different way.
%   More precisely, A/B = (B'\A')'. See MLDIVIDE for details.
%
%   C = MRDIVIDE(A,B) is called for the syntax 'A / B' when A or B is an
%   object.
%
%   See also MLDIVIDE, RDIVIDE, LDIVIDE.

%   Copyright 1984-2005 The MathWorks, Inc.

Run Code Online (Sandbox Code Playgroud)

请注意,该'符号表示复共轭转置。在使用 numpy 的 python 中,需要将 .conj().T 链接在一起。


sec*_*ond 1

a/b 求线性方程组的最小二乘解 bx = a

如果 b 是可逆的,则为 a*inv(b),但如果不是,则为最小化范数 (bx-a) 的 x

您可以在维基百科上阅读有关最小二乘法的更多信息。

根据matlab 文档,mrdivide 将返回最多 k 个非零值,其中 k 是 b 的计算秩。我的猜测是,在您的情况下,matlab 通过用 b(:1) (具有相同的等级)替换 b 来解决最小二乘问题。在这种情况下,摩尔-彭罗斯逆b2 = b(1,:); inv(b2*b2')*b2*a'被定义并给出相同的答案