Home > Mobile >  Pyomo, TypeError: 'numpy.ndarray' object is not callable
Pyomo, TypeError: 'numpy.ndarray' object is not callable

Time:10-14

I am trying to use scipy commands in Pyomo, an optimizer based in Python.

My goal is to develop an optimal trajectory for aircraft in the presence of a wind field. I have data measurements at grid points. I have used scipy to generate the interpolation as

xi, yi = np.linspace(X2.astype('float').min(), X2.astype('float').max(), 100), np.linspace(Y2.astype('float').min(), Y2.astype('float').max(), 100)
xi, yi = np.meshgrid(xi, yi)

# Interpolate
rbfX = sp.interpolate.Rbf(X2, Y2, Wx2, function='multiquadric')
zXi = rbfX(xi, yi)

being sp how I call scipy. This is the way I have to calculate the speed of wind at any point. I am interpolating the windspeed.

Then, inside of the pyomo part, I write

def Wind_lammda_definition1(model, i):
    return m.Wind_lammda[i,1] ==zXi(m.lammda[i,1], m.phi[i,1])
m.Wind_lammda_const1 = Constraint(m.N, rule = Wind_lammda_definition1)

being m.lammda and m.phi the position of the airplane.

Unfortunately, once I run the code, I get rhe following error:

    return m.Wind_lammda[i,1] ==zXi(m.lammda[i,1], m.phi[i,1])

TypeError: 'numpy.ndarray' object is not callable

I have checked this and this threads and as far as I see, this is an error message which appears if there are syntax errors. However, I haven't found any and I think that this happens becasue I cannot port scipy into Pyomo. Is this true or can it be fixed?

CodePudding user response:

Let's setup a Rbf object:

In [177]: X,Y = np.meshgrid(np.arange(4),np.arange(4))
In [178]: Z = np.sin(X-Y)
In [179]: fn = interpolate.Rbf(X,Y,Z)
In [180]: type(fn)
Out[180]: scipy.interpolate.rbf.Rbf

That's like your rbfX. According to the docs it is callable, that is it has a __call__ method.

If we call it with 2 scalars, we get a single element array:

In [181]: fn(1.5, 2.3)
Out[181]: array(-0.73094599)

Call it with a pair of arrays, we get an array with matching size:

In [184]: fn(np.arange(1,3,.5), np.arange(0,2,.5))
Out[184]: array([0.84147098, 0.85639014, 0.84147098, 0.85639014])

This is what your zXi. Look at its type, shape, and dtype. It's an array. It cannot be "called", and there are specific rules as to how it can be indexed.

zXi(m.lammda[i,1], m.phi[i,1]) is wrong because it tries to "call" a numpy array. But zXi[m.lammda[i,1], m.phi[i,1]] apparently has invalid indices, quite possibly floats. I haven't examined what they are.

rbfX(m.lammda[i,1], m.phi[i,1]) might work if the 2 arguments are meant to be interpolation points.

zXi = rbfX(xi, yi) creates an array (probably 2d (100,100)) that contains values interpolated at the xi,yi mesh. You can pick an element, e.g zXi[50,50] or array of values. But you can't treat it like the interpolation function, giving it float values.

  • Related