2023-07-05 Matlab中的数值和符号微分.md
2023-07-05 Matlab中的数值和符号微分
Matlab中包含了数值微分的函数diff和gradient,同时这两个函数存在于Symbolic Math Toolbox中,可以对函数句柄进行操作。
1. 数值微分
1-1. diff
diff函数主要用于计算向量的差分,用法有:
- Y = diff(X)
- Y = diff(X,n)
- Y = diff(X,n,dim)
- 当X是向量时
Y = diff(X) 表示对X各元素进行差分,返回n-1个元素: - 当X是mn矩阵时
Y = diff(X) 表示对X按列进行差分,返回(m-1)n矩阵。 - 当X是向量时
Y = diff(X,n) 返回X的n次差分,即diff(X,1) = diff(X), diff(X,2) = diff(diff(X,1)) = diff(diff(X)). - 当X是mn矩阵时
Y = diff(X) 表示按照指定的维度dim进行n次差分,dim=1按列进行差分,dim=2按行进行差分。
知道差分之后可以得到导出的近似值,比如
- h = 0.001; % step size
- X = -pi:h:pi; % domain
- f = sin(X); % range
- Y = diff(f)/h; % first derivative
- Z = diff(Y)/h; % second derivative
- plot(X(:,1:length(Y)),Y,'r',X,f,'b', X(:,1:length(Z)),Z,'k')
注意的长度依次递减1.
1-2. gradient
gradient用于计算数值梯度,主要用法有
- FX = gradient(F)
- [FX,FY] = gradient(F)
- [FX,FY,FZ,...,FN] = gradient(F)
- [___] = gradient(F,h)
- [___] = gradient(F,hx,hy,...,hN)
-
对于n维向量F,gradient(F)返回F的一维数值梯度,点之间的距离假设为1.
-
对于n维向量F,gradient(F, h)返回F的一维数值梯度,点之间的距离为h.
注意到间距必须是均匀的
-
对于mn维矩阵F,[FX, FY] = gradient(F)返回二维数值梯度的 x 和 y 分量, 默认间距为1.
-
对于mn维矩阵F,[FX, FY] = gradient(F,hx,hy)返回二维数值梯度的 x 和 y 分量, 并指定间距hx, hy.
二维数组可以推广到多维数组
gradient返回的长度和原始的长度是一致的,这个diff不一样,其原因在于gradient是计算内部数据点的中心差分,而在边界点使用的是单侧差分
例1 计算指定点处的梯度
- x = -3:0.2:3;
- y = x';
- f = x.^2 .* y.^3;
- surf(x,y,f)
- xlabel('x')
- ylabel('y')
- zlabel('z')
- [fx,fy] = gradient(f,0.2);
- x0 = 1;
- y0 = -2;
- t = (x == x0) & (y == y0);
- indt = find(t);
- f_grad = [fx(indt) fy(indt)]
其困难在于计算梯度并找到指定点处的数值梯度,这里生成了一个判断矩阵t,并找到的坐标,然后带入fx和fy.
例2 向量场的等高线图
- x = -2:0.2:2;
- y = x';
- z = x .* exp(-x.^2 - y.^2);
- [px,py] = gradient(z);
- figure
- contour(x,y,z)
- hold on
- quiver(x,y,px,py) %用于绘制箭头
- hold off
2. 符号微分
2-1. diff
diff用于求解符号变量的时候同时会返回符号表达式,主要用法是
- Df = diff(f)
- Df = diff(f,n)
- Df = diff(f,var)
- Df = diff(f,var,n)
- Df = diff(f,var1,...,varN)
- Df = diff(f,mvar)
- diff(f) 计算函数f的一阶导数
- syms f(x)
- f(x) = sin(x^2);
- Df = diff(f,x)
- Df(2) %指定点处的导数
- double(Df(2))
- syms f(x)
- diff(f,n)计算函数f的n阶导数
- syms t
- D4 = diff(t^6,4)
- syms t
- diff(f,var)计算函数f关于var的偏导数
- diff(f,var,n)计算函数f关于var的n阶偏导数
- syms x y
- Df = diff(x*cos(x*y), y, 2)
- syms x y
- Df = diff(f,var1,...,varN)计算函数f关于一系列变量的混合偏导
- syms x y
- Df = diff(x*sin(x*y),x,x,x,y)
- syms x y
- Df = diff(f,mvar)计算mvar为符号矩阵的结果。仅在2021以上的版本中有,我使用的2020没有此功能,2020中符号矩阵可由A = sym('a', [3 3])生成。