help文件中关于gradient:
FX = gradient(F) 返回向量 F 的一维数值梯度。输出 FX 对应于 ∂F/∂x,即 x(水平)方向上的差分。点之间的间距假定为 1。
[___] = gradient(F,h) 使用 h 作为每个方向上的点之间的均匀间距。您可以指定上述语法中的任何输出参数。
[___] = gradient(F,hx,hy,…,hN) 为 F 的每个维度上的间距指定 N 个间距参数。
其中h的意义一开始并不明白,后来测试后才知道其实就是生成x与y的一维数组的时候的间距,有的时候是0.1 有的时候是1,取决于计算的需要
比如
x=[-1:0.1:1];
y=[-1:0.1:1]';
[X,Y]=meshgrid(x,y);
Z=2*X.*Y;
h=contour(Z,12);
clabel(h);
hold on
[dx, dy]=gradient(Z,0.1,0.1);
quiver(dx, dy);
hold off
第五行的12是画12个等值线
第一行和第二行的0.1就是生成数组的间隔,
因此在第8行的调用gradient函数的时候,括号内后两个值就应该取0.1,这样得到的梯度值才是对的。
其实就是这样
x=[-1:a:1];
y=[-1:b:1]';
[X,Y]=meshgrid(x,y);
Z=2*X.*Y;
h=contour(Z,12);
clabel(h);
hold on
[dx, dy]=gradient(Z,a,b);
quiver(dx, dy);
hold off
a和a是对应的,b和b是对应的
这主要是由matlab里面gradient函数的求解方法有关。接下来会解释。
假设一个矩阵Z为:
Z =
6 9 3 4 0
5 4 1 2 5
6 7 7 8 0
7 8 9 10 0
那么
[Fx,Fy]=gradient(Z)
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
具体来说就是对x的梯度
Fx的第一列为Z的第二列减去第一列,
Fx的第二列为Z的(第三列减去第一列)/2,
Fx的第三列为Z的(第四列减去第二列)/2,
Fx的第四列为Z的(第五列减去第三列)/2,
Fx的最后一列为Z的最后一列减去倒数第二列。
这就是最简单的差分格式
同理
Fy的第一行为为Z的第二行减去第一行,
Fx的第二行为Z的(第三行减去第一行)/2,
Fx的第三行为Z的(第四行减去第二行)/2,
Fx的第四行为Z的(第五行减去第三行)/2,
Fx的最后一行为Z的最后一行减去倒数第二行。
当相应的x和y的队列相差为1的时候当然没问题
但是如果相差不为1时,算出的就不对了
例如
Z=2xy时
x=[-1:0.5:1];
y=[-1:0.5:1]';
[X,Y]=meshgrid(x,y);
Z=2*X.*Y;
[dx, dy]=gradient(Z);
第五行中gradient中只写Z而不设定h参数就默认为1,我们可以得到
X =
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
Y =
-1.0000 -1.0000 -1.0000 -1.0000 -1.0000
-0.5000 -0.5000 -0.5000 -0.5000 -0.5000
0 0 0 0 0
0.5000 0.5000 0.5000 0.5000 0.5000
1.0000 1.0000 1.0000 1.0000 1.0000
Z =
2.0000 1.0000 0 -1.0000 -2.0000
1.0000 0.5000 0 -0.5000 -1.0000
0 0 0 0 0
-1.0000 -0.5000 0 0.5000 1.0000
-2.0000 -1.0000 0 1.0000 2.0000
很容易知道 dx=2Y,dy=2X
所以dx应该等于Y这个矩阵乘2
但是,得到的结果为
dx =
-1.0000 -1.0000 -1.0000 -1.0000 -1.0000
-0.5000 -0.5000 -0.5000 -0.5000 -0.5000
0 0 0 0 0
0.5000 0.5000 0.5000 0.5000 0.5000
1.0000 1.0000 1.0000 1.0000 1.0000
dy =
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
-1.0000 -0.5000 0 0.5000 1.0000
所以说明这样求得的梯度正好小了50%
正是因为我们调用gradient的时候没有在后面加参数h
[dx, dy]=gradient(Z);//错误的命令
正确的命令应该是
[dx, dy]=gradient(Z,0.5,0.5);
这次得到的dx和dy就对了
dx =
-2 -2 -2 -2 -2
-1 -1 -1 -1 -1
0 0 0 0 0
1 1 1 1 1
2 2 2 2 2
dy =
-2 -1 0 1 2
-2 -1 0 1 2
-2 -1 0 1 2
-2 -1 0 1 2
-2 -1 0 1 2
所以,总而言之,调用gradient求梯度的时候,一定记得要加h参数,并且这个参数的值应该等于相应的x和y的间隔。
本文围绕Matlab里的gradient函数展开。介绍了该函数不同调用语法,指出h参数代表生成x与y一维数组时的间距。通过实例说明调用gradient求梯度时,若不设置h参数默认间距为1,可能导致结果错误,强调调用时要加h参数且值应等于x和y的间隔。
5005

被折叠的 条评论
为什么被折叠?



