Take the derivative of a SYMBOLIC Matrix with respect to a Vector

101 views (last 30 days)
Hi community,
I am trying to compute the derivative of a matrix with respect to a vector . Both have symbolic components. I cannot use the naive 'for-loop' implementation because the matrix is quite large and, more importantly, the and in general is quite complex (many trigonometric functions). I was wondering if there is a faster 'vectorized' implementation to perform this computation.
% PSEUDOCODE of WHAT I HAVE
% M = matrix function of (x) size: [nxn]
% x vector size: [nx1]
n = length(x)
for i = 1:n
for j = 1:n
for k = 1:n
M_ij = M(i,j)
dM_dx(i,j,k) = diff(M_ij, x(k))
end
end
end
I would like to know if there is a method to perform this computation without for loops, like the following:
% PSEUDOCODE of WHAT I WISH
dM_dx = diff(M, x)
PS: I already tried to look at: Differentiate symbolic expression or function - MATLAB diff (mathworks.com) but doesn't seem to work since it gives me the following error:
'Components of second argument explicitly present in first argument.'
Thank you very much for the help!

Accepted Answer

Bjorn Gustavsson
Bjorn Gustavsson on 21 Mar 2023
Edited: Bjorn Gustavsson on 21 Mar 2023
You might get close enough with jacobian to get the full output:
syms x y real
% simple 2 x 2 matrix:
M = [sin(x+y) cos(x*y);-cos(x/(x^2+y^2)) tan(x)];
% Should return this:
% M =
%
% [ sin(x + y), cos(x*y)]
% [-cos(x/(x^2 + y^2)), tan(x)]
%
% This will turn the 2x2 matrix M into a 4x1 column-array, which jacobian
% can handle:
J = jacobian(M(:),[x,y])
% should return
% J =
%
% [ cos(x + y), cos(x + y)]
% [sin(x/(x^2 + y^2))*(1/(x^2 + y^2) - (2*x^2)/(x^2 + y^2)^2), -(2*x*y*sin(x/(x^2 + y^2)))/(x^2 + y^2)^2]
% [ -y*sin(x*y), -x*sin(x*y)]
% [ tan(x)^2 + 1, 0]
Here you get all 4 x 2 derivatives, you will have to re-sort the rows into the ordering you expect. For this toy-model-example I get:
J3D = reshape(J,[2,2,2]);
to produce something like what you describe. In your case this might be a rather big array of the size n1 x n2 x n_vars - if I understood your problem right.
HTH
  2 Comments
Bjorn Gustavsson
Bjorn Gustavsson on 22 Mar 2023
Good that it solved your problem!
It just dawned on me that it is possible to use the (:)-operation for the assignment to avoid the hassle with reshaping the jacobian:
syms x y real
% Symbolic matrix easier to differentiate manually:
M = [x*y, x^2*y x^3*y;x*y^2, x^2*y^2, x^3*y^2];
% define the size of the Jacobian-like array:
syms JM [2 3 2]
% doing it in one swoop!(?):
JM(:) = jacobian(M(:),[x,y])
...at least I got this to be in the format I think you want your output...
Happy that it helped.

Sign in to comment.

More Answers (0)

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!