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

126 vues (au cours des 30 derniers jours)
N/A le 21 Mar 2023
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.
% 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))
I would like to know if there is a method to perform this computation without for loops, like the following:
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!

Réponse acceptée

Bjorn Gustavsson
Bjorn Gustavsson le 21 Mar 2023
Modifié(e) : Bjorn Gustavsson le 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.
  2 commentaires
N/A le 22 Mar 2023
Thank you very much. It solves my problem :)
Bjorn Gustavsson
Bjorn Gustavsson le 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.

Connectez-vous pour commenter.

Plus de réponses (0)




Community Treasure Hunt

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

Start Hunting!

Translated by