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

126 vues (au cours des 30 derniers jours)
N/A
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.
% 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!

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.
HTH
  2 commentaires
N/A
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)

Produits


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by