I'm trying to solve an optimization problem with GEKKO using python, I'm trying to develop some mathematical function with log and sqrt and I figure out that I should use gekko operator instead of using numpy or math function. I wanted to know how to implement log base 2 instead of log or log10 using gekko.
gk = GEKKO()
gk.log(...) # work
gk.sqrt(...) # work
gk.log2(...) # does not work!
Error :
AttributeError: 'GEKKO' object has no attribute 'log2'
Instead you can change the log base using the rule:
log2(x) = gk.log(x)/gk.log(2)
You can't expect for it to have all of the log bases implemented.
You can create a log2 function in Gekko, especially if you need to use it multiple times throughout your model.
def glog2(x):
return gk.log(x)/np.log(2)
Below is a complete script that demonstrates the use of the new log2 function and shows the agreement with the Numpy log2 function.
from gekko import GEKKO
import numpy as np
# compare with numpy
xnp = np.logspace(-1,4,100)
ynp = np.log2(xnp)
gk = GEKKO(remote=False)
x = gk.Param(xnp)
y,z = gk.Array(gk.Var,2)
# define a new log2 function
def glog2(x):
return gk.log(x)/np.log(2)
gk.Equation(y==glog2(x))
gk.options.IMODE=2; gk.solve(disp=False)
import matplotlib.pyplot as plt
plt.semilogx(xnp,ynp,'b-',lw=4,label=r'$y=\log_2(x)$ Numpy')
plt.semilogx(x.value,y.value,'r--',lw=2,label=r'$y=\log_2(x)$ Gekko')
plt.legend(); plt.xlabel('x'); plt.ylabel('y'); plt.grid(); plt.show()
Related
I'm trying to write a function that, given a set of parameters, uses Gekko to solve an optimal control problem. For whatever reason, whenever I run this function, it gives this error.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-92ece108f7ea> in <module>
1 import gekko as GEKKO
----> 2 solve_system()
<ipython-input-6-9d154ef663e4> in solve_system(theta, alpha, rho, chi, L_bar, n, w, delta_inc, xi, phi, tau, kappa, GAMMA, T, SIGMA, BETA, s_init, i_init, r_init)
26
27 ##### initialize model #####
---> 28 m = GEKKO()
29
30 ##### parameters #####
TypeError: 'module' object is not callable
I was looking into it and it seems to generally be an issue with the way you import the package/module, but I did this similarly (but not in a function) previously and had no issues. I have no idea where to start solving it: any pointers?
From the docs I think the import is supposed to be:
from gekko import GEKKO
You can import gekko a couple different ways to create a model m.
Method 1
from gekko import GEKKO
m = GEKKO()
Method 2
import gekko as gk
m = gk.GEKKO()
Method 3
If you want to use some of the other modules like the chemicals or deep learning objects in gekko you can use something like:
from gekko import gekko, chemical, brain
m = gekko()
c = chemical.Properties(m)
b = brain.Brain(m)
Method 4
Although it is possible, you should never do the following because of potential namespace conflicts with other imports:
from gekko import *
m = GEKKO()
BTW, great question! I recommend keeping the answer by rdas as the accepted response because it is the minimal correct solution. I just included these other options here for reference.
Lets say I have the following function:
def f(x):
return log(3*exp(3*x) + 7*exp(7*x))
I want to do two things:
1) plot the function over a range of x-values
2) find the root of the function using the Newton method from scipy
My problem is that it seems that plotting is best done with a numpy array x=np.linspace(-2,2,1000), but then evaluating the function results in erros TypeError: only size-1 arrays can be converted to Python scalars. I can fix this by simply changing log and exp to np.log and np.exp, respectively.
But doing so then makes scipy.optimize.newton unhappy.
It seems like I need to define the function twice, once for use in plotting (with np. ...) and once for optimizing in the form given above.
I can't imagine that this is actually the case. Any hints would be greatly appreciated.
Seems legit, you just need to use numpy functions instead of base math functions:
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
%matplotlib inline
def f(x):
return np.log(3*np.exp(3*x) + 7*np.exp(7*x))
x = np.linspace(-2,2,1000)
y = f(x)
plt.scatter(x, y)
optimize.root(f, 1)
I want to use the spectral method to solve partial differential equations. The equations like that, formula,the initial condition is u(t=0,x)=(a^2)*sech(x),u'_t (t=0)=0.
To solve it, I use the python with the spectral method. Following is the code,
import numpy as np
from scipy.integrate import solve_ivp
from scipy.fftpack import diff as psdiff
#RHS of equations
def f(t,u):
uxx= psdiff(u[N:],period=L,order=2)
du1dt=u[:N]
du2dt =a**2*uxx
dudt=np.append(du1dt,du2dt)
return dudt
a=1
amin=-40;bmax=40
L=bmax-amin;N=256
deltax=L/N
x=np.arange(amin,bmax,deltax)
u01 = 2*np.cosh(x)**(-1)
u02=np.zeros(N)
# y0
inital=np.append(u01,u02)
sola1 = solve_ivp(f, t_span=[0,40],y0=inital,args=(a,))
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(x,sola1.y[:N,5])
plt.show()
Following is my expected result,
expected result.
My python code can run,but I can't get the expected result,and can't find the problem.Following is the result from my python code,
my result
-----------------------------Update----------------------------------------------
I also try a new code,but still can't solve
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from scipy.fftpack import diff as psdiff
from itertools import chain
def lambdifide_odes(y,t,a):
# uxx =- (1j)**2*k**2*u[:N]
u1=y[::2]
u2=y[1::2]
dudt=np.empty_like(y)
du1dt=dudt[::2]
du2dt=dudt[1::2]
du1dt=u2
uxx=psdiff(u1,order=2,period=L)
du2dt=a**2*uxx
return dudt
a=1
amin=-40;bmax=40
L=bmax-amin;N=256
deltax=L/N
x=np.arange(amin,bmax,deltax)
u01 = 2*np.cosh(x)**(-1)
u02=np.zeros(N)
initial=np.array(list(chain.from_iterable(zip(u01,u02))))
t0=np.linspace(0,40,100)
sola1 = odeint(lambdifide_odes,y0=initial,t=t0,args=(a,))
fig, ax = plt.subplots()
ax.plot(x,sola1[20,::2])
plt.show()
You have some slight problem with the design of your state vector and using this in the ODE function. The overall intent is that u[:N] is the wave function and u[N:] its time derivative. Now you want the second space derivative of the wave function, thus you need to use
uxx= psdiff(u[:N],period=L,order=2)
at the moment you use the time derivative, making this a mixed third derivative that does not occur in the equation.
I am trying to do an exponential smothing in Python on some detrended data on a Jupyter notebook. I try to import
from statsmodels.tsa.api import ExponentialSmoothing
but the following error comes up
ImportError: cannot import name 'SimpleExpSmoothing'
I don't know how to solve that problem from a Jupyter notebook, so I am trying to declare a function that does the exponential smoothing.
Let's say the function's name is expsmoth(list,a) and takes a list list and a number a and gives another list called explist whose elements are given by the following recurrence relation:
explist[0] == list[0]
explist[i] == a*list[i] + (1-a)*explist[i-1]
I am still leargnin python. How to declare a function that takes a list and a number as arguments and gives back a list whose elements are given by the above recurrence relation?
A simple solution to your problem would be
def explist(data, a):
smooth_data = data.copy() # make a copy to avoid changing the original list
for i in range(1, len(data)):
smooth_data[i] = a*data[i] + (1-a)*smooth_data[i-1]
return smooth_data
The function should work with both native python lists or numpy arrays.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.random(100) # some random data
smooth_data = explist(data, 0.2)
plt.plot(data, label='orginal')
plt.plot(smooth_data, label='smoothed')
plt.legend()
plt.show()
I'm currently working on defining a mathematical function, i.e.,
from numpy import tanh
def stravinska(Z, eps=0.5):
return ((-0.86928)+(0.052481*Z))*(tanh(((2.66503)-(4.44255*Z))))-1.251617
SII = np.linspace(-3.0, 0.20)
To call within
axScatter_middle.plot(SII, stravinska(Z=0.5), '-k')
However, the following error is return upon compilation:
ValueError: x and y must have same first dimension
I'm scratching my head as to where I have gone wrong as I have used this method successfully many times before. What does this error mean and how can I rectify this problem?
I'm essentially trying to plot the equation 10 from this paper: Semi-empirical analysis of Sloan Digital Sky Survey galaxies – III. How to distinguish AGN hosts
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from numpy import tanh
def stravinska(log_SII_Ha, eps=0):
strav = ((-30.787)+(1.1358*(log_SII_Ha))+(0.27297*((log_SII_Ha)**2)))*(tanh(5.7409* (log_SII_Ha)))-31.093
return strav
SII = np.linspace(-3.0, 0.20)
axScatter_middle.plot(SII, stravinska(SII), '-k')