Search code examples
pythonperformancescipyscientific-computing

Slow performance using scipy.interpolate inside loop


I am using Python to generate input data for engineering simulations. I need to define how a certain physical quantity (let's call it force) varies with time.

The force depends on a known time-varying quantity (let's call it angle). The dependency between force and angle is different for each time step. The force-angle dependency for each time step is defined as data points, not as a function. For each time step I need to interpolate the value for force from the force-angle dependency of that time step. I am using scipy.interpolate.interp1d inside a list comprehension.

However, I am unhappy with the performance. The interpolation loop takes almost 20 seconds, which is unacceptably slow. The number of time steps is approximately 250k. The number of data points in a force-angle dependency is approximately 2k. I tried using a for loop instead, but this was even slower.

How can I improve performance? The execution time needs to be less than a second, if possible. The code here does not contain the actual data I'm using, but is similar enough.

import numpy as np
import random
from scipy.interpolate import interp1d
import time

nTimeSteps = 250000
nPoints_forceAngleDependency = 2000

# Generating an example (bogus data)
angle = np.linspace(0., 2*np.pi, nPoints_forceAngleDependency)
forceAngleDependency_forEachTimeStep = [random.random() * np.sin(angle) for i in range(nTimeSteps)]
angleHistory = [random.random() * 2 * np.pi for i in range(nTimeSteps)]

# Interpolation
start = time.time()
forceHistory = [interp1d(angle, forceAngleDependency_forEachTimeStep[i])(angleHistory[i]) \
    for i in range(nTimeSteps)]
end = time.time()
print 'interpolation duration: %s s' % (end - start)

Solution

    1. Use np.random.random(size=nTineSteps) to generate samples

    2. For linear interpolation, use numpy.interp instead of interp1d. For higher order spline interpolation use either CubicSpline or make_interp_spline, and use vectorized evaluation.