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

时间:2009-06-17 14:36:13

标签: python matlab numpy linear-algebra

我有这行MATLAB代码:

a/b

我正在使用这些输入:

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

这是结果(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]

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

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

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

相关:

4 个答案:

答案 0 :(得分:8)

MRDIVIDE/运算符实际上解决了xb = a线性系统,而不是MLDIVIDE\运算符将解决系统{{} 1}}。

要解决具有非对称,不可逆矩阵bx = a的系统xb = a,您可以依赖b,这是通过mridivide()的因子分解来完成的高斯消元或b,通过奇异值分解完成,并将奇异值置零到(默认)容差水平以下。

这是差异(对于pinv()的情况):What is the difference between PINV and MLDIVIDE when I solve A*x=b?

  

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

在你的例子中:

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);

在这两种情况下,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 的近似误差都是不可忽略的(非精确解)并且相同,即xb-anorm(x1*b-a)将返回相同的结果。

MATLAB在做什么?

这个帖子在scicomp.stackexchange.com中给出了'\'运算符调用的算法(和属性检查)的一个很好的细分,具体取决于矩阵norm(x2*b-a)的结构。我假设类似的选项适用于b运算符。

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

Python在做什么?

Python,在/中使用伪逆/ SVD,如上所示(这就是为什么你得到0.2的向量)。实际上,以下内容将为您提供与MATLAB的linalg.lstsq

相同的结果
pinv()

答案 1 :(得分:2)

a / b找到线性方程组bx = a

的最小二乘解

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

您可以在wikipedia上详细了解最小二乘法。

根据matlab documentation,mrdivide将返回最多k个非零值,其中k是b的计算等级。我的猜测是你的案例中的matlab解决了用b(:1)(具有相同的等级)替换b给出的最小二乘问题。在这种情况下,moore-penrose逆b2 = b(1,:); inv(b2*b2')*b2*a'被定义并给出相同的答案

答案 2 :(得分:1)

对于matlab用户来说,每this handy "cheat sheet"个numpy,linalg.lstsq(b,a) - linalgnumpy.linalg.linalg,是scipy.linalg的轻量级版本。

答案 3 :(得分:1)

TL; DR: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.

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