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.