Mau - 11 months ago 59

Python Question

I am new using Pyomo, so I apologize in advance if this is a basic question. Well, I am working with kinetic models and my aim is to estimate kinetic parameters. I started with a 'toy model' for understanding better Pyomo before trying my complicated one.

So, my toy model is a simple ODE system of 3 equations:

`dX1/dt = -k1*X1`

dX2/dt = k1*X1 - k2*X2

dX3/dt = k2*X2

My aim is to estimate parameters k1 and k2. I slightly changed the code from this tutorial and is the following:

`from pyomo.environ import *`

from pyomo.dae import *

model = AbstractModel()

model.t = ContinuousSet()

model.MEAS_t = Set(within=model.t)

model.x1_meas = Param(model.MEAS_t)

model.x2_meas = Param(model.MEAS_t)

model.x3_meas = Param(model.MEAS_t)

model.x1 = Var(model.t)

model.x2 = Var(model.t)

model.x3 = Var(model.t)

model.k1 = Var(bounds=(0,3))

model.k2 = Var(bounds=(0,3))

model.x1dot = DerivativeVar(model.x1,wrt=model.t)

model.x2dot = DerivativeVar(model.x2,wrt=model.t)

model.x3dot = DerivativeVar(model.x3,wrt=model.t)

def _x1dot(model,i):

return model.x1dot[i] == -model.k1*model.x1[i]

model.x1dotcon = Constraint(model.t, rule=_x1dot)

def _x2dot(model,i):

return model.x2dot[i] == model.k1*model.x1[i]-model.k2*model.x2[i]

model.x2dotcon = Constraint(model.t, rule=_x2dot)

def _x3dot(model,i):

return model.x3dot[i] == model.k2*model.x2[i]

model.x3dotcon = Constraint(model.t, rule=_x3dot)

def _obj(model):

return sum((model.x1[i]-model.x1_meas[i])**2+(model.x2[i]-model.x2_meas[i])**2+(model.x3[i]-model.x3_meas)**2 for i in model.MEAS_t)

model.obj = Objective(rule=_obj)

model.pprint()

instance = model.create_instance('data2.dat')

instance.t.pprint()

discretizer = TransformationFactory('dae.collocation')

discretizer.apply_to(instance,nfe=8,ncp=5)

solver=SolverFactory('ipopt')

results = solver.solve(instance,tee=True)

instance.k1.pprint()

instance.k2.pprint()

Once I run this code, I got the following message:

`TypeError: Cannot convert object of type 'IndexedParam' (value = x3_meas) to a numeric value.`

However, when I erase all the lines corresponding to x3_meas in my code, as well as the data in my .dat file, it works perfectly.

Does anyone know what is the problem?

My data looks like:

`set t := 0.00 0.66 1.33 2.00 2.66 3.33 4.00 4.66 5.33 6.00 ;`

set MEAS_t := 0.00 0.66 1.33 2.00 2.66 3.33 4.00 4.66 5.33 6.00 ;

param x1_meas :=

0.00 1.000000

0.66 0.263597

1.33 0.069483

2.00 0.018316

2.66 0.004828

3.33 0.001273

4.00 0.000335

4.66 0.000088

5.33 0.000023

6.00 0.000006

;

param x2_meas :=

0.00 0.000000

0.66 0.499640

1.33 0.388227

2.00 0.234039

2.66 0.129311

3.33 0.068803

4.00 0.035960

4.66 0.018630

5.33 0.009609

6.00 0.004945

;

param x3_meas :=

0.00 0.000000

0.66 0.236763

1.33 0.542289

2.00 0.747645

2.66 0.865861

3.33 0.929925

4.00 0.963704

4.66 0.981281

5.33 0.990367

6.00 0.995049

;

Answer Source

After asking for help in Pyomo's google group, I was pointed out that I commited a silly mistake:

In your objective function you forgot to index x3_meas. Your objective function should be:

```
def _obj(model):
return sum((model.x1[i]-model.x1_meas[i])**2+(model.x2[i]-model.x2_meas[i])**2+(model.x3[i]-model.x3_meas[i])**2 for i in model.MEAS_t)
```