将符号函数乘以微分运算符以创建导数
Multiply symbolic function by differential operator to create derivative
我有一个矩阵,A
:
A=[ x.^2 + y , 0;
0 , x.^2 + y ]
我也有算子矩阵,D
:
D = [d/dx , 0;
0 , d/dy ]
我希望能够乘以 D*A
并得到一个如下所示的矩阵:
B = [ diff(A(1,1),x) , 0 ;
0 , diff(A(2,2),y) ]
显然我不能使用 diff() 函数来执行此操作,因为该函数不是可以乘以函数的运算符。那么我该如何使用符号运算符来解决这个问题呢?实际上,我的矩阵很大,所以不使用运算符乘法是不可取的。
此外,假设我找到了一种生成上述 B
矩阵的方法,它看起来像:
B =
[ 2*x, 0
0, 1]
如何评估 B
,例如 x=2, y=1
;
我的尝试:
subs(B,x,2,y,1)
但这显然是 sym.subs
函数的不正确参数
我也试过:
subs(B,2,1)
这也没有用,所以我的另一个问题是如何在 B
矩阵中替换 x
和 y
。
关于你的第二个问题:用多个值代替符号变量的语法是
subs(B, {x,y}, {2,1})
(并在 Matlab 命令提示符中键入 help subs
即可给出此示例)。
首先:您通过向量化符号导数来加速符号导数计算的想法行不通。向量化对于 low-level 操作很有意义,这些操作可以由一些旨在处理数组的现有 C++ 库批量执行。符号微分是完全不同的东西:每个表达式都有一个复杂的算法 运行 。使用 for 循环查找多个符号导数是合适的,无论有多少。如果需要很长时间,那是因为取很多符号导数需要很长时间。
我寻找的一种可能的优化是在矩阵 B 中的函数之间找到公共元素,以便它们可以微分一次。但这需要处理矩阵中包含哪些函数的细节。
看这里:https://www.mathworks.com/matlabcentral/answers/36580-operator-matrix-for-matrix-differentiation
function dNdv = diffmtx(v,N)
% v -vector m x 1 - sym array
% N - matrix m x n - sym array
rz = arrayfun(@(ii)diff(N(ii,:),v(ii)),(1:numel(v)).','un',0);
dNdv = cat(1,rz{:});
end
我有一个矩阵,A
:
A=[ x.^2 + y , 0;
0 , x.^2 + y ]
我也有算子矩阵,D
:
D = [d/dx , 0;
0 , d/dy ]
我希望能够乘以 D*A
并得到一个如下所示的矩阵:
B = [ diff(A(1,1),x) , 0 ;
0 , diff(A(2,2),y) ]
显然我不能使用 diff() 函数来执行此操作,因为该函数不是可以乘以函数的运算符。那么我该如何使用符号运算符来解决这个问题呢?实际上,我的矩阵很大,所以不使用运算符乘法是不可取的。
此外,假设我找到了一种生成上述 B
矩阵的方法,它看起来像:
B =
[ 2*x, 0
0, 1]
如何评估 B
,例如 x=2, y=1
;
我的尝试:
subs(B,x,2,y,1)
但这显然是 sym.subs
函数的不正确参数
我也试过:
subs(B,2,1)
这也没有用,所以我的另一个问题是如何在 B
矩阵中替换 x
和 y
。
关于你的第二个问题:用多个值代替符号变量的语法是
subs(B, {x,y}, {2,1})
(并在 Matlab 命令提示符中键入 help subs
即可给出此示例)。
首先:您通过向量化符号导数来加速符号导数计算的想法行不通。向量化对于 low-level 操作很有意义,这些操作可以由一些旨在处理数组的现有 C++ 库批量执行。符号微分是完全不同的东西:每个表达式都有一个复杂的算法 运行 。使用 for 循环查找多个符号导数是合适的,无论有多少。如果需要很长时间,那是因为取很多符号导数需要很长时间。
我寻找的一种可能的优化是在矩阵 B 中的函数之间找到公共元素,以便它们可以微分一次。但这需要处理矩阵中包含哪些函数的细节。
看这里:https://www.mathworks.com/matlabcentral/answers/36580-operator-matrix-for-matrix-differentiation
function dNdv = diffmtx(v,N)
% v -vector m x 1 - sym array
% N - matrix m x n - sym array
rz = arrayfun(@(ii)diff(N(ii,:),v(ii)),(1:numel(v)).','un',0);
dNdv = cat(1,rz{:});
end