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 sym
s) is possible, then you only have to perform the first version once. The rest is only substitution into the result.
[diff(M,x) diff(M,y) diff(M,z)]
. I couldn't find a proper gradient in 2 minutes searching; for 3 variables this can do. – Andras DeakCM
andM
are 3by3. – MOON