相对于矩阵对标量进行微分
Differentiating a scalar with respect to matrix
我有一个标量函数,它是通过迭代计算得到的。我希望区分(找到方向导数)关于矩阵元素的值。在这种情况下我应该如何使用有限差分近似。 diff
或 gradient
在这种情况下有帮助吗?请注意,我只想要数值导数。
我将处理的典型代码是:
n=4;
for i=1:n
for x(i)=-2:0.04:4;
for y(i)=-2:0.04:4;
A(:,:,i)=[sin(x(i)), cos(y(i));2sin(x(i)),sin(x(i)+y(i)).^2];
B(:,:,i)=[sin(x(i)), cos(x(i));3sin(y(i)),cos(x(i))];
R(:,:,i)=horzcat(A(:,:,i),B(:,:,i));
L(i)=det(B(:,:,i)'*A(:,:,i)B)(:,:,i));
%how to find gradient of L with respect to x(i), y(i)
grad_L=tr((diff(L)/diff(R)')*(gradient(R))
endfor;
endfor;
endfor;
我知道 grad_L
的最后一部分会出现语法错误,指出尺寸不匹配。我该如何着手解决这个问题。请注意,矩阵变量 X
的标量函数 f
的梯度或方向导数由 nabla(f)=trace((partial f/patial(x_{ij})*X_dot
给出,其中 x_{ij}
表示矩阵元素,X_dot
表示梯度矩阵的 X
你的代码和解释都很混乱。您正在使用 n = 4 的迭代,但您没有对输入或输出执行任何操作,而是覆盖了所有内容。所以我暂时忽略 n
方面,因为您似乎没有使用它。此外,你有许多看起来更像是数学或伪代码的语法错误,而不是任何编写有效的 Matlab / Octave 的尝试。
但是,从本质上讲,您似乎在问,"I have a function which for each (x,y) coordinate on a 2D grid, it calculates a scalar output L(x,y)",其中导致 L 的计算涉及将两个矩阵相乘,然后得到它们的行列式。下面是如何生成这样的数组 L
:
X = -2 : 0.04 : 4;
Y = -2 : 0.04 : 4;
X_indices = 1 : length(X);
Y_indices = 1 : length(Y);
for Ind_x = X_indices
for Ind_y = Y_indices
x = X(Ind_x); y = Y(Ind_y);
A = [sin(x), cos(y); 2 * sin(x), sin(x+y)^2];
B = [sin(x), cos(x); 3 * sin(y), cos(x) ];
L(Ind_x, Ind_y) = det (B.' * A * B);
end
end
然后你想得到L的梯度,当然是向量输出。现在,为了得到这个,暂时忽略你提到的数学,如果你基本上是想正确使用 gradient
函数,那么你只需直接在 L
上使用它,并指定网格 X
Y
用于指定 L
中不同元素之间的间距,并将其输出收集为双元素数组,以便您同时捕获 x
和y
梯度的矢量分量:
[gLx, gLy] = gradient(L, X, Y);
我有一个标量函数,它是通过迭代计算得到的。我希望区分(找到方向导数)关于矩阵元素的值。在这种情况下我应该如何使用有限差分近似。 diff
或 gradient
在这种情况下有帮助吗?请注意,我只想要数值导数。
我将处理的典型代码是:
n=4;
for i=1:n
for x(i)=-2:0.04:4;
for y(i)=-2:0.04:4;
A(:,:,i)=[sin(x(i)), cos(y(i));2sin(x(i)),sin(x(i)+y(i)).^2];
B(:,:,i)=[sin(x(i)), cos(x(i));3sin(y(i)),cos(x(i))];
R(:,:,i)=horzcat(A(:,:,i),B(:,:,i));
L(i)=det(B(:,:,i)'*A(:,:,i)B)(:,:,i));
%how to find gradient of L with respect to x(i), y(i)
grad_L=tr((diff(L)/diff(R)')*(gradient(R))
endfor;
endfor;
endfor;
我知道 grad_L
的最后一部分会出现语法错误,指出尺寸不匹配。我该如何着手解决这个问题。请注意,矩阵变量 X
的标量函数 f
的梯度或方向导数由 nabla(f)=trace((partial f/patial(x_{ij})*X_dot
给出,其中 x_{ij}
表示矩阵元素,X_dot
表示梯度矩阵的 X
你的代码和解释都很混乱。您正在使用 n = 4 的迭代,但您没有对输入或输出执行任何操作,而是覆盖了所有内容。所以我暂时忽略 n
方面,因为您似乎没有使用它。此外,你有许多看起来更像是数学或伪代码的语法错误,而不是任何编写有效的 Matlab / Octave 的尝试。
但是,从本质上讲,您似乎在问,"I have a function which for each (x,y) coordinate on a 2D grid, it calculates a scalar output L(x,y)",其中导致 L 的计算涉及将两个矩阵相乘,然后得到它们的行列式。下面是如何生成这样的数组 L
:
X = -2 : 0.04 : 4;
Y = -2 : 0.04 : 4;
X_indices = 1 : length(X);
Y_indices = 1 : length(Y);
for Ind_x = X_indices
for Ind_y = Y_indices
x = X(Ind_x); y = Y(Ind_y);
A = [sin(x), cos(y); 2 * sin(x), sin(x+y)^2];
B = [sin(x), cos(x); 3 * sin(y), cos(x) ];
L(Ind_x, Ind_y) = det (B.' * A * B);
end
end
然后你想得到L的梯度,当然是向量输出。现在,为了得到这个,暂时忽略你提到的数学,如果你基本上是想正确使用 gradient
函数,那么你只需直接在 L
上使用它,并指定网格 X
Y
用于指定 L
中不同元素之间的间距,并将其输出收集为双元素数组,以便您同时捕获 x
和y
梯度的矢量分量:
[gLx, gLy] = gradient(L, X, Y);