Search code examples
pythongekko

Gekko Optimization EXIT: Invalid number in NLP function or derivative detected


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.


Solution

  • 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