Matlab 符号梯度与解析梯度大不相同

Matlab 符号梯度与解析梯度大不相同,matlab,matlab-figure,Matlab,Matlab Figure,我试图模拟一个移动机器人网络,该网络使用人工势场来规划到共享目的地xd的移动。这是通过从符号表达式生成一系列m文件(每个机器人一个)来完成的,因为这似乎是计算时间和精度方面的最佳方式。然而,我无法找出我的梯度计算出了什么问题:正在计算的分析梯度似乎是错误的,而数值梯度的计算是正确的(见下图)。我写了下面列出的MWE,它也显示了这个问题。我已经检查了代码的文件生成部分,它确实返回了一个具有正确梯度的正确函数文件。但我不明白为什么解析梯度和数值梯度如此不同 (可以找到下图的放大版) 我试图生成的势

我试图模拟一个移动机器人网络,该网络使用人工势场来规划到共享目的地xd的移动。这是通过从符号表达式生成一系列m文件(每个机器人一个)来完成的,因为这似乎是计算时间和精度方面的最佳方式。然而,我无法找出我的梯度计算出了什么问题:正在计算的分析梯度似乎是错误的,而数值梯度的计算是正确的(见下图)。我写了下面列出的MWE,它也显示了这个问题。我已经检查了代码的文件生成部分,它确实返回了一个具有正确梯度的正确函数文件。但我不明白为什么解析梯度和数值梯度如此不同

(可以找到下图的放大版)

我试图生成的势场由(x,y)位置定义,在我的代码中称为
xd
x
是尺寸nx2的位置矩阵,其中第一列表示x1、x2等,第二列表示y1、y2等。Xvec只是将该向量重新整形为x1、y1、x2、y2、x3、y3等等,因为我生成的matlabfunction只接受向量输入


机器人i的梯度是通过导数w.r.t.x_i和y_i来计算的,这两个分量共同产生一个导数“向量”,如箭图所示。导数应该是这样的,我检查了[gradx,grady]的符号表达式在生成m文件之前确实是这样的与符号渐变相比,未给出正确的结果。我会尽力解释的。以下是如何创建
xGrid
yGrid

% create a grid centered on the selected (x,y) pair
xGrid = (x(i,1)-0.1):0.005:(x(i,1)+0.1);
yGrid = (x(i,2)-0.1):0.005:(x(i,2)+0.1);
但是在
for
循环中,
ii
jj
phi(jj,ii)
gradx(ii,jj)
一样使用,但对应于相同的物理位置。这就是为什么你的结果不同。您遇到的另一个问题是您使用的
渐变
不正确。Matlab假设
[FX,FY]=梯度(phi)
意味着
phi
是从
phi=f(x,y)
计算出来的,其中
x
y
是使用
meshgrid
创建的矩阵。实际上,
phi
元素的排列方式与此不同,因此
梯度(phi)
给出了错误的答案。在反转
jj
ii
以及不正确的梯度之间,错误被抵消了(我怀疑您在尝试
phi(ii,jj)
之后,首先尝试了
phi(ii,jj)
,但发现它不起作用)

无论如何,要将其全部整理出来,在创建
xGrid
yGrid
后的行中,将以下内容放入:

[X,Y]=meshgrid(xGrid,yGrid);
然后在加载
fun
fun2
后将代码更改为:

for ii = 1:length(xGrid) %// x loop
    for jj = 1:length(yGrid) %// y loop
        xp(i,:) = [X(ii,jj);Y(ii,jj)]; %// using X and Y not xGrid and yGrid
        Xvec = reshape(xp.',1,size(x,1)*size(x,2));
        [gradx(ii,jj),grady(ii,jj)] = fun(Xvec,xd);
        phi(ii,jj) = fun2(Xvec,xd);  
    end
end

[FX,FY] = gradient(phi,0.005); %// use the second argument of gradient to set spacing

subplot(2,2,2*i-1)
hold all
axis([min(X(:)) max(X(:)) min(Y(:)) max(Y(:))]) %// use axis rather than xlim/ylim
quiver(X,Y,gradx,grady)
contour(X,Y,phi)
title(strcat('Analytic result for position ',int2str(i)));
xlabel('x');
ylabel('y');

subplot(2,2,2*i)
hold all
axis([min(X(:)) max(X(:)) min(Y(:)) max(Y(:))])
quiver(X,Y,FX,FY)
contour(X,Y,phi)
title(strcat('Numerical result for position ',int2str(i)));
xlabel('x');
ylabel('y');

我对你的代码还有其他一些意见。我认为你的势函数定义不清楚,这导致了各种各样的问题。你在问题中说,
x
是一个Nx2矩阵,但你的势函数定义为

norm(x(i,:)-xd)/norm(x(1,:)-x(2,:));
也就是说,如果
N
为三,则有以下三种电位:

norm(x(1,:)-xd)/norm(x(1,:)-x(2,:));
norm(x(2,:)-xd)/norm(x(1,:)-x(2,:));
norm(x(3,:)-xd)/norm(x(1,:)-x(2,:));
我不认为第三个有意义。我认为这可能会造成一些梯度混乱


此外,我不确定是否有理由在真实代码中创建
.m
文件函数,但它们不是您发布的代码所必需的。

看起来analytical没有做正确的事情!你能给出梯度计算的数学描述吗?我发现
x
xd
Xvec
令人费解,而且你的梯度似乎与标准的
x
和y`导数不一致。@David:我在代码下面添加了一些信息,如果仍然有效,请告诉我unclear@AnderBiguri事实似乎的确如此,由于数值方法中的箭图与等高线图垂直,但分析梯度不垂直。@AnderBiguri等高线图也是错误的,这是因为没有使用
meshgrid
计算位置,所以一切都在错误的位置。非常感谢,非常有魅力。关于势函数:我选择这个势函数是为了说明,我的实际势函数依赖于所有移动机器人之间的互连,但是有点太复杂了,不能放在这里。我认为从符号表达式生成m文件将是计算分析梯度的最有效的方法,因为使用
subs
非常慢,我需要计算很多梯度。啊,那很好。您可以只使用
matlabFunction
生成渐变函数,但不保存和加载它们。
norm(x(1,:)-xd)/norm(x(1,:)-x(2,:));
norm(x(2,:)-xd)/norm(x(1,:)-x(2,:));
norm(x(3,:)-xd)/norm(x(1,:)-x(2,:));