GEKKO gives TypeError: must be real number, not GK_Operators, I have several approaches that is recommended

Viewed 39

I am trying to solve an NLP with GEKKO, however I have a few problem while implementing the Python code. The model that I am trying to solve is pretty trivial, I am trying to find the optimal point that has minimum loss function value in a 3D convex set.

def calculateLossFunction(h, x, y, lmbd, n):
    sum = 0
    x_star = np.dot(np.transpose(lmbd), x)
    y_star = np.dot(np.transpose(lmbd), y)

    for i in range(n):
        RNJ = math.sqrt((x_star - x[i]) ** 2 + (y_star - y[i]) ** 2)
        P = 1 / (math.degrees(math.atan(h[i] / RNJ)))
        sum += A * P + B
    return sum

This is the objective function for my problem and I am using this as follows

m = GEKKO(remote=True)
eq = m.Param()
H = [500, 1500, 2500]
locations = np.array([[1, 2],
                      [2, 3],
                      [3, 1]])
XN = locations[:, 0]
YN = locations[:, 1]
n = len(locations)

lambdas = m.Array(m.Var,n,lb=0, ub = 1, value = 0)
lambdas[0].value = 1


m.Minimize(calculateLossFunction(H, XN, YN, lambdas, n))
m.Equation(sum(lambdas) == 1)
m.solve(disp=True) # solve on public server
#Results
print('')
print('Results')
print('x1: ' + str(lambdas[0].value))
print('x2: ' + str(lambdas[1].value))
print('x3: ' + str(lambdas[2].value))

The thing is, although I've checked similar problems that are raised in Stack Overflow and tried to mimic the recommended solutions, at this point seems like I cannot figure out what is wrong because above code gives the following error.

Traceback (most recent call last):
    m.Minimize(calculateLossFunction(H, XN, YN, lambdas, n))
  File "C:\Users\admin\PycharmProjects\nonlinear.py", line 13, in calculateLossFunction
    RNJ = math.sqrt((x_star - x[i]) ** 2 + (y_star - y[i]) ** 2)
TypeError: must be real number, not GK_Operators

I've also read the documentation but couldn't find any solution. Thanks in advance for your answers.

1 Answers

Use the gekko functions m.sqrt() and m.atan() instead of math.sqrt() and math.atan(). The TypeError: must be real number, not GK_Operators is from the math function. There is no math.degrees() equivalent in gekko, so use 360.0/(2.0*np.pi) for the conversion. Gekko uses gradient-based optimizers that require overloading of the operators and functions for automatic differentiation to provide exact 1st and 2nd derivatives of constraints and objectives. Some functions are compatible such as np.dot() while others do not return a symbolic solution, such as math.sqrt(). Here is a complete problem that solves successfully:

from gekko import GEKKO
import numpy as np
A = 1.0; B=0.0
def calculateLossFunction(h, x, y, lmbd, n):
    sum = 0
    x_star = np.dot(np.transpose(lmbd), x)
    y_star = np.dot(np.transpose(lmbd), y)

    for i in range(n):
        RNJ = m.sqrt((x_star - x[i]) ** 2 + (y_star - y[i]) ** 2)
        P = 1 / (360.0*(m.atan(h[i] / RNJ)/(2.0*np.pi)))
        sum += A * P + B
    return sum
m = GEKKO(remote=True)
eq = m.Param()
H = [500, 1500, 2500]
locations = np.array([[1, 2],
                      [2, 3],
                      [3, 1]])
XN = locations[:, 0]
YN = locations[:, 1]
n = len(locations)
lambdas = m.Array(m.Var,n,lb=0, ub = 1, value = 0)
lambdas[0].value = 1
m.Minimize(calculateLossFunction(H, XN, YN, lambdas, n))
m.Equation(sum(lambdas) == 1)
m.solve(disp=True) # solve on public server
print('Results')
print('x1: ' + str(lambdas[0].value))
print('x2: ' + str(lambdas[1].value))
print('x3: ' + str(lambdas[2].value))

Solution with sample A=1.0 and B=0.0 values:

Results
x1: [0.99999702144]
x2: [1.9787728836e-06]
x3: [9.9978717975e-07]

and the solver output:

Number of Iterations....: 113

                                   (scaled)                 (unscaled)
Objective...............:   3.3346336759950239e-02    3.3346336759950239e-02
Dual infeasibility......:   8.4348140936638533e-07    8.4348140936638533e-07
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   1.0000010522025397e-11    1.0000010522025397e-11
Overall NLP error.......:   8.4348140936638533e-07    8.4348140936638533e-07


Number of objective function evaluations             = 1237
Number of objective gradient evaluations             = 114
Number of equality constraint evaluations            = 1237
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 114
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 113
Total CPU secs in IPOPT (w/o function evaluations)   =      0.067
Total CPU secs in NLP function evaluations           =      0.034

EXIT: Optimal Solution Found.
 
 The solution was found.
 
 The final value of the objective function is   3.334633675995024E-002
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :   0.131699999998091      sec
 Objective      :   3.334633675995024E-002
 Successful solution
 ---------------------------------------------------

Trigonometric functions sometimes need constraints on the variables to ensure that a NaN value is not returned or to make a solution unique (such as cos(np.pi) and cos(-np.pi).

Related