Search code examples
mathematical-optimizationgekko

GEKKO fails to solve simple model - why?


I have formulated a very simple model, but GEKKO fails to solve it (with standard settings and MAX_ITER = 100000). I'm trying to understand why GEKKO struggles in this case. This is the model:

from gekko import GEKKO

m = GEKKO()
x = m.Var(value=15.0, lb=10.0, ub=20.0, name="x")
y = m.Intermediate(-5.0, name="y")
z = m.Intermediate(y, name="z")
r = m.Intermediate(200000.0 * z ** 0.5, name="r")
obj_expr = r - x
m.Maximize(obj_expr)
m.options.MAX_ITER = 10000
m.solve()

EXIT: Invalid number in NLP function or derivative detected.
An error occured.
The error code is          -13 
Exception:  @error: Solution Not Found

The optimal solution is obvious: Since y = -5, z = -5. Hence, r = 200000.0 * -5 ** 0.5 = -447213.59549995797. The objective is to maximize r - x. r cannot be changed. Therefore, x should be set to the lower bound.

What is the problem here?


Solution

  • The value of z is -5 so -5**0.5 is 2.236i, but the solvers don't implicitly handle complex numbers. One way to protect against negative values is to make z a variable and set a lower bound such as:

    z = m.Var(lb=1e-5)
    m.Equation(z==y)
    

    However, this would lead to an infeasible solution if y=-5. Another way is to create the intermediate variable so that negative numbers aren't a problem:

    r = m.Intermediate(200000.0 * (z**2) ** 0.25, name="r")
    

    This protects against negative numbers. Here is a complete script that solves successfully:

    from gekko import GEKKO
    
    m = GEKKO()
    x = m.Var(value=15.0, lb=10.0, ub=20.0, name="x")
    y = m.Intermediate(-5.0, name="y")
    z = m.Intermediate(y, name="z")
    r = m.Intermediate(200000.0 * (z**2) ** 0.25, name="r")
    obj_expr = r - x
    m.Maximize(obj_expr)
    m.options.MAX_ITER = 10000
    m.solve()
    

    Here is a way to handle complex numbers, if needed: Is it possible to use GEKKO for curve fitting if complex numbers can appear in intermediate steps?