x values when taking a numerical derivative
Afficher commentaires plus anciens
I want to calculate the first derivative f(x) = dy/dx for data that is irregularly spaced in x. I think (correct me if I'm wrong) this can be done by diff(y)./diff(x)
But the resulting vector is one less than the length of the x and y vectors, so what are the corresponding x values? I want to then calculate x dy/dx, so it would be helpful to know what to use.
Réponse acceptée
Plus de réponses (4)
Yes, you are right, e.g.:
x = [0 .2 .3 .45 .65 .75 .96]
y = [-3 10 11 12 13 12 9]
dydx = diff(y)./diff(x)
yyaxis left
plot(x, y, 'b-o', 'MarkerFaceColor', 'y', 'DisplayName', 'y(x)')
ylabel('y(x)')
yyaxis right
plot(x(1:end-1), dydx, 'r--p', 'MarkerFaceColor','c','DisplayName', 'dy/dx')
ylabel('dy/dx')
xlabel('x')
grid on
legend show
2 commentaires
Sulaymon Eshkabilov
le 6 Fév 2023
difference1 is between 1 and 2 and then 2 and 3, etc., and thus end-1
Tushar Behera
le 6 Fév 2023
Modifié(e) : Tushar Behera
le 6 Fév 2023
Hi L'O.G,
I believe you want to calculate derivate for two separate datasets. In order to do that you can use 'diff(y)./diff(x)' for example:
clc;
clear;
close all;
x=linspace(0,2*pi,100);
y=sin(x);
yp=cos(x);
dx=diff(x);
dy=diff(y);
yp_hat=dy./dx;
err=yp(1:end-1)-yp_hat;
figure;
subplot(1,2,1);
plot(x,y);
hold on;
plot(x(1:end-1),yp_hat)
xlabel('x');
ylabel('y');
legend('original function','Approx derivative');
grid on;
subplot(1,2,2);
plot(x(1:end-1),err);
xlabel('x');
ylabel('error');

here 'x' and 'y' are two vectors and by using 'diff(y)./diff(x)' you can calculate the first order derivate which is 'cos(x)'. To answer the question which values of x corresponds to which 'yp_hat' . you can get that by using,
x(1:end-1)
I hope this solves your query.
Regards,
Tushar
Use
n = numel(y);
dydx(1) = (y(2) - y(1))/(x(2) - x(1));
dydx(2:n-1) = (y(3:n) - y(1:n-2))./(x(3:n) - x(1:n-2));
dydx(n) = (y(n) - y(n-1))/(x(n) - x(n-1));
Sulaymon Eshkabilov
le 6 Fév 2023
Modifié(e) : Sulaymon Eshkabilov
le 6 Fév 2023
There will be some significantly different results from diff() and gradient() if the increment of x varies. See this simulation:
x = [0 .2 .3 .45 .65 .75 .96];
y = [-3 10 11 12 13 12 9];
dy1 = diff(y)./diff(x);
dy2 = gradient(y)./gradient(x);
for ii = 1:length(x)-1
dy3(ii) = (y(ii+1)-y(ii))/(x(ii+1)-x(ii));
end
N = numel(y);
dy4(1) = (y(2)-y(1))/(x(2)-x(1));
dy4(2:N-1) = (y(3:N)-y(2:N-1))./(x(3:end)-x(2:end-1));
dy4(N) = (y(end)-y(end-1))/(x(end)-x(end-1));
plot(x(1:end-1), dy1, 'b-o', 'MarkerFaceColor', 'y', 'DisplayName', 'diff', 'markersize', 13)
hold on
plot(x(1:end), dy2, 'rs--', 'MarkerFaceColor', 'c', 'DisplayName', 'gradient')
plot(x(1:end-1), dy3, 'g--p', 'MarkerFaceColor','y','DisplayName', 'Loop computed difference', 'MarkerSize', 10)
hold on
plot(x(1:end), dy4, 'k--h', 'MarkerFaceColor','c','DisplayName', 'vectorized: gradient')
ylabel('dy/dx')
xlabel('x')
grid on
legend show
% Note that as the increment of x gets smaller the error (offset) will also
% diminish. See this example: dx = 0.063467 vs. dx = 0.006289:
x=linspace(0,2*pi,100);
dx = x(2);
y=sin(x);
ANS=cos(x);
dY1=diff(y)./diff(x);
dY2 = gradient(y)./gradient(x);
for ii = 1:length(x)-1
dY3(ii) = (y(ii+1)-y(ii))/(x(ii+1)-x(ii)); % The same as diff()
end
n = numel(y);
dY4(1) = (y(2)-y(1))/(x(2)-x(1));
dY4(2:n-1) = (y(3:end)-y(1:end-2))./(x(3:end)-x(1:end-2));
dY4(n) = (y(end)-y(end-1))/(x(end)-x(end-1));
E1=ANS(1:end-1)-dY1;
E2 = ANS-dY2;
E3 = ANS(1:end-1)-dY3;
E4 = ANS-dY4;
fprintf(['Norm of errors @ dx = %f: ' ...
'E_diff = %f; E_gradient = %f; ' ...
'E_loop = %f; E_grad_vect = %f \n'], [dx, norm(E1) norm(E2) norm(E3) norm(E4)])
% 10 times smaller incremental step of x than the previous example leads to
% the reduction of error norm to more than 3 times
x=linspace(0,2*pi,1000);
dx = x(2);
y=sin(x);
ANS=cos(x);
dY1=diff(y)./diff(x);
dY2 = gradient(y)./gradient(x);
for ii = 1:length(x)-1
dY3(ii) = (y(ii+1)-y(ii))/(x(ii+1)-x(ii)); % The same as diff()
end
n = numel(y);
dY4(1) = (y(2)-y(1))/(x(2)-x(1));
dY4(2:n-1) = (y(3:end)-y(1:end-2))./(x(3:end)-x(1:end-2));
dY4(n) = (y(end)-y(end-1))/(x(end)-x(end-1));
E1=ANS(1:end-1)-dY1;
E2 = ANS-dY2;
E3 = ANS(1:end-1)-dY3;
E4 = ANS-dY4;
fprintf(['Norm of errors @ dx = %f: ' ...
'E_diff = %f; E_gradient = %f; ' ...
'E_loop = %f; E_grad_vect = %f \n'], [dx, norm(E1) norm(E2) norm(E3) norm(E4)])
Catégories
En savoir plus sur Spline Postprocessing dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

