Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

second_derivative shows different results from that of applying first_derivative twice #3175

Closed
664787022 opened this issue Sep 1, 2023 · 2 comments
Labels
Type: Question Issues does not require work, but answers a user question

Comments

@664787022
Copy link

What went wrong?

I want to calculate second derivative of a variable, but I find second_derivative shows different results from that of applying first_derivative twice.
There is a big difference between the two results. Which one is correct to abtain second derivative? Thank you in advance!

import xarray as xr
import matplotlib.pyplot as plt
from metpy.calc import first_derivative, second_derivative

z = xr.DataArray([5,3,4,8,9,6,4,3,1,5,6,4,5,2,4,1,3,4,1,2,5,3,5,1,1], coords={'x':np.arange(25)}) 

dzdx = second_derivative(z, axis='x').values 
dzdx2 = first_derivative(first_derivative(z, axis='x'), axis='x').values 

plt.plot(dzdx, label='second_derivative')
plt.plot(dzdx2, label='twice first_derivative')
plt.legend()

image

Operating System

Windows

Version

1.3.1

Python Version

3.9.13

Code to Reproduce

import xarray as xr
import matplotlib.pyplot as plt
from metpy.calc import first_derivative, second_derivative

z = xr.DataArray([5,3,4,8,9,6,4,3,1,5,6,4,5,2,4,1,3,4,1,2,5,3,5,1,1], coords={'x':np.arange(25)}) 

dzdx = second_derivative(z, axis='x').values 
dzdx2 = first_derivative(first_derivative(z, axis='x'), axis='x').values 

plt.plot(dzdx, label='second_derivative')
plt.plot(dzdx2, label='twice first_derivative')
plt.legend()

Errors, Traceback, and Logs

No response

@664787022 664787022 added the Type: Bug Something is not working like it should label Sep 1, 2023
@kgoebber
Copy link
Collaborator

kgoebber commented Sep 1, 2023

I'll refer you to the discussion that happened in closed issue #1389 that contains information about how the two calculations are fundamentally different. Essentially when applying the first derivative twice, you get a smoothed first pass. Additionally, the discussion of issue #893 might be relevant to the conversation around some of the mathematics at play here. Hope this helps distinguish the differences that occur when employing these particular MetPy calculations.

@kgoebber kgoebber added Type: Question Issues does not require work, but answers a user question and removed Type: Bug Something is not working like it should labels Sep 1, 2023
@dopplershift
Copy link
Member

dopplershift commented Sep 1, 2023

To add to what @kgoebber posted above, if you neglect the formulation around non-uniform spacing that MetPy uses, the centered, "3-point" approximation in first_derivative is:
$ f'(x) \approx (f_{i+1} - f_{i - 1}) / 2 \Delta x$

If you apply this twice, you end up with:
$ f''(x) \approx (f_{i+2} - 2f_i + f_{i-2}) / 4 \Delta x^2$

This is the same form as the centered 3-point approximation used in second_derivative:
$f''(x) \approx (f_{i+1} - 2f_i + f_{i-1}) / \Delta x^2$

except the repeated application ends up using further neighbors and a $2 \Delta x$ spacing. Thus the smoothing effect you can see in the graph as you're using a less precise estimate (twice the point spacing).

TLDR; Use second_derivative directly. While calculus indicates that the second derivative is just the first derivative applied twice, numerical approximations do not necessarily stack in the same way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question Issues does not require work, but answers a user question
Projects
None yet
Development

No branches or pull requests

3 participants