Gradient Vector for partial derivative seems backward for dfdx

2 次查看(过去 30 天)
clc; clear;
xo = 0.8;
yo = 0.2;
%analytic solution
syms f(x,y) %tells matlab to treat f(x) symbolically
f(x,y) = x*exp(-(x^2+y^2));
%Calculate Derivatives
Dfx = diff(f,x); %partial of f w.r.t x
Dfy = diff(f,y); %partial of f w.r.t y
fprintf('Analytic Solutions:\n')
Analytic Solutions:
fprintf('Dfx = %9.5f\n',Dfx(xo,yo))
Dfx = -0.14185
fprintf('Dfy = %9.5f\n',Dfy(xo,yo))
Dfy = -0.16212
%numerical solution
h = 0.01; %grid size deltax = deltay = 0.01
[nx,ny] = meshgrid(0:h:2); %x and y range from 0 to 2, step size h
z = nx.*exp(-(nx.^2+ny.^2));
%locate index values for xo = 0.8 and yo = 0.2.
nxo = find(nx(1,:)==xo);
nyo = find(ny(:,1)==yo);
Calculate Derivatives
[nDfx, nDfy] = gradient(z,h); %calculate the partials w.r.t x and y
fprintf('Numerical Solutions:\n')
Numerical Solutions:
fprintf('Dfx = %9.5f\n',nDfx(nxo,nyo)) %incorrect value
Dfx = 0.46604
fprintf('Dfx = %9.5f\n',nDfx(nyo,nxo)) %correct value, but why?
Dfx = -0.14180
fprintf('Dfy = %9.5f\n',nDfy(nxo,nyo))
Dfy = -0.16211
These are the outputs:
Analytic Solutions:
Dfx = -0.14185
Dfy = -0.16212
Numerical Solutions:
Dfx = 0.46604
Dfx = -0.14180
Dfy = -0.16211
Why must I switch the order for dfdx in order to get the correct result?

采纳的回答

Paul
Paul 2024-12-2
Hi Kevin,
It turns out that nDfy only gives the correct result because of the symmetry.
xo = 0.8;
yo = 0.2;
h = 0.01; %grid size deltax = deltay = 0.01
[nx,ny] = meshgrid(0:h:2); %x and y range from 0 to 2, step size h
z = nx.*exp(-(nx.^2+ny.^2));
%locate index values for xo = 0.8 and yo = 0.2.
nxo = find(nx(1,:)==xo);
nyo = find(ny(:,1)==yo);
[nDfx, nDfy] = gradient(z,h); %calculate the partials w.r.t x and y
nDfx(nxo,nyo) %incorrect value
ans = 0.4660
nDfx(nyo,nxo) %correct value, but why?
ans = -0.1418
nDfy(nxo,nyo) % happens to be the correct value
ans = -0.1621
nDfy(nyo,nxo) % corret value
ans = -0.1621
When we use meshgrid, the x-values vary across the 2nd dimension (horizontal) and the y-values vary down the 1st dimension (vertical). Sounds counterintutive, but that's how it works. Similarly, gradient assumes the x-direction is horizontal across the array and the y-direction is vertical down the array, which is consistent with the meshgrid convention. But that means that indexing into the results also has to reverse as well, which is what we're seeing.
Consider a simpler problem
x = 1:3;
y = 101:103;
[X,Y] = meshgrid(x,y);
Z = 5*X + Y
Z = 3×3
106 111 116 107 112 117 108 113 118
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
If we want the value of Z that corresponds to the second element of x and the first element y (z = 5*2 + 101 = 111), we'd need Z(1,2)
  4 个评论
Kevin
Kevin 2024-12-2
I will play around with this further, but it seems odd to switch the order of the arrays. To me, it seems like you use f(xo,yo) to evaluate the function at (xo,yo), but dfdx(yo,xo) for the derivative. Why would you want to do that?
Paul
Paul 2024-12-2
When using meshgrid, indexing into the function array is the same as indexing into the gradient arrays:
xo = 0.8;
yo = 0.2;
h = 0.01; %grid size deltax = deltay = 0.01
v = 0:h:2;
nxo = find(v==xo);
nyo = find(v==yo);
[nx,ny] = meshgrid(v); %x and y range from 0 to 2, step size h
z = nx.*exp(-(nx.^2+ny.^2));
[z(nyo,nxo) xo.*exp(-(xo.^2 + yo.^2))] % z(nyo,nxo)
ans = 1×2
0.4053 0.4053
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
If all we want is to index into the function array as z(nxo,nyo), then we can use ndgrid
[nx,ny] = ndgrid(v);
z = nx.*exp(-(nx.^2+ny.^2));
[z(nxo,nyo) xo.*exp(-(xo.^2 + yo.^2))] % z(nxo,nyo)
ans = 1×2
0.4053 0.4053
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
However, gradient expects the input array to be in meshgrid format, so if z is in ndgrid format we'd have to go through some additional gymnastics.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

产品


版本

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by