1

I have a numpy array of floats which when printed look like this: enter image description here

The red circles are the original values, the blue crosses are a linear interpolation using numpy.interp.

I would like to find the abscissa of the zero crossing of this numpy array (red circle) using scipy.optimize.bisect (for example). Since this is a numpy array (and not a function) I cannot pass it directly to scipy.optimize.bisect. So I was thinking to pass a function that interpolates the numpy array to bisect. Here is the code I am using for the moment:

def Inter_F(x,xp,fp):
    return np.interp(x,xp,fp)
Numpyroot = scp.optimize.bisect(Inter_F,0,9,args=(XNumpy,YNumpy)) 

I find a value that seems correct, Numpyroot = 3.376425289196618.
I am wondering:

  • if this is the correct technical way to use scipy.optimize.bisect on a numpy array? Specially when I am going to do this 10^6 times on different set of numpy values.
  • if enforcing a linear interpolation is not influencing the results that bisect is going to find and if yes, are there better choice?

Here are the two numpy arrays:

XNumpy = array([ 0.   ,  1.125,  2.25 ,  3.375,  4.5  ,  5.625,  6.75 ,  7.875,  9.   ])
YNumpy = array([ -2.70584242e+04,  -2.46925289e+04,  -1.53211676e+04,
        -2.30000000e+01,   1.81312104e+04,   3.41662461e+04,
         4.80466863e+04,   5.75113178e+04,   6.41718009e+04])
user
  • 5,370
  • 8
  • 47
  • 75
gregory
  • 413
  • 4
  • 12

1 Answers1

2

I think what you do is correct. However, there is a more concise way.

import numpy as np
from scipy.interpolate import interp1d


XNumpy = np.array([0., 1.125, 2.25, 3.375, 4.5, 5.625, 6.75, 7.875, 9.])
YNumpy = np.array([
    -2.70584242e+04, -2.46925289e+04, -1.53211676e+04,
    -2.30000000e+01, 1.81312104e+04, 3.41662461e+04,
    4.80466863e+04,   5.75113178e+04,   6.41718009e+04
]) 

invf = interp1d(YNumpy, XNumpy)
print(invf(0))

Result:

array(3.376425289199028)

Here I use scipy.interpolate.interp1d to return a function. Also I interpolate the inverse function so that the abscissa are readily calculated. Of course you can do the same trick with np.interp, I just like scipy.interpolate.interp1d because it returns a function so I can calculate x value from any given y value.

Longwen Ou
  • 859
  • 4
  • 4
  • thanks. It work perfectly. What kind of algorithm is used in scipy.interpolate.interp1d ? – gregory Feb 07 '17 at 21:35
  • @gregory `scipy.interpolate.interp1d` supports various interpolating method. The default is linear, you can also specify higher order spline interpolator via the `kind` argument. You can find more details in the [documentation](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html). – Longwen Ou Feb 07 '17 at 21:54