Gekko if3 works differet for 0 and -0

Viewed 36

I'm trying to use if3 method in gekko but it's working different than in docs:

y = m.if3(condition,x1,x2)
    y = x1 when condition<0
    y = x2 when condition>=0

Please see the example below:

from gekko import GEKKO
m = GEKKO(remote=False)

p = m.Param()
y = m.if3(p,1,0)

for val, expected in [(-1, 1), (0, 0), (1, 0)]:
    p.value = val
    m.solve(disp=False)
    print("P=", p.value, " y=",y.value, " expected=", expected)

print()
m2 = GEKKO(remote=False)

p2 = m2.Param()
y2 = m2.if3(-p2,0,1)

for val, expected in [(-1, 1), (0, 1), (1, 0)]:
    p2.value = val
    m2.solve(disp=False)
    print("P=", p2.value, " y=",y2.value, " expected=", expected)

The output is: (I'm using python3.9, gekko=1.0.4)

P= [-1.0]  y= [1.0]  expected= 1
P= [0.0]  y= [1.0]  expected= 0
P= [1.0]  y= [0.0]  expected= 0

P= [-1.0]  y= [1.0]  expected= 1
P= [0.0]  y= [1.0]  expected= 1
P= [1.0]  y= [0.0]  expected= 0

For the first case, for p=0 the solver should return 0 or am I missing something? In general, how to write in gekko the following if statement:

if val == 0:
    y=constant1
elif val > 0:
    y=constant2

I've found similar question (Gekko Optimization Suite for Python - if3 always <0) but upgrading the gekko version didn't help. Thanks for any answer

1 Answers

Thanks for catching that error in the documentation of if3(). The documentation has been updated to be consistent with the algorithm behavior. At the transition point, the solution may be x1 or x2 for the if3() function. For the if2() function (MPCC form), the solution at the transition point may also be a linear combination of the two values. Gekko computes a numerical solution with a solver tolerance that is 1e-6 by default. Setting the solver tolerance tighter will help to improve the resolution at the transition point.

m.options.RTOL=1e-8
m.options.OTOL=1e-8

The m.if3() transition point can be shifted to avoid the issues with the 0 value. One common strategy is to shift the transition to the left m.if3(x-0.1) or to the right m.if3(x+0.1) by a small amount, especially for mixed integer problems where x=0 has a desired output. For example, the energy usage of a pump may be something like:

energy = 2e-5*voltage**2 + 0.5*voltage + 3.0
pump_energy = m.if3(voltage-0.1,0,energy)

This ensures that the pump reports no energy use when the voltage is below 0.1.

Related