I need to optimize this function in gekko and something is wrong. Black function(x2) is how teoretical it should look like.
m = GEKKO()
m.options.IMODE = 6
m.time = np.linspace(0, 1, 100)
x = m.Var(lb=1, ub=3)
x2 = m.Var(lb=1, ub=3)
J = m.Var(0)
t = m.Param(value=m.time)
m.Equation(J.dt() == 24*x*t + 2*x.dt()**2 -4*t)
m.Equation(x2==t**3 + t + 1)
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf, J, pos2 = 'end')
m.Obj(Jf)
m.solve()
plt.plot(m.time, x.value)
plt.plot(m.time, x2.value, color='black')
plt.show()
Here is a solution to the problem that aligns with the known solution:
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO(remote=True)
n = 101
m.time = np.linspace(0,1,n)
x = m.Var(1,lb=1,ub=3)
t = m.Param(value=m.time)
p = np.zeros(n); p[-1]=1
final = m.Param(p)
m.Equation(final*(x-3)==0)
m.Minimize(final*m.integral(24*x*t + 2*x.dt()**2 -4*t))
m.options.IMODE = 6
m.options.SOLVER = 3
m.options.NODES = 2
m.solve()
plt.plot(m.time, x.value,'b-',label='x gekko')
tm = m.time
plt.plot(tm,tm**3+t+1,'r--',label='x solution')
plt.legend(); plt.xlabel('time'); plt.ylabel('x')
plt.grid(); plt.show()
The variable x
has an initial value 1 and bounds between 1 and 3. The parameter final
is a numpy array with all zeros except for the last element set to one. This setup is used to define a constraint in the model that only applies at the final time point, ensuring x
equals 3 at the final time. Don't use m.fix_final(x,3)
because it also sets the derivative of x
to zero at the final point. The objective function m.Minimize()
contains an m.integral()
expression that depends on x
, t
, and the derivative of x
with respect to time. It is also multiplied by final
so that only the final integral value is used to define the objective function.