Gradient Vector for partial derivative seems backward for dfdx
31 views (last 30 days)
Show older comments
Kevin Cornelius
on 2 Dec 2024 at 1:43
Commented: Paul
on 2 Dec 2024 at 19:39
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')
fprintf('Dfx = %9.5f\n',Dfx(xo,yo))
fprintf('Dfy = %9.5f\n',Dfy(xo,yo))
%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')
fprintf('Dfx = %9.5f\n',nDfx(nxo,nyo)) %incorrect value
fprintf('Dfx = %9.5f\n',nDfx(nyo,nxo)) %correct value, but why?
fprintf('Dfy = %9.5f\n',nDfy(nxo,nyo))
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?
0 Comments
Accepted Answer
Paul
on 2 Dec 2024 at 2:16
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
nDfx(nyo,nxo) %correct value, but why?
nDfy(nxo,nyo) % happens to be the correct value
nDfy(nyo,nxo) % corret value
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
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 Comments
Paul
on 2 Dec 2024 at 19:39
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)
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)
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.
More Answers (0)
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!