Hello I have the aim to optimize a currently simple set of equations in order to obtain the value of kd
with a fit.
Generate testing data (works fine)
def solve_gekko_equations(H0input, D0input, Kinput):
m = GEKKO(remote=False)
d0 = m.Const(D0input)
h0 = m.Const(H0input)
hdLimit=min([D0input,H0input])
d = m.Var(1,0,D0input)
h = m.Var(1,0,H0input)
hd = m.Var(1,0,hdLimit)
kd = m.Const(Kinput)
m.Equations([h + hd == h0, d + hd == d0, kd == h * d / hd])
m.solve(disp=False)
return d.value[0], h.value[0], hd.value[0]
H0values= np.linspace(0, 12, 100)
solve_gekko_equations_vec = np.vectorize(solve_gekko_equations)
dvalues, hvalues, hdvalues = solve_gekko_equations_vec(H0values, 2, 0.5)
Optimize kd
from gekko import GEKKO
m = GEKKO(remote=False)
kd = m.FV(value=1)
kd.STATUS = 1
d0 = m.Const(2)
hdmeas = m.Param(value=hdvalues)
h0 = m.Param(value=H0values)
d = m.Var(1,0,2)
h = m.Var(1,0)
hd = m.Var(1,0)
m.Equation(h + hd == h0)
m.Equation(d + hd == d0)
# Objective
m.Obj(h * d / hd)
m.Minimize(((hd-hdmeas)/hdmeas)**2)
# Solve
m.solve(disp=False)
m.options.IMODE = 2
# Final objective
print('Final Objective: '+ str(m.options.objfcnval))
# Print solution
print('Solution')
print('kd: ' + str(kd.value))
I constantly receive this error: EXIT: Invalid number in NLP function or derivative detected. Please help.
Thank you very much for your answer, and now the optimization finishes, but the result is wrong. we generated testing data for kd=0.5 but the fitting result is kd=1.0 in the suggested solution. It seemed that any initalValue in mFV(value=initialValue) was in the end the found solution.
So I modified the code to only provide one minimize function:
from gekko import GEKKO
H0values= np.linspace(0, 12, 100)
dvalues, hvalues, hdvalues = solve_gekko_equations_vec(H0values, 2, 0.5)
print(len(hdvalues))
print(len(H0values))
print('optimize kd')
m = GEKKO(remote=False)
kd = m.FV(value=2)
kd.STATUS = 1
d0 = 2
hdmeas = m.Param(value=hdvalues)
h0 = m.Param(value=H0values)
d = m.Var(1,lb=0,ub=2)
h = m.Var(1,lb=0)
hd = m.Var(1,lb=0)
m.Equation(h + hd == h0)
m.Equation(d + hd == d0)
m.Equation(kd == (h * d)/hd)
# Objective
m.Minimize(((hd-hdmeas)/(hdmeas+0.001))**2)
# Solve
m.options.IMODE = 2
m.solve(disp=True)
# Final objective
print('Final Objective: '+ str(m.options.objfcnval))
# Print solution
print('Solution')
print('kd: ' + str(kd.value[0]))
The solve_gekko_equations_vec is the same as in my initial question. Now the result is correct but it strongly depends on the range of the numbers. This was just an example; the final ranges will be around 110-9 - 110-6; if I use the current code and make a range with np.linspace(0, 0.00012, 100) it already does not find a solution; is there maybe a more robust minimization approach or other suggestions?
Thank you very much, I really appriciate your help! Stephan