Search code examples
gekko

Python Gekko - How to use built-in maximum function with sequential solvers?


When solving models sequentially in Python GEKKO (i.e. with IMODE >= 4) fails when using the max2 and max3 functions that come with GEKKO.

This is for use cases, where np.maximum or the standard max function treat a GEKKO parameter like an array, which is not always the intended usage or can create errors when comparing against integers for example.

minimal code example:

from gekko import GEKKO
import numpy as np

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

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

m.Equation(y.dt()== m.max2(forcing,0) * y)
m.options.IMODE=4
m.solve(disp=False)

returns:

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

I know from looking at the code that both max2 and max3 use inequality expressions in the equations, which understandably introduces the degrees of freedoms, so was this functionality never intended? Could there be some workaround to fix this?

Any help would be much appreciated!

Note: I hope this is not a duplicate of How to define maximum of Intermediate and another value in Python Gekko, when using sequential solver?, but instead asking a more concise & different question, about essentially the same issue.


Solution

  • You can get a successful solution by switching to IMODE=6. IMODE=4 (simultaneous simulation) or IMODE=7 sequential simulation requires zero degrees of freedom. Both m.max2() and m.max3() require degrees of freedom and an optimizer to solve.

    from gekko import GEKKO
    import numpy as np
    
    m = GEKKO(remote=False)
    m.time = np.arange(0,20)
    
    y = m.Var(value=5)
    forcing = m.Param(value=np.arange(-5,15))
    
    m.Equation(y.dt()== -m.max2(forcing,0) * y)
    m.options.IMODE=6
    m.solve(disp=True)
    

    The equation y.dt()== -m.max2(forcing,0) * y exponentially increases beyond machine precision so I switched the equation to something that can solve.