I am doing many thousands of repetitive interpolations within an optimization algorithm in Python. I have written a function to interpolate a single value fairly efficiently. I would like to extend this to allow for 1D array inputs, as this may help speed up the computations avoiding for loops in my optimizer.
Sample code:
import numpy as np
from numba import njit
#Universal Interpolation function
@njit
def calc(x0, x, y):
if x0 < x[0]:
return y[0]
elif x0 > x[-1]:
return y[-1]
else:
for i in range(len(x) - 1):
if x[i] <= x0 <= x[i + 1]:
x1, x2 = x[i], x[i + 1]
y1, y2 = y[i], y[i + 1]
return y1 + (y2 - y1) / (x2 - x1) * (x0 - x1)
WeirCurve=np.array([[749.81, 0], [749.9, 5], [750, 14.2], [751, 226], [752, 556], [753, 923.2], [754, 1155.3]])
def WeirDischCurve(x):
x = np.asarray(x)
result = calc(x, WeirCurve[:, 0], WeirCurve[:, 1])
return result
The function works for single value inputs:
WeirDischCurve(751.65)
Out[10]: 440.4999999999925
but fails with a vector/1D array input.
WeirDischCurve([751.65, 752.5, 753.3])
Any suggestions on how to do this as efficiently as possible? Scipy.interpolate features are too slow for my needs. Any suggestions would be appreciated (Note - I tried Creating a polynomial to do this but it seems to introduce a lot of error for some of the required interpolations)
I changed the function WeirDischCurve to accept a list of values and return the results as a list
def WeirDischCurve(x):
result = []
for value in x:
result.append(calc(value, WeirCurve[:, 0], WeirCurve[:, 1]))
return result
Passing a list to the functionWeirDischCurve([751.65, 752.5, 753.3])
And it returns a list with the results
[440.4999999999925, 739.6, 992.8299999999895]