A \ B
提供了一个特殊的解决方案,而numpy.linalg.lstsq没有。
A = [1 2 0; 0 4 3];
b = [8; 18];
c_mldivide = A \ b
c_mldivide =
0
4
0.66666666666667
c_lstsq = np.linalg.lstsq([[1 ,2, 0],[0, 4, 3]],[[8],[18]])
print c_lstsq
c_lstsq = (array([[ 0.91803279],
[ 3.54098361],
[ 1.27868852]]), array([], dtype=float64), 2, array([ 5.27316304,1.48113184]))
A \ B
如何提供特殊解决方案?答案 0 :(得分:8)
对于欠定系统,例如你的(等级小于变量数),mldivide
会返回一个尽可能多的零值的解决方案。哪个变量将设置为零取决于其任意选择。
相反,在这种情况下,lstsq
方法返回最小范数的解决方案:也就是说,在无限系列的精确解中,它将选择具有最小和的一个变量的平方。
所以,"特别" Matlab的解决方案有点武断:在这个问题中,可以将三个变量中的任何一个设置为零。 NumPy给出的解决方案实际上更加特殊:有一个独特的最小范数解决方案
哪种解决方案更适合您的目的取决于您的目的。解决方案的非唯一性通常是重新思考方程方法的一个原因。但是既然你问过,这里是生成Matlab类型解决方案的NumPy代码。
import numpy as np
from itertools import combinations
A = np.matrix([[1 ,2, 0],[0, 4, 3]])
b = np.matrix([[8],[18]])
num_vars = A.shape[1]
rank = np.linalg.matrix_rank(A)
if rank == num_vars:
sol = np.linalg.lstsq(A, b)[0] # not under-determined
else:
for nz in combinations(range(num_vars), rank): # the variables not set to zero
try:
sol = np.zeros((num_vars, 1))
sol[nz, :] = np.asarray(np.linalg.solve(A[:, nz], b))
print(sol)
except np.linalg.LinAlgError:
pass # picked bad variables, can't solve
对于你的例子,它输出三个"特殊"解决方案,最后一个是Matlab选择的。
[[-1. ]
[ 4.5]
[ 0. ]]
[[ 8.]
[ 0.]
[ 6.]]
[[ 0. ]
[ 4. ]
[ 0.66666667]]