Numpy vs mldivide,"\"matlab运算符

Sch*_*ger 7 python matlab numpy

A \ B 在matlab中给出了一个特殊的解决方案,而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]))
Run Code Online (Sandbox Code Playgroud)
  1. A \ Bmatlab 中的mldivide如何提供特殊的解决方案?
  2. 这个解决方案是否有助于实现计算精度?
  3. 为什么这个解决方案很特别,你怎么可能在numpy中实现它?

小智 9

对于诸如你的欠定系统(秩小于变量的数量),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
Run Code Online (Sandbox Code Playgroud)

对于您的示例,它输出三个"特殊"解决方案,最后一个是Matlab选择的.

[[-1. ]
 [ 4.5]
 [ 0. ]]

[[ 8.]
 [ 0.]
 [ 6.]]

[[ 0.        ]
 [ 4.        ]
 [ 0.66666667]] 
Run Code Online (Sandbox Code Playgroud)