简体   繁体   中英

How to define maximum of Intermediate and another value in Python Gekko, when using sequential solver?

In a modeling framework for solving systems of differential equations with GEKKO that I am writing I want to calculate the maximum of a parameter (an external forcing) and an integer value (eg 0) and use the result in the model equations.

The crucial problem is that for passing the parameter through vectorized functions, the parameter currently is wrapped as an Intermediate equation. This is why a vectorized maximum function, such as built-in max and np.maximum return TypeError: object of type 'int' has no len()

I want to use a sequential solver (eg IMODE == 4) so the GEKKO max2 and max3 functions also do not work, as shown below.

Essentially the use case boils down to this minimal example:

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt  

m = GEKKO()
m.time = np.arange(0,20)

y = m.Var(value=5)
forcing = m.Intermediate(m.Param(value=np.arange(-5,15)))

@np.vectorize
def value_above_zero(var):
    return m.max2(var, 0)

forcing_above_0 = value_above_zero(forcing)

m.Equation(y.dt()==-forcing_above_0*y)
m.options.IMODE=4
m.solve(disp=False)

which gives this error when trying to solve:

Exception:  @error: Degrees of Freedom
 * Error: DOF must be zero for this mode
 STOPPING...

Is there some way to define the max of an intermediate equation and some other value using GEKKO, when using a sequential solver? Or is there perhaps another way to wrap the parameter so that np.vectorize does not unpack the time-discretized values of the forcing (ie the array in the gekko parameter)?

Any help is very much appreciated!

IMODE=6 gives a good solution for this problem. It is still a simulation but allows the additional degrees of freedom. IMODE=4 checks that the number of equations and variables are equal. Both the m.max2() and m.max3() use additional degrees of freedom to solve the problem as shown here .

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt  

m = GEKKO()
m.time = np.arange(0,20)

y = m.Var(value=5)
forcing = m.Intermediate(m.Param(value=np.arange(-5,15)))

@np.vectorize
def value_above_zero(var):
    return m.max2(var, 0)

forcing_above_0 = value_above_zero(forcing)

m.Equation(y.dt()==-forcing_above_0*y)
m.options.IMODE=6
m.solve(disp=False)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM