Python Numpy包中的linalg.lstsq()函数与Matlab中 \ 的区别

Python Numpy包中的linalg.lstsq()函数与Matlab中 \ 的区别

起因:将Matlab的代码转换为Python形式的过程中发现这一情况。
经过:根据Python Numpy包中各种操作符与Matlab的对应关系将程序转换完毕后。在测试的时候发现Python结果输出与Matlab的结果并不一致。于是开启调试模式,在分步调试过程中发现是在进行 \ 运算时,Python和Matlab开始出现区别,于是进行分析百度。
已知:A \ B 和 linalg.lstsq(A,B)[0]是对线性方程组 A m × n X n × k = B m × k A_{m\times n} X_{n\times k} = B_{m\times k} Am×nXn×k=Bm×k求解 X X X,这里 A 、 X 、 B A、X、B AXB分别表示 m × n , n × k , 和 m × k m\times n, n\times k, 和 m\times k m×n,n×k,m×k矩阵。返回结果为X。当A为方阵时,linalg.lstsq(A,B)改用linalg.solve(A,B)求解。
讨论

  1. m < n m < n m<n时, r a n k ( A ) < = n , 即 未 知 数 的 个 数 > 方 程 组 的 个 数 。 这 时 通 解 X 有 n − m 个 基 础 解 系 , 由 不 同 的 基 础 解 系 组 成 的 特 解 有 C n n − m 个 rank(A) <= n, 即 未知数的个数>方程组的个数。这时通解X有n-m个基础解系,由不同的基础解系组成的特解有C_{n}^{n-m}个 rank(A)<=n>XnmCnnm

对于Matlab

clc;
clear;
A  = [1,2,3; 4,5,6];
B = [2,4,5,6; 1,2,3,4];
% X = ?
X = A \ B;
disp(X);

运行程序得X如下图所示:
Python Numpy包中的linalg.lstsq()函数与Matlab中 \ 的区别_第1张图片

对于Python

import numpy as np
A = np.array([[1,2,3],[4,5,6]])
B = np.array([[2,4,5,6],[1,2,3,4]])
X = np.linalg.lstsq(A, B, rcond=-1)[0]
print('X value:', X)

运行程序得X如下图所示:
Python Numpy包中的linalg.lstsq()函数与Matlab中 \ 的区别_第2张图片
可以看出,由于矩阵A不满秩,使得X存在多个解,这时Matlab和Python返回的解则不相同。通过查阅资料发现,Matlab返回得解是尽可能多0值得解,Python返回得解是最小二乘解(范数最小)。

那么如何让Python返回和Matlab一样的结果呢?

其实很简单,只需要将相应的 x i x_{i} xi取0即可。以上面为例,
X [ 1 , : ] = 0 X[1,:] = 0 X[1,:]=0, 只需要假设 X X X相应的行为0即可,这时可以这么操作。

import numpy as np
A = np.array([[1,2,3],[4,5,6]])
B = np.array([[2,4,5,6],[1,2,3,4]])
x_index = (0, 2)
X = np.zeros((A.shape[1], B.shape[1]))
X[x_index, :] = np.linalg.solve(A[:, x_index], B)
print('X value:', X)

运行程序得X如下图所示:
Python Numpy包中的linalg.lstsq()函数与Matlab中 \ 的区别_第3张图片
这时Python返回的 X X X和Matlab返回的值一样。

总结:其实对于Matlab和Python的这点区别,对于算法的应用应该区别不大,想返回何种解取决于实际问题。

你可能感兴趣的:(matlab,python,线性代数)