Brian,
The only thing you need to do is replace np.exp with m.exp. You have to use gekko functions so that gradients can be computed and passed to the solver.
from gekko import GEKKO
import numpy as np
m = GEKKO()
m.options.SOLVER=1
Variables = ['x1','x2','x3','x4']
# intiliaze GEKKO variables for NLP
Variable_Dict = {j : m.Var(value=1,lb=1,ub=5,integer=True) for j in Variables}
# per GEKKO documentation, if multiple objectives are given, they are summed
for i in Variables:
test=m.exp(Variable_Dict[i])
m.Obj(test)
m.solve()
If there are functions that are not currently supported in GEKKO then I recommend one of three options:
1. Request that the function be added as a feature request in Github. https://github.com/BYU-PRISM/GEKKO
2. Use a cspline (1D) or bspline (2D) to approximate the function CDF. See https://apmonitor.com/wiki/index.php/Main/GekkoPythonOptimization (Problem #4) for an example of a cspline.
3. Switch to a package such as Scipy.optimize.minimize that allows you to use Numpy or Scipy functions. Here are tutorials on both: http://apmonitor.com/che263/index.php/Main/PythonOptimization (See methods #2 and #3).
Best regards,
John Hedengren
--
--
APMonitor user's group e-mail list.
- To post a message, send email to apmo...@googlegroups.com
- To unsubscribe, send email to
apmonitor+...@googlegroups.com
- Visit this group at http://groups.google.com/group/apmonitor
---
You received this message because you are subscribed to the Google Groups "apmonitor" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
apmonitor+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To post to this group, send email to apmo...@googlegroups.com.
Visit this group at https://groups.google.com/group/apmonitor.
For more options, visit https://groups.google.com/d/optout.
Brian,
When I run your model with the local executable (apm.exe from https://github.com/APMonitor/apm_server/tree/master/apm_windows/online), I get the following for your case that originally failed:
C:\Users\johnh\Desktop\gk_model4>apm gk_model4.apm
----------------------------------------------------------------
APMonitor, Version 0.8.3
APMonitor Optimization Suite
----------------------------------------------------------------
--------- APM Model Size ------------
Each time step contains
Objects : 0
Constants : 0
Variables : 33194
Intermediates: 0
Connections : 0
Equations : 33194
Residuals : 33194
My guess is that GEKKO is loading the large model file to the server (35 MB) and it is not able to even start loading the Equations section by the time the connection times out. Here are two suggestions:
· If your model is scaling up with the number of data points, you should consider using IMODE = 2 instead. This way you only define one set of model equations and objective function and then the computational engine multiplies your model for you for each of the data sets. Your model will be very small but it is still very efficient for large amounts of data. Here is an example of IMODE = 2 for regression:
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
# measurements
xm = np.array([0,1,2,3,4,5])
ym = np.array([0.1,0.2,0.3,0.5,0.8,2.0])
# GEKKO model
m = GEKKO()
# parameters
x = m.Param(value=xm)
a = m.FV()
a.STATUS=1
# variables
y = m.CV(value=ym)
y.FSTATUS=1
# regression equation
m.Equation(y==0.1*m.exp(a*x))
# regression mode
m.options.IMODE = 2
# optimize
m.solve(disp=False)
# print parameters
print('Optimized, a = ' + str(a.value[0]))
plt.plot(xm,ym,'bo')
plt.plot(xm,y.value,'r-')
plt.show()
· The other suggestion is to use the option remote=False so that you don’t need to send the problem to a remote server and where you run into server issues such as a timeout for large files. I’d recommend that you try the first suggestion initially and then use this suggestion if it is not possible.
-John Hedengren
Brian,
You were naming one of your variables starting with a reserved keyword (cos()) and it was looking for the opening of the cosine operator. The original error message had a very long string with spaces that wrapped around onto multiple lines:
Position: 433
((((((v1-1))*(forecast))-(short-(((((((((((v1-1))*(forecast)))/(sd)))*((1-((exp((((-(((((((v1-1))*(forecast)))/(sd)))^(2))))/(2))))/(((0.5569620253164557+((1.6)*((((((v1-1))*(forecast)))/(sd)))))+((0.8333333333333334)*(sqrt(((((((((v1-1))*(forecast)))/(sd)))^(2))+3))))))))))+((0.3989422804014327)*(exp((((((-(((((v1-1))*(forecast)))/(sd))))*((((((v1-1))*(forecast)))/(sd)))))/(2))))))-(((((v1-1))*(forecast)))/(sd))))*(sd)))))*(cost))
?
If we break up the long expression into multiple smaller expressions with Intermediates then it is easier to see:
def Expected_Short(Factor,SD,Forecast):
part1 = m.Intermediate(Service_Factor(Factor, SD, Forecast)*CDF(Service_Factor(Factor, SD, Forecast)))
part2 = m.Intermediate(PDF(Service_Factor(Factor, SD, Forecast)))
part3 = m.Intermediate(Service_Factor(Factor, SD, Forecast))
return (part1 + part2 - part3) * SD
The new error points to the “cost” variable that starts with “cos”.
@error: Model Expression
*** Error in syntax of function string: Missing opening parenthesis
Position: 62
((((((v1-1))*(forecast))-(short-((((i3+i4)-i5))*(sd)))))*(cost))
?
If you don’t name your variables then it isn’t a problem. When you use names, please check your “names” for starting with reserved keywords: http://apmonitor.com/wiki/index.php/Main/Equations Perhaps we should automatically pre-pend the names in GEKKO with something like “_cost” to avoid that.
|
abs() |
Absolute value |
abs(x*y)=0 |
|
exp() |
Exponentiation |
exp(x*y)=0 |
|
log10 |
Base-10 Log |
log10(x*y)=0 |
|
log |
Natural Log |
log(x*y)=0 |
|
sqrt() |
Square Root |
sqrt(x*y)=0 |
|
sinh() |
Hyperbolic Sine |
sinh(x*y)=0 |
|
cosh() |
Hyperbolic Cosine |
cosh(x*y)=0 |
|
tanh() |
Hyperbolic Tangent |
tanh(x*y)=0 |
|
sin() |
Sine |
sin(x*y)=0 |
|
cos() |
Cosine |
cos(x*y)=0 |
|
tan() |
Tangent |
tan(x*y)=0 |
|
asin() |
Arc-sine |
asin(x*y)=0 |
|
acos() |
Arc-cos |
acos(x*y)=0 |
|
atan() |
Arc-tangent |
atan(x*y)=0 |
|
erf() |
Error function |
erf(x*y)=0 |
|
erfc() |
Complementary error function |
erfc(x*y)=0 |
If you start your names with one of these, it will trigger an error that it cannot find an opening parenthesis.
Best regards,
from gekko import GEKKOimport numpy as np
m = GEKKO(remote=False)m.options.SOLVER = 3m.options.IMODE = 2xm = np.array([1,1,1,1,1,1])ym = np.array([2,2,2,2,2,2])x = m.Var(value=xm,lb=1,ub=5,integer=False)y = m.Param(value=ym)m.Obj(x*y)test = [m.Intermediate(x[i]) for i in range(len(xm))]m.Equation(sum(test) <= 7)# Solvem.solve(disp=True)for i in x:print(i)
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
m.options.SOLVER = 3
m.options.IMODE = 2
xm = np.array([1,1,1,1,1,1])
ym = np.array([2,2,2,2,2,2])
# define x[0], x[1], x[2]
x = [m.Var(value=xm,lb=i+1,ub=5,integer=False) for i in range(3)]
y = m.Param(value=ym)
# define parameter that is the same across all data points
k = m.FV(lb=2,ub=4)
k.STATUS = 1
m.Obj(-k*sum(x)*y)
test = [m.Intermediate(x[i]) for i in range(3)]
m.Equation(sum(test) <= 7)
# Solve
m.solve(disp=True)
for i in x:
print(i.value)
print('k: ' + str(k.value[0]))
If you do need to solve across the data dimension, I recommend that you use a dynamic mode such as IMODE = 6 and integrate the variable. Let me know if you need this and I can show you an example, similar to this one: https://apmonitor.com/do/index.php/Main/IntegralObjective You wouldn't have a differential equation but this would allow you to integrate the across the data dimension.
Best regards,
John Hedengren
Brian,
You are correct - it won't work with IMODE=2. I think you could do this with IMODE=6 by integrating a parameter such as #11 here:
https://apmonitor.com/wiki/index.php/Main/GekkoPythonOptimization There is also an example of connections with specific a data horizon point in #12.
Best regards,
John Hedengren