MATLAB—离散一元、二元、多元函数求导求梯度(二维、三维、多维空间)(diff和gradient)
(离散)一元函数求导—二维
- 已知同维度的x和y序列,则可使用diff(y)./diff(x)来估算。设x为n维向量,Dx=diff(x),计算向量x的向前差分,DX(i)=X(i+1)-X(i),0<i<n。
- 已知同维度的x和y序列,则可使用gradient(y)./gradient(x)来估算 。梯度gradient用的是中心点差分
- 从区间上看梯度用的范围比导数大一倍!所以梯度方式精度会更高一些!但是梯度法的边界可能会出现误差问题。
%一维列向量(对应一元函数求导)
y=[7.86 7.84 7.82 7.77 7.72 7.68 7.61 7.51 7.42 7.33 7.21 7.07 6.94 6.79 6.64 6.48 6.29 6.11 ...
5.92 5.72 5.50 5.27 5.03 4.78 4.53 4.25 3.98 3.69 3.40 3.10 2.78 2.43 2.09 1.77 1.42 1.09 ...
0.68 0.30];
x=0:0.04:1.48;
subplot(2,2,1);
plot(x,y)
title('原函数')
dy_diff=diff(y)./diff(x);
xx=0.04:0.04:1.48; %维度变了,所以这里重新定义一下自变量
%figure创建一个新的窗口
subplot(2,2,2); %hold on 维度不一致,不能绘制在同一窗口
plot(xx,dy_diff)
title('diff函数')
subplot(2,2,3)
dy_grad=gradient(y)./gradient(x);
x=0:0.04:1.48; %使用length()函数试探向量长度是否一致
plot(x,dy_grad)
title('gradient函数')
输出结果:
(离散)二元函数求导求梯度—三维空间
Gradient(F)函数求的是数值上的梯度,对于二元函数这里的F就为函数值矩阵。(一元函数的话F就是向量)
[Fx,Fy]=gradient(F),其中Fx为其水平方向上的梯度,Fy为其垂直方向上的梯度,Fx的第一列元素为原矩阵第二列与第一列元素之差,Fx的第二列元素为原矩阵第三列与第一列元素之差除以2,以此类推:Fx(i,j)=(F(i,j+1)-F(i,j-1))/2。最后一列则为最后两列之差。同理,可以得到Fy。
例如:
F=[6,9,3,4,0;5,4,1,2,5;6,7,7,8,0;7,8,9,10,0]
即函数值矩阵为:
>> [Fx,Fy]=gradient(F)
输出结果:
Fx =
3.0000 -1.5000 -2.5000 -1.5000 -4.0000
-1.0000 -2.0000 -1.0000 2.0000 3.0000
1.0000 0.5000 0.5000 -3.5000 -8.0000
1.0000 1.0000 1.0000 -4.5000 -10.0000
Fy =
-1.0000 -5.0000 -2.0000 -2.0000 5.0000
0 -1.0000 2.0000 2.0000 0
1.0000 2.0000 4.0000 4.0000 -2.5000
1.0000 1.0000 2.0000 2.0000 0
结果解释:Fx表示每一个点处对x的偏导,Fy表示每一个点处对y的偏导。例如函数值是6这一点处对x的偏导数为3,对y的偏导数为-1,这一点处的梯度为(3,-1).
【注意偏导数是一个数,梯度是一个向量,既有大小又有方向。】
一开始我很疑惑,这里我不懂为啥是这个样子,为啥不是像上面说离散一元函数求导那样有:gradient(y)./gradient(x)
这个只有函数值矩阵呀?也就是只有函数值呀,为啥只对函数值进行了差分,没有gradient(F)./gradient(x)
没有gradient(F)./gradient(y)
?直接gradient(F)
就是梯度了?
菜鸡果然是菜鸡…
然后看了一下gradient()函数的用法…哦!是这样的:
[FX,FY] = gradient(F) 返回矩阵 F 的二维数值梯度的 x 和 y 分量。每个方向上的点之间的间距假定为 1。
自变量之间的距离默认为1了,也就是gradient(自变量)=1,所以直接gradient(F)就是梯度值了。
所以如果有一天,小菜鸡获得了一个离散函数值矩阵F,但函数值对应的自变量之间的间距不是1,而是其他的比如是10,那么就要设置一下自变量的间距,具体的语法是:[FX,FY] = gradient(F,hx,hy)
其中hx表示自变量1的间距,hy表示自变量2的间距。
网友案例
在CSDN上看到这样一个例子,题主发出来的例子还没有解答:
我想求以下坐标点构成的曲面的偏导数,不是先拟合出函数再求,而是对离散点用差分法求,不知道怎么操作,希望能得到解答
x=linspace(4.97,7.47,12);
y=linspace(1.34,3.84,12);
z=[0.798244 0.901491 1.017275 1.143169 1.278748 1.428146 1.598996 1.798642 2.0272 2.268551 2.513092 2.750643
0.864101 0.977688 1.104656 1.241846 1.387899 1.546248 1.723809 1.927275 2.156333 2.395788 2.633801 2.856417
0.929699 1.053369 1.190896 1.338288 1.493399 1.659119 1.841813 2.047668 2.276033 2.512622 2.742516 2.953214
0.995203 1.128478 1.275511 1.43147 1.59371 1.764847 1.950888 2.157592 2.383908 2.61635 2.838233 3.040193
1.061214 1.203453 1.358655 1.521291 1.688612 1.863258 2.051027 2.257252 2.480391 2.70764 2.922821 3.118565
1.128837 1.279329 1.441344 1.608944 1.779682 1.956419 2.144821 2.349791 2.569286 2.791146 3.000813 3.191565
1.199633 1.357596 1.525108 1.696229 1.869132 2.046962 2.235288 2.438578 2.654342 2.871077 3.075895 3.262051
1.274609 1.439139 1.610884 1.784329 1.958437 2.136621 2.324363 2.52569 2.737744 2.949703 3.149976 3.331591
1.353984 1.524095 1.698945 1.873801 2.04842 2.226431 2.413232 2.612413 2.820842 3.028366 3.224094 3.401016
1.437333 1.612043 1.789093 1.964729 2.139381 2.316857 2.502464 2.699384 2.904298 3.107622 3.298604 3.470585
1.523777 1.702221 1.880829 2.056847 2.23122 2.407915 2.592147 2.786734 2.988225 3.187417 3.373362 3.540142
1.612192 1.7937 1.973482 2.149662 2.323561 2.499308 2.682023 2.874214 3.072324 3.267271 3.447892 3.609262];
解答:
z=[0.798244 0.901491 1.017275 1.143169 1.278748 1.428146 1.598996 1.798642 2.0272 2.268551 2.513092 2.750643
0.864101 0.977688 1.104656 1.241846 1.387899 1.546248 1.723809 1.927275 2.156333 2.395788 2.633801 2.856417
0.929699 1.053369 1.190896 1.338288 1.493399 1.659119 1.841813 2.047668 2.276033 2.512622 2.742516 2.953214
0.995203 1.128478 1.275511 1.43147 1.59371 1.764847 1.950888 2.157592 2.383908 2.61635 2.838233 3.040193
1.061214 1.203453 1.358655 1.521291 1.688612 1.863258 2.051027 2.257252 2.480391 2.70764 2.922821 3.118565
1.128837 1.279329 1.441344 1.608944 1.779682 1.956419 2.144821 2.349791 2.569286 2.791146 3.000813 3.191565
1.199633 1.357596 1.525108 1.696229 1.869132 2.046962 2.235288 2.438578 2.654342 2.871077 3.075895 3.262051
1.274609 1.439139 1.610884 1.784329 1.958437 2.136621 2.324363 2.52569 2.737744 2.949703 3.149976 3.331591
1.353984 1.524095 1.698945 1.873801 2.04842 2.226431 2.413232 2.612413 2.820842 3.028366 3.224094 3.401016
1.437333 1.612043 1.789093 1.964729 2.139381 2.316857 2.502464 2.699384 2.904298 3.107622 3.298604 3.470585
1.523777 1.702221 1.880829 2.056847 2.23122 2.407915 2.592147 2.786734 2.988225 3.187417 3.373362 3.540142
1.612192 1.7937 1.973482 2.149662 2.323561 2.499308 2.682023 2.874214 3.072324 3.267271 3.447892 3.609262];
>> x=linspace(4.97,7.47,12);
>> y=linspace(1.34,3.84,12);
>> grad_x=gradient(z)./gradient(x);
>> grad_y=gradient(z)./gradient(y);
注意,这里需要使用的就是gradient(F)./gradient(自变量)了!
输出结果:
m0_60793153: 二阶偏导怎么求啊
CSDN-Ada助手: 恭喜你写了第6篇博客!标题“Jacobi雅克比矩阵与偏导数向量的关系和不同”非常吸引人。你在这篇博客中清晰地解释了雅克比矩阵和偏导数向量之间的关系,让读者更好地理解了它们的不同之处。我真的很欣赏你对这个主题的深入研究。 在下一步的创作中,我想建议你考虑提供一些实际应用的例子,以帮助读者更好地理解雅克比矩阵和偏导数向量的实际意义。此外,你可以探索一些相关概念,如海森矩阵或梯度向量,以进一步丰富读者的知识。期待你在以后的博客中继续分享你的见解!
天际的风笛~~: 补充,最后一个问题 求取对y偏导有问题 gradient(z)默认输出对x偏导,修改如下: [code=plain] [fx,fy]=gradient(z) Fx=fx./gradient(x)%对x偏导 Fy=fy./gradient(y)%对y偏导 [/code]
weixin_40147929: 很有帮助的帖子,求更离散多元函数的求导,期待后续