# x values when taking a numerical derivative

조회 수: 4 (최근 30일)
L'O.G. . 2023년 2월 6일
댓글: Star Strider . 2023년 2월 6일
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.

댓글을 달려면 로그인하십시오.

### 채택된 답변

Star Strider 2023년 2월 6일
I think (correct me if I'm wrong) this can be done by diff(y)./diff(x)
Not actually wrong, simply mistaken with respect to expecting that the result of diff will be what you want.
Use the gradient function (or Torsten’s approach, that does essentially the same operation) instead:
.
##### 댓글 수: 6이전 댓글 5개 표시이전 댓글 5개 숨기기
Star Strider 2023년 2월 6일
@Torsten — Thank you!

댓글을 달려면 로그인하십시오.

### 추가 답변 (4개)

Sulaymon Eshkabilov 2023년 2월 6일
Yes, you are right, e.g.:
x = [0 .2 .3 .45 .65 .75 .96]
x = 1×7
0 0.2000 0.3000 0.4500 0.6500 0.7500 0.9600
y = [-3 10 11 12 13 12 9]
y = 1×7
-3 10 11 12 13 12 9
dydx = diff(y)./diff(x)
dydx = 1×6
65.0000 10.0000 6.6667 5.0000 -10.0000 -14.2857
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이전 댓글 1개 표시이전 댓글 1개 숨기기
Sulaymon Eshkabilov 2023년 2월 6일
difference1 is between 1 and 2 and then 2 and 3, etc., and thus end-1

댓글을 달려면 로그인하십시오.

Tushar Behera 2023년 2월 6일
편집: Tushar Behera 님. 2023년 2월 6일
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
##### 댓글 수: 0이전 댓글 -1개 표시이전 댓글 -1개 숨기기

댓글을 달려면 로그인하십시오.

Torsten 2023년 2월 6일
편집: Torsten 님. 2023년 2월 6일
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));
##### 댓글 수: 0이전 댓글 -1개 표시이전 댓글 -1개 숨기기

댓글을 달려면 로그인하십시오.

Sulaymon Eshkabilov 2023년 2월 6일
편집: Sulaymon Eshkabilov 님. 2023년 2월 6일
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);
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);
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)])
Norm of errors @ dx = 0.063467: E_diff = 0.223238; E_gradient = 0.004770; E_loop = 0.223238; E_grad_vect = 0.004770
% 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);
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)])
Norm of errors @ dx = 0.006289: E_diff = 0.070283; E_gradient = 0.000147; E_loop = 0.070283; E_grad_vect = 0.000147

댓글을 달려면 로그인하십시오.

### 카테고리

Help CenterFile Exchange에서 Get Started with MATLAB에 대해 자세히 알아보기

R2021b

### Community Treasure Hunt

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

Start Hunting!

Translated by