MRDIVIDE 或 / 运算符实际上解决了 xb = a 线性系统,而不是 MLDIVIDE 或 \ 运算符将解决系统 bx = a。
要求解具有非对称、不可逆矩阵b 的系统xb = a,您可以依赖mridivide(),这是通过使用高斯消元法对b 进行因式分解完成的,或者pinv() ,这是通过奇异值分解和低于(默认)容差水平的奇异值归零完成的。
这里是区别(mldivide 的情况):What is the difference between PINV and MLDIVIDE when I solve A*x=b?
当系统超定时,两种算法都提供
相同的答案。当系统不确定时,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 在做什么?
根据矩阵b 的结构,'\' 运算符调用的算法(和属性检查)的详细分解在scicomp.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))