MRDIVIDE或/
算子实际上解决了xb = a
线性系统,而不是MLDIVIDE或\
将解决系统的算子bx = a
。
要求解xb = a
具有非对称、不可逆矩阵的系统b
,您可以依赖mridivide()
,这是通过b
使用高斯消元的因式分解来完成的,或者pinv()
是通过奇异值分解和以下奇异值的归零来完成的(默认)容差水平。
以下是区别(对于 的情况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);
系统未确定,两种不同的解决方案将是:
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-a
都是不可忽略的(非精确解)并且相同,即norm(x1*b-a)
并且norm(x2*b-a)
将返回相同的结果。
MATLAB 在做什么?
在scicomp.stackexchange.comb
的这篇文章中给出了 由 '\' 运算符调用的算法(和属性检查)的一个很好的分解,具体取决于矩阵的结构。我假设类似的选项适用于运营商。/
对于您的示例,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))