mrdivide function in MATLAB: what is it doing, and how can I do it in Python?

前端 未结 4 1962
花落未央
花落未央 2020-12-09 20:11

I have this line of MATLAB code:

a/b

I am using these inputs:

a = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]   
b = ones(25, 18)
         


        
4条回答
  •  南方客
    南方客 (楼主)
    2020-12-09 20:41

    MRDIVIDE or the / operator actually solves the xb = a linear system, as opposed to MLDIVIDE or the \ operator which will solve the system bx = a.

    To solve a system xb = a with a non-symmetric, non-invertible matrix b, you can either rely on mridivide(), which is done via factorization of b with Gauss elimination, or pinv(), which is done via Singular Value Decomposition, and zero-ing of the singular values below a (default) tolerance level.

    Here is the difference (for the case of mldivide): What is the difference between PINV and MLDIVIDE when I solve A*x=b?

    When the system is overdetermined, both algorithms provide the same answer. When the system is underdetermined, PINV will return the solution x, that has the minimum norm (min NORM(x)). MLDIVIDE will pick the solution with least number of non-zero elements.

    In your example:

    % 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);
    

    the system is underdetermined, and the two different solutions will be:

    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 
    

    In both cases the approximation error of xb-a is non-negligible (non-exact solution) and the same, i.e. norm(x1*b-a) and norm(x2*b-a) will return the same result.

    What is MATLAB doing?

    A great break-down of the algorithms (and checks on properties) invoked by the '\' operator, depending upon the structure of matrix b is given in this post in scicomp.stackexchange.com. I am assuming similar options apply for the / operator.

    For your example, MATLAB is most probably doing a Gaussian elimination, giving the sparsest solution amongst a infinitude (that's where the 5 comes from).

    What is Python doing?

    Python, in linalg.lstsq uses pseudo-inverse/SVD, as demonstrated above (that's why you get a vector of 0.2's). In effect, the following will both give you the same result as MATLAB's 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)) 
    

提交回复
热议问题