Search code examples
matlabmatrixlinear-algebrasymbolic-math

How to extract coefficients of variables in a matrix in Matlab


Suppose I have the matrix below:

syms x y z
M = [x+y-z;2*x+3*y+-5*z;-x-y6*z];

I want to have the a matrix consisting the coefficients of the variables x,y, and z:

CM = [1,1,-1;2,3,-5;-1,-1,6];

If I multiply CM by [x;y;z], I expect to get M.

Edit

I have a system of ODE:

(d/dt)A = B

A and B are square matrices. I want to solve these set of equations. I don't want to use ode solving commands of Matlab. If I turn the above set of equations into:

(d/dt)a = M*a

then I can solve it easily by the eigen vectors and values of matrix M. Here a is a column vector containing the variables, and M is the matrix of coefficient extracted from B.


Solution

  • Since you seem to be using the Symbolic Math Toolbox, you should diff symbolically, saving the derivative with respect to each variable:

    syms x y z;
    M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
    Mdiff=[];
    for k=symvar(M)
       Mdiff=[Mdiff diff(M,k)];
    end
    

    Then you get

    Mdiff =
    
    [  1,  1, -1]
    [  2,  3, -5]
    [ -1, -1,  6]
    

    If you want to order the columns in a non-lexicographical way, then you need to use a vector of your own instead of symvar.

    Update

    Since you mentioned that this approach is slow, it might be faster to use coeffs to treat M as a polynomial of its variables:

     syms x y z;
     M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
     Mdiff2=[];
     varnames=symvar(M);
    
     for k=1:length(M)
        Mdiff2=[Mdiff2; coeffs(M(k),varnames(end:-1:1))];
     end
    

    Note that for some reason (which I don't understand) the output of coeffs is reversed compare to its input variable list, this is why we call it with an explicitly reversed version of symvar(M).

    Output:

    >> Mdiff2
    
    Mdiff2 =
    
    [  1,  1, -1]
    [  2,  3, -5]
    [ -1, -1,  6]
    

    As @horchler pointed out, this second solution will not work if your symbolic vector has varying number of variables in its components. Since speed only matters if you have to do this operation a lot of times, with many configurations of the parameters in your M, I would suggest constructing M parametrically (so that the coefficients are also syms) is possible, then you only have to perform the first version once. The rest is only substitution into the result.