How can I obtain random numbers in gekko? - python

I am trying to solve an optimization problem in Python, using gekko, where one of the variables takes on a random value at each time step, but I haven't been able to use the gekko function that returns random numbers.
Following the documentation page (http://t-t.dk/gekko/docs/user-manual/functions.htm), the function rnorm returns "a random number from a normal distribution with mean and variance provided". I used it as shown here:
x = m.Var(value=0)
m.Equation(x == 5.*m.rnorm(0, 1))
provided that
m = GEKKO()
but I get the following error message:
AttributeError: 'GEKKO' object has no attribute 'rnorm'
I would like to know if there is something that I am missing or if there is another way to get random numbers.

The documentation page you linked is associated with another package that isn't the same as the Optimization Suite in Python. I suggest looking at this page: https://gekko.readthedocs.io/en/latest/model_methods.html for the correct documentation.
As for your question about random numbers, I suggest using another package like python's random or numpy's random.normal. I'm not sure how exactly to apply it in your problem without seeing more code; what you could do is have an array of random numbers for each timestep and multiply or add it in somewhere while writing the problem in Gekko.

The documentation link that you provided is to different gekko software:
Gekko Timeseries and Modeling Software is a free and open-source software system for managing and analyzing timeseries data, and for solving and analyzing large-scale economic models. See the Gekko homepage: www.t-t.dk/gekko. Read more about the status of different Gekko versions on the Gekko versions overview page.
The Gekko Optimization Suite in Python pip install gekko is described in the Wikipedia article and in the Read the Docs documentation.
GEKKO is a Python package for machine learning and optimization of mixed-integer and differential algebraic equations. It is coupled with large-scale solvers for linear, quadratic, nonlinear, and mixed integer programming (LP, QP, NLP, MILP, MINLP). Modes of operation include parameter regression, data reconciliation, real-time optimization, dynamic simulation, and nonlinear predictive control. GEKKO is an object-oriented Python library to facilitate local execution of APMonitor.
Both software packages can analyze time-series data. The numpy.random.randn() function can be used with gekko.
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
p = m.Param()
x = m.Var()
m.Equation(x==5*p)
for i in range(10):
p.value = np.random.randn()
m.solve(disp=False)
print(x.value[0],p.value[0])
This solves the optimization problem 10 times with different values for p sampled from a normal, mean-zero distribution.

Related

Is it possible to change the linear solver used within GEKKO?

As the title says, I'm trying to find out what linear solver is used within GEKKO, for solving problems with remote=True and remote=False. I'm also curious if it's possible to change this, as you can in Pyomo. I was unable to find any reference to this within the either the Gekko documentation (https://gekko.readthedocs.io/en/latest/) or the APMonitor documentation (https://apmonitor.com/wiki/).
Is anyone familiar with the internals of Gekko / how I could find this out?
Thank you!
All of the solvers in Gekko are Nonlinear Programming (NLP) or Mixed Integer Nonlinear Programming (MINLP). The Nonlinear Programming solvers use linear solvers to iteratively solve the line-search problem. The public server (remote=True) uses MA57 while the version distributed locally (remote=False) uses a linear solver called MUMPS that can be distributed. However, there are no linear programming solvers to directly solve LPs. The MINLP solver can solve LP, QP, QPQC, MILP, NLP, and MINLP problems. Here is example code to specify MA57 solver in IPOPT.
from gekko import GEKKO
m = GEKKO(remote=True)
m.options.SOLVER=3
m.solver_options = ['linear_solver ma57']
From the documentation:
SOLVER selects the solver to use in an attempt to find a solution. There are free solvers: 1: APOPT, 2: BPOPT, 3: IPOPT distributed with the public version of the software. There are additional solvers that are not included with the public version and require a commercial license. IPOPT is generally the best for problems with large numbers of degrees of freedom or when starting without a good initial guess. APOPT is generally the best when warm-starting from a prior solution or when the number of degrees of freedom (Number of Variables - Number of Equations) is less than 2000. APOPT is also the only solver that handles Mixed Integer problems. Use option 0 to compare all available solvers.

Nonlinear constrained optimization package for Python with direct support of matrix variables

I've been looking around for a nonlinear constrained optimization package for Python (to deal with problems that are NOT necessarily convex) that can directly handle matrix variables. More specifically, I'm dealing with optimization problems where the optimization variables are matrices, and where there are equality constraints with both sides of the equations being matrices. An example of such an optimization problem is the Orthogonal Procrustes problem (https://en.wikipedia.org/wiki/Orthogonal_Procrustes_problem).
In my search I have come across SciPy, pyOpt, Ipopt and GEKKO, but neither of them seem to directly support matrix variables (from the documentation I was able to find). I have considered doing some maneuvering to convert the matrices into vectors when necessary and vice versa (through numpy.reshape or something similar), but I would like to avoid that option as much as possible. The reason for this is that my problems are fairly large, and constantly reshaping arrays would significantly harm the efficiency of the optimization procedure.
Any suggestions?
Here is a problem with matrices:
min(sum(sum(B))
s.t. AX=B
sum(sum(A))=5
sum(sum(X))=2
It is configured using the m.Array method in Python GEKKO with A, X, and B as 2D matrices but they could be higher dimensional as well.
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
ni = 3; nj = 2; nk = 4
# solve AX=B
A = m.Array(m.Var,(ni,nj),lb=0)
X = m.Array(m.Var,(nj,nk),lb=0)
AX = np.dot(A,X)
B = m.Array(m.Var,(ni,nk),lb=0)
# equality constraints
m.Equations([AX[i,j]==B[i,j] for i in range(ni) \
for j in range(nk)])
m.Equation(5==m.sum([m.sum([A[i][j] for i in range(ni)]) \
for j in range(nj)]))
m.Equation(2==m.sum([m.sum([X[i][j] for i in range(nj)]) \
for j in range(nk)]))
# objective function
m.Minimize(m.sum([m.sum([B[i][j] for i in range(ni)]) \
for j in range(nk)]))
m.solve()
print(A)
print(X)
print(B)
You mentioned non-convexity so you may need to use a multi-start or other method to find a global solution in Gekko or else use a global optimizer in a different Python package. The axb or qobj object are valuable if some of your constraints are linear equation or quadratic objectives with constant matrices. You can use those for large-scale and sparse systems. The APMonitor and Gekko papers also review some of the other Python packages for optimization.

Solving first-order ODE, which contains another ODE (odeint / solve_ivp in Python)

I'm trying to set up a fast numerical solver in Python for a differential problem of the form:
where r is some constant.
I want to integrate A over some time period, t of interest. However, this is complicated by the fact that the dA/dt equation includes another variable B, which itself is described by an ODE dB/dt. B is actually a vector, but I've simplified the expression to try and highlight my problems more clearly.
I currently have a solution using a manual Euler method: ie compute dB/dt (then use B = B_previous + dB/dt * dt) and manually step along using a fixed time step size dt. However, this is slow and unreliable. I imagine it would be far better to use the built-in ODE solvers in Numpy, but I'm not sure this is possible given the coupled nature of the problem I'm trying to solve?
Is this possible using Numpy odeint or solve_ivp please? And if so, can anyone suggest any pointers please! Thanks.
What you have is a coupled differential equation which are standard to solve using Runge kutta, Eulers, and many other methods. You can use this example to guide you in writting your python code:
https://scipy-cookbook.readthedocs.io/items/CoupledSpringMassSystem.html
Keep in mind that that not all equations can be solved with ODEINT. If your ODE is a "stiff" ODE then you will have to choose your algorithm precisely. The definition of a stiff ODE is not completely defined but usually they arise if you have large or non-integral powers of your dependent variable in your ODE.
The first step in solving a coupled ODE though is to use standard methods. If they don't work then look into something else.

Multidimensional/multivariate dynamic time warping (DTW) library/code in Python

I am working on a time series data. The data available is multi-variate. So for every instance of time there are three data points available.
Format:
| X | Y | Z |
So one time series data in above format would be generated real time. I am trying to find a good match of this real time generated time series within another time series base data, which is already stored (which is much larger in size and was collected at a different frequency). If I apply standard DTW to each of the series (X,Y,Z) individually they might end up getting a match at different points within the base database, which is unfavorable. So I need to find a point in base database where all three components (X,Y,Z) match well and at the same point.
I have researched into the matter and found out that multidimensional DTW is a perfect solution to such a problem. In R the dtw package does include multidimensional DTW but I have to implement it in Python. The R-Python bridging package namely "rpy2" can probably of help here but I have no experience in R. I have looked through available DTW packages in Python like mlpy, dtw but are not help. Can anyone suggest a package in Python to do the same or the code for multi-dimensional DTW using rpy2.
Thanks in advance!
Thanks #lgautier I dug deeper and found implementation of multivariate DTW using rpy2 in Python. Just passing the template and query as 2D matrices (matrices as in R) would allow rpy2 dtw package to do a multivariate DTW. Also if you have R installed, loading the R dtw library and "?dtw" would give access to the library's documentation and different functionalities available with the library.
For future reference to other users with similar questions:
Official documentation of R dtw package: https://cran.r-project.org/web/packages/dtw/dtw.pdf
Sample code, passing two 2-D matrices for multivariate DTW, the open_begin and open_end arguments enable subsequence matching:
import numpy as np
import rpy2.robjects.numpy2ri
rpy2.robjects.numpy2ri.activate()
from rpy2.robjects.packages import importr
import rpy2.robjects as robj
R = rpy2.robjects.r
DTW = importr('dtw')
# Generate our data
template = np.array([[1,2,3,4,5],[1,2,3,4,5]]).transpose()
rt,ct = template.shape
query = np.array([[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]]).transpose()
rq,cq = query.shape
#converting numpy matrices to R matrices
templateR=R.matrix(template,nrow=rt,ncol=ct)
queryR=R.matrix(query,nrow=rq,ncol=cq)
# Calculate the alignment vector and corresponding distance
alignment = R.dtw(templateR,queryR,keep=True, step_pattern=R.rabinerJuangStepPattern(4,"c"),open_begin=True,open_end=True)
dist = alignment.rx('distance')[0][0]
print dist
It seems like tslearn's dtw_path() is exactly what you are looking for. to quote the docs linked before:
Compute Dynamic Time Warping (DTW) similarity measure between (possibly multidimensional) time series and return both the path and the similarity.
[...]
It is not required that both time series share the same size, but they must be the same dimension. [...]
The implementation they provide follows:
H. Sakoe, S. Chiba, “Dynamic programming algorithm optimization for spoken word recognition,” IEEE Transactions on Acoustics, Speech and Signal Processing, vol. 26(1), pp. 43–49, 1978.
I think that it is a good idea to try out a method in whatever implementation is already available before considering whether it worth working on a reimplementation.
Did you try the following ?
from rpy2.robjects.packages import importr
# You'll obviously need the R package "dtw" installed with your R
dtw = importr("dtw")
# all functions and objects in the R package "dtw" are now available
# with `dtw.<function or object>`
I happened upon this post and thought I would provide some updated information in case anyone else is trying to locate a way to do multivariate DTW in Python. The DTADistance package has the option to perform multivariate DTW.

How to solve a stiff ode with Python?

I'm a Python beginner. I'm trying to switch some programs that I have in matlab.
I need solve a stiff ode equation, whose inputs are all matrices. In matlab I use
[ttT,uT] = ode23s('SST',t,fT);
For most things you do in Matlab, you can do them with the NumPy module in Python. It can be found here.
You might also find the related module SciPy useful as well.
PyDSTool might also be of relevance to you. It's a wrapper around the Radau solver.
Then you might like to try matplotlib for plotting. It works quite like Matlab's plotting thing.
The following links might help, too:
http://www.ews.uiuc.edu/~mrgates2/ode/
http://wiki.python.org/moin/NumericAndScientific?action=show&redirect=SciPy
Integrate stiff ODEs with Python
If you show me the differential equations I can help you a little more, but in general, a good way to solve a stiff ODE system is through the next sentence:
solution = scipy.integrate.solve_ivp(function, [t_0, t_f], y0, method='BDF', first_step =0.0001, dense_output=True)
where your function has to be defined previously in this way: function(t,variable,parameters)
t_0 = initial value for time
t_f = final value for time
y0 = value of your variables at t_0
For stiff ODE system, I suggest use the method 'BDF' (is typically used in the solve of microkinetic systems in reactors, where the importance of the time could change a lot)
for more infomation about the options of the code: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html

Categories