19 views (last 30 days)

Show older comments

L'O.G. on 6 Feb 2023

Commented: Star Strider on 6 Feb 2023

Accepted Answer: Star Strider

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.

##### 0 Comments Show -2 older commentsHide -2 older comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sign in to answer this question.

### Accepted Answer

Star Strider on 6 Feb 2023

‘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:

dydx = gradient(y) ./ gradient(x);

.

##### 6 Comments Show 4 older commentsHide 4 older comments

Show 4 older commentsHide 4 older comments

L'O.G. on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2601270

Thank you!

L'O.G. on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2601290

Just to make sure I understand, would you be able to tell me why you recommend using gradient rather than diff here? They give quite different results.

Star Strider on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2601350

As always, my pleasure!

The gradient funciton returns an estimate of the derivative with the length (and more generally, size) of the output being the same as the input. (It can also be used to calculate spatial derivatives.) It is more accurate than diff, that simply calculates sequential differences. It computes a numerical derivative by approximating it with central differences, as described in the documentation section on Algorithms, and also described by Torstein’s code, that describes it in more detail.

.

L'O.G. on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2601945

Thank you again. Sorry, just one more question (I promise this will be it for this thread): the support page for gradient says that FX = gradient(F) corresponds to /, so why do you recommend dividing by the gradient in x in this case?

Torsten on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2601980

the support page for gradient says that FX = gradient(F) corresponds to /, so why do you recommend dividing by the gradient in x in this case?

Because in the case FX = gradient(F), the distance between the x values is assumed to be 1 for all of them.

Or do you think MATLAB knows how your x vector looks like if you don't supply it ?

Star Strider on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2602040

@Torsten — Thank you!

Sign in to comment.

### More Answers (4)

Sulaymon Eshkabilov on 6 Feb 2023

Open in MATLAB Online

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 Comments Show NoneHide None

Show NoneHide None

L'O.G. on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2600510

⋮

Edited: L'O.G. on 6 Feb 2023

Thanks. So just to be clear, why does dydx(end-1) correspond to x(end)?

Sulaymon Eshkabilov on 6 Feb 2023

#### Direct link to this comment

https://matlabcentral.mathworks.com/matlabcentral/answers/1907035-x-values-when-taking-a-numerical-derivative#comment_2601140

difference1 is between 1 and 2 and then 2 and 3, etc., and thus end-1

Sign in to comment.

Tushar Behera on 6 Feb 2023

Edited: Tushar Behera on 6 Feb 2023

Open in MATLAB Online

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 Comments Show -2 older commentsHide -2 older comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Torsten on 6 Feb 2023

Edited: Torsten on 6 Feb 2023

Open in MATLAB Online

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 Comments Show -2 older commentsHide -2 older comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sulaymon Eshkabilov on 6 Feb 2023

Edited: Sulaymon Eshkabilov on 6 Feb 2023

Open in MATLAB Online

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)])

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);

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)])

Norm of errors @ dx = 0.006289: E_diff = 0.070283; E_gradient = 0.000147; E_loop = 0.070283; E_grad_vect = 0.000147

##### 0 Comments Show -2 older commentsHide -2 older comments

Show -2 older commentsHide -2 older comments

Sign in to comment.

Sign in to answer this question.

### See Also

### Categories

MATLABLanguage FundamentalsMatrices and ArraysCreating and Concatenating Matrices

Find more on **Creating and Concatenating Matrices** 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!

**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list

Americas

- América Latina (Español)
- Canada (English)
- United States (English)

Europe

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- Deutsch
- English
- Français

- United Kingdom(English)

Asia Pacific

- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)

Contact your local office