Search code examples
pythongekko

What is causing this Gekko syntax error: Error in syntax of function string: Missing opening parenthesis?


I am using a function to create a dictionary containing gekko variables. Please can someone tell me what is causing the syntax error?

Here is the code I am running:

from gekko import GEKKO
m = GEKKO(remote = False)
def tank(tank_id, area, gm): #gm = gekko model
    tank_dict = {}
    tank_dict['id'] = tank_id
    tank_dict['area'] = gm.Param(value = area, name = tank_id + '_area')
    tank_dict['volume'] = gm.FV(value = 10, name = tank_id + '_volume')
    tank_dict['height'] = gm.Var(name = tank_id + '_height')
    
    gm.Equation(tank_dict['height'] == tank_dict['volume']/tank_dict['area'])
    
    return(tank_dict)

tank_1 = tank('tank_1', area = 5, gm = m)
m.solve(disp = True)

This is the error message I get:

 ----------------------------------------------------------------
 APMonitor, Version 1.0.0
 APMonitor Optimization Suite
 ----------------------------------------------------------------
 
 
 --------- APM Model Size ------------
 Each time step contains
   Objects      :  0
   Constants    :  0
   Variables    :  3
   Intermediates:  0
   Connections  :  0
   Equations    :  1
   Residuals    :  1
 
 @error: Model Expression
 *** Error in syntax of function string: Missing opening parenthesis

Position: 4                   
 tank_1_height-(((tank_1_volume)/(tank_1_area)))
    ?

I'm expecting the 'height' key in the tank_1 dictionary to contain a value of 2.


Solution

  • There are reserved keywords for naming variables in gekko because of how the underlying APMonitor model is written and compiled to byte-code. Those keywords include the tan() function that is used in the name tank in the variable definition. Naming the variables is optional, but does help if you need to read the gk0_model.apm file in the run directory m._path. Prepending something like x_ to the variable names overcomes this error.

    tank_1 = tank('x_tank_1', area = 5, gm = m)
    

    Here is the full script.

    from gekko import GEKKO
    m = GEKKO(remote = False)
    def tank(tank_id, area, gm): #gm = gekko model
        tank_dict = {}
        tank_dict['id'] = tank_id
        tank_dict['area'] = gm.Param(value = area, name = tank_id + '_area')
        tank_dict['volume'] = gm.FV(value = 10, name = tank_id + '_volume')
        tank_dict['height'] = gm.Var(name = tank_id + '_height')
        
        gm.Equation(tank_dict['height'] == tank_dict['volume']/tank_dict['area'])
        
        return(tank_dict)
    
    tank_1 = tank('x_tank_1', area = 5, gm = m)
    m.solve(disp = False)
    
    print('Height: ', tank_1['height'].value[0])
    

    Alternatively, just let gekko handle the internal variable naming:

    from gekko import GEKKO
    m = GEKKO(remote = False)
    def tank(tank_id, area, gm):
        tank_dict = {}
        tank_dict['id'] = tank_id
        tank_dict['area'] = gm.Param(value = area)
        tank_dict['volume'] = gm.FV(value = 10)
        tank_dict['height'] = gm.Var()
        
        gm.Equation(tank_dict['height'] == tank_dict['volume']/tank_dict['area'])
        
        return(tank_dict)
    
    tank_1 = tank('tank_1', area = 5, gm = m)
    m.solve(disp = False)
    
    print('Height: ', tank_1['height'].value[0])
    

    Here is a list of other reserved keywords in gekko for naming variables:

    abs(x) absolute value |x|
    abs2(x) absolute value with MPCC
    abs3(x) absolute value with binary variable for switch
    acos(x) inverse cosine, cos^-1(x)
    acosh(x) inverse hyperbolic cosine, cosh^-1(x)
    Array(type,size) array of GEKKO objects
    arx auto-regressive exogenous input (time series) model
    asin(x) inverse sine, sin^-1(x)
    asinh(x) inverse hyperbolic sine, sinh^-1(x)
    atan(x) inverse tangent, tan^-1(x)
    atanh(x) inverse hyperbolic tangent, tanh^-1(x)
    bspline bspline for 2D data
    cos(x) cosine
    cspline cubic spline for 1D data
    erf(x) error function
    erfc(x) complementary error function
    exp(x) e^x
    if3(cond,x1,x2) switch between x1 (cond<0) and x2 (cond>=0)
    log(x) log_e (x), natural log
    log10(x) log_10 (x), log base 10
    max2(x1,x2) maximum value with MPCC
    max3(x1,x2) maximum value with binary variable for switch
    min2(x1,x2) minimum value with MPCC
    min3(x1,x2) minimum value with binary variable for switch
    periodic periodic (initial=final) for dynamic problems
    pwl piece-wise linear function
    sign2(x) signum operator with MPCC
    sign3(x) signum operator with binary variable for switch
    sin(x) sine
    sinh(x) hyperbolic sine
    sqrt(x) square root
    state_space continuous/discrete and dense/sparse state space
    sum summation of elements in a list or numpy array
    tan(x) tangent
    tanh(x) hyperbolic tangent
    vsum(x) vertical sum of a single variable in the data direction
    

    This list is also found in the APMonitor Documentation.