I would write a simple wrapper, something along the lines of

def partial_derivative(func, var=0, point=[]):
    args = point[:]
    def wraps(x):
        args[var] = x
        return func(*args)
    return derivative(wraps, point[var], dx = 1e-6)

Demo:

>>> partial_derivative(foo, 0, [3,1])
6.0000000008386678
>>> partial_derivative(foo, 1, [3,1])
2.9999999995311555
Answer from alko on Stack Overflow
🌐
SciPy
docs.scipy.org › doc › scipy › reference › generated › scipy.differentiate.derivative.html
derivative — SciPy v1.17.0 Manual
For each element of the output of f, derivative approximates the first derivative of f at the corresponding element of x using finite difference differentiation.
🌐
SciPy
docs.scipy.org › doc › scipy-1.14.1 › reference › generated › scipy.misc.derivative.html
derivative — SciPy v1.14.1 Manual
Order of the derivative. Default is 1. ... Number of points to use, must be odd. ... Decreasing the step size too small can result in round-off error. ... Try it in your browser! >>> from scipy.misc import derivative >>> def f(x): ...
Discussions

python - scipy.misc.derivative for multiple argument function - Stack Overflow
It is straightforward to compute the partial derivatives of a function at a point with respect to the first argument using the SciPy function scipy.misc.derivative. Here is an example: def foo(x, ... More on stackoverflow.com
🌐 stackoverflow.com
python - Computing numeric derivative via FFT - SciPy - Computational Science Stack Exchange
I wrote the following code to compute the approximate derivative of a function using FFT: from scipy.fftpack import fft, ifft, dct, idct, dst, idst, fftshift, fftfreq from numpy import linspace, z... More on scicomp.stackexchange.com
🌐 scicomp.stackexchange.com
May 30, 2020
python - Scipy Derivative - Stack Overflow
I have a question about the derivative function of Scipy. I used it last night and got some odd answers. I tried again this morning with some simple functions and got some right answers and some wr... More on stackoverflow.com
🌐 stackoverflow.com
Help with scipy derivatives
Here, SciPy computes derivatives numerically, using finite differencing . The default setting (from the docs) is the central difference with step size 1 about your point: f'(1) approx (f(2)-f(0))/2 which gives what you got. You can lower the dx setting and/or increase the order to give you a better result. Try a = der(f,1,dx=1e-5) instead. More on reddit.com
🌐 r/learnpython
3
2
February 3, 2021
🌐
SciPy
docs.scipy.org › doc › scipy › reference › differentiate.html
Finite Difference Differentiation (scipy.differentiate) — SciPy v1.17.0 Manual
SciPy differentiate provides functions for performing finite difference numerical differentiation of black-box functions · derivative(f, x, *[, args, tolerances, ...])
🌐
SciPy
docs.scipy.org › doc › scipy-1.16.1 › reference › generated › scipy.differentiate.derivative.html
derivative — SciPy v1.16.1 Manual
For each element of the output of f, derivative approximates the first derivative of f at the corresponding element of x using finite difference differentiation.
🌐
YouTube
youtube.com › tsinfo technologies
How to find the derivative of the given function using scipy | Python Scipy derivative - YouTube
In this Python SciPy video tutorial, I will tell you How to find the derivative of the given function using Scipy. Then I will explain how to compute the der...
Published   September 25, 2022
Views   946
Find elsewhere
🌐
Svitla Systems
svitla.com › home › articles › blog › numerical differentiation methods in python
Python for Numerical Differentiation: Methods & Tools
January 14, 2021 - We’re going to use the scipy derivative to calculate the first derivative of the function. Please don’t write your own code to calculate the derivative of a function until you know why you need it.
Price   $$$
Address   100 Meadowcreek Drive, Suite 102, 94925, Corte Madera
🌐
SciPy
scipy.github.io › devdocs › reference › differentiate.html
Finite Difference Differentiation (scipy.differentiate) — SciPy v1.18.0.dev Manual
SciPy differentiate provides functions for performing finite difference numerical differentiation of black-box functions.
Top answer
1 of 3
10

FFT returns a complex array that has the same dimensions as the input array. The output array is ordered as follows:

  1. Element 0 contains the zero frequency component, F0.

  2. The array element F1 contains the smallest, nonzero positive frequency, which is equal to 1/(Ni Ti), where Ni is the number of elements and Ti is the sampling interval.

  3. F2 corresponds to a frequency of 2/(Ni Ti).

  4. Negative frequencies are stored in the reverse order of positive frequencies, ranging from the highest to lowest negative frequencies.

  5. For an even number of points, the frequencies corresponding to the returned complex values are: 0, 1/(NiTi), 2/(NiTi), ..., (Ni/2–1)/(NiTi), 1/(2Ti), –(Ni/2–1)/(NiTi), ..., –1/(NiTi) where 1/(2Ti) is the Nyquist critical frequency.

  6. For an odd number of points, the frequencies corresponding to the returned complex values are: 0, 1/(NiTi), 2/(NiTi), ..., (Ni–1)/2)/(NiTi), –(Ni–1)/2)/(NiTi), ..., –1/(NiTi)

Using this information we can construct the proper vector of frequencies that should be used for calculating the derivative. Below is a piece of self-explanatory Python code that does it all correctly. Note that the factor 2N cancels out due to normalization of FFT.

from scipy.fftpack import fft, ifft, dct, idct, dst, idst, fftshift, fftfreq
from numpy import linspace, zeros, array, pi, sin, cos, exp, arange
import matplotlib.pyplot as plt


N = 100
x = 2*pi*arange(0,N,1)/N #-open-periodic domain                                                   

dx = x[1]-x[0]
y = sin(2*x)+cos(5*x)
dydx = 2*cos(2*x)-5*sin(5*x)


k2=zeros(N)

if ((N%2)==0):
    #-even number                                                                                   
    for i in range(1,N//2):
        k2[i]=i
        k2[N-i]=-i
else:
    #-odd number                                                                                    
    for i in range(1,(N-1)//2):
        k2[i]=i
        k2[N-i]=-i

dydx1 = ifft(1j*k2*fft(y))

plt.plot(x,dydx,'b',label='Exact value')
plt.plot(x,dydx1, color='r', linestyle='--', label='Derivative by FFT')
plt.legend()
plt.show()

2 of 3
9

Maxim Umansky’s answer describes the storage convention of the FFT frequency components in detail, but doesn’t necessarily explain why the original code didn’t work. There are three main problems in the code:

  1. x = linspace(0,2*pi,N): By constructing your spatial domain like this, your x values will range from to , inclusive! This is a problem because your function y = sin(2*x)+cos(5*x) is not exactly periodic on this domain ( and correspond to the same point, but they’re included twice). This causes spectral leakage and thus a small deviation in the result. You can avoid this by using x = linspace(0,2*pi,N, endpoint=False) (or x = 2*pi*arange(0,N,1)/N, as Maxim Umansky did; this is what he is referring to with “open-periodic domain”).
  2. k = fftshift(k): As Maxim Umansky explained, your k values need to be in a specific order to match the FFT convention. fftshift sorts the values (from small/negative to large/positive), which can be useful e. g. for plotting, but is incorrect for computations.
  3. dydx1 = ifft(-k*1j*fft(y)).real: scipy defines the FFT as y(j) = (x * exp(-2*pi*sqrt(-1)*j*np.arange(n)/n)).sum(), i. e. with a factor of in the exponential, so you need to include this factor when deriving the formula for the derivative. Also, for scipy’s FFT convention, the k values shouldn’t get a minus sign.

So, with these three changes, the original code can be corrected as follows:

from scipy.fftpack import fft, ifft, dct, idct, dst, idst, fftshift, fftfreq
from numpy import linspace, zeros, array, pi, sin, cos, exp
import matplotlib.pyplot as plt

N = 100
x = linspace(0,2*pi,N, endpoint=False) # (1.)

dx = x[1]-x[0]
y = sin(2*x)+cos(5*x)
dydx = 2*cos(2*x)-5*sin(5*x)

k = fftfreq(N,dx)
# (2.)

dydx1 = ifft(2*pi*k*1j*fft(y)).real # (3.)

plt.plot(x,dydx,'b',label='Exact value')
plt.plot(x,dydx1,'r',label='Derivative by FFT')
plt.legend()
plt.show()
🌐
Reddit
reddit.com › r/learnpython › help with scipy derivatives
r/learnpython on Reddit: Help with scipy derivatives
February 3, 2021 -

from scipy.misc import derivative as der

import sympy as sy

def f(x):

......return sy.sin(x)

a = der(f, 1)

print(a)

I really don't understand why this isn't working properly. I'm trying to derive sin(x) (as a simple test) at a certain point, but it gives me the wrong result (0.454648713412841 instead of 0.5403023....). In the line "a = der(f, 1)", it means that I'm looking for the derivative of the function f, at point 1.

why is this not working?

🌐
GitHub
github.com › pvlib › pvlib-python › issues › 1644
scipy.misc.derivative is deprecated · Issue #1644 · pvlib/pvlib-python
January 24, 2023 - scipy v1.10.0 (released Jan 3, 2023) has deprecated scipy.misc.derivative, a function used by pvlib.ivtools.sdm.pvsyst_temperature_coeff. The deprecation notice mentions some alternatives (although I'm not confident a new dependency is w...
Author   kandersolar
🌐
YouTube
youtube.com › engineering educator academy
Numerical Differentiation and Integration Using Scipy - YouTube
Using Scipy for numerical differentiation and integration is explained in this video.
Published   March 15, 2023
Views   100
🌐
Reddit
reddit.com › r/physics › how to take derivatives in python: 3 different types of scenarios
r/Physics on Reddit: How To Take Derivatives In Python: 3 Different Types of Scenarios
August 9, 2021 - For example. f(x) = "solve an ode ... derivatives can't be computed symbolically, but one can use scipy's derivative method to get a good estimate of df/dx at certain values of x....
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.polyfit.html
numpy.polyfit — NumPy v2.4 Manual
scipy.interpolate.UnivariateSpline · Computes spline fits. Notes · The solution minimizes the squared error · \[E = \sum_{j=0}^k |p(x_j) - y_j|^2\] in the equations: x[0]**n * p[0] + ... + x[0] * p[n-1] + p[n] = y[0] x[1]**n * p[0] + ... + x[1] * p[n-1] + p[n] = y[1] ...
🌐
Sage Q&A Forum
ask.sagemath.org › question › 9272 › problem-with-numerical-integration-and-differentiation-with-scipy
problem with numerical integration and differentiation with scipy - ASKSAGE: Sage Q&A Forum
August 28, 2012 - import scipy as sp from scipy import integrate, derivative I2=integrate.quad( sp.derivative(f(y),y, dx=0.00001, n=1, order=7) , 0, pi,)[0]; show(I2) show( integral(diff(f(y),y),y,0,1).n() )
Top answer
1 of 2
3

As pointed out by @SevC_10 in his answer, you are missing dx parameter.

I like to show case the use of sympy for derivation operations, I find it much easier in many cases.

Copyimport sympy
import numpy as np

x = sympy.Symbol('x')

f = sympy.exp(x) # my function e^x
df = f.diff() # y' of the function = e^x

f_lambda = sympy.lambdify(x, f, 'numpy')
df_lambda = sympy.lambdify(x, yprime, 'numpy') # use lambdify

print(f_lambda(np.ones(5)))

# array([2.71828183, 2.71828183, 2.71828183, 2.71828183, 2.71828183])

print(df_lambda(np.ones(5)))

# array([2.71828183, 2.71828183, 2.71828183, 2.71828183, 2.71828183])

print(f_lambda(np.zeros(5)))

# array([1., 1., 1., 1., 1.])

print(df_lambda(np.zeros(5)))

# array([1., 1., 1., 1., 1.])


print(f_lambda(np.array([0, 1, 2, 3, 4])))
# array([ 1.        ,  2.71828183,  7.3890561 , 20.08553692, 54.59815003])

print(df_lambda(np.array([0, 1, 2, 3, 4])))
# array([ 1.        ,  2.71828183,  7.3890561 , 20.08553692, 54.59815003])
2 of 2
3

The derivative function has other arguments. From the help(derivative):

CopyParameters
----------
func : function
    Input function.
x0 : float
    The point at which the nth derivative is found.
dx : float, optional
    Spacing.
n : int, optional
    Order of the derivative. Default is 1.
args : tuple, optional
    Arguments
order : int, optional
    Number of points to use, must be odd.

As you can see, you didn't specify the dx parameter, so this can cause rounding error because the approximate derivative is computed on a larger interval. From the documentation, the default value is 1 (https://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.derivative.html).

Simply try to reduce the spacing interval: for example, using 1e-3 I get:

Copy2.718281828459045
2.718282281505724