2

I try to use the scipy.optimze.minimize solver (Nelder-Mead) to optimize my parameters of a GEKKO simulation.

Is this possible at all?

My idea was to hand over the GEKKO object to the solver, but this leads to a error:

TypeError: float() argument must be a string or a number, not 'GEKKO'

But without handing over the object, I couldn“t get the GEKKO solver starting.

Attached is an easy version of the code, doing nothing which makes sense, just for technical understanding, and maybe showing the error I did.

from scipy.optimize import minimize
from numpy.random import rand
from gekko import GEKKO
m = GEKKO()             # create GEKKO model
x = m.Var    # define new variable
y = m.Var    # define new variable

# objective function
def objective(m,v):

    x, y = v
    m.Equations([x + 2 * y == 0, x ** 2 + y ** 2 == 1])  # equations
    m.solve(disp=False)  # solve
    print([x.value[0], y.value[0]])  # print solution

    return x

# define range for input
r_min, r_max = -5.0, 5.0
# define the starting point as a random sample from the domain
pt = r_min + rand(2) * (r_max - r_min)
# perform the search
result = minimize(objective, m, pt, method='nelder-mead')
H Bode
  • 165
  • 7

1 Answers1

0

Here is a solution that mixes Gekko and scipy.optimize.minimize:

from scipy.optimize import minimize
from numpy.random import rand
from gekko import GEKKO
m = GEKKO() # create GEKKO model
x = m.Var() # define new variable
y = m.Var() # define new variable
m.Equations([x + 2 * y == 0, x ** 2 + y ** 2 == 1])  # equations

# objective function
def objective(v):
    x.value = v[0]
    y.value = v[1]
    m.solve(disp=False)  # solve
    print([x.value[0], y.value[0]])  # print solution
    return x.value[0]

# define range for input
r_min, r_max = -5.0, 5.0
# define the starting point as a random sample from the domain
pt = r_min + rand(2) * (r_max - r_min)
# perform the search
result = minimize(objective, pt, method='nelder-mead')

The values need to be transferred into Gekko with x.value=v[0] and y.value=v[1] and exported from Gekko with return x.value[0]. The objective of this problem is to find the root (among the 2) that gives the lowest value of x.

two solutions

Another way to do this with just Gekko is to minimize x:

from scipy.optimize import minimize
from numpy.random import rand
from gekko import GEKKO
m = GEKKO() # create GEKKO model
x = m.Var() # define new variable
y = m.Var() # define new variable
m.Equations([x + 2 * y == 0, \
             x ** 2 + y ** 2 == 1])
m.Minimize(x)
m.solve()
print(x.value[0],y.value[0])

This also produces the correct solution [-0.8944271912,0.4472135956].

John Hedengren
  • 12,068
  • 1
  • 21
  • 25