Gekko 求解微分方程和代数方程。y
您可以通过定义一个导数等于的新变量来包含积分x
。
from gekko import GEKKO
import numpy as np
m = GEKKO()
m.time = np.linspace(0,2,5)
m.options.IMODE=4; m.options.NODES=6
x = m.Var(5)
m.Equation(x.dt()==-x)
y = m.Var(0)
m.Equation(y.dt()==x)
m.solve()
print(np.round(y.value,5))
结果是在时间点 [0, 0.5, 1.0, 1.5, 2.0][0., 1.96735, 3.1606, 3.88435, 4.32332]
的积分。x
的初始条件y
为零,但它可以是非零的,例如使用比例积分微分 (PID) 控制器,其中积分项可以在每个循环中累积。
在 Gekko v0.2.6 ( pip install gekko --upgrade
) 中,将有一个新integral
功能(感谢您的提问)。您的注释行是正确的,但不要忘记方程式表达式中的双等号。
m.Equation(y==m.integral(x))
这是数值解和精确解的比较。
from gekko import GEKKO
import numpy as np
m = GEKKO()
m.time = np.linspace(0,2,5)
m.options.IMODE=4; m.options.NODES=6
x = m.Var(5)
m.Equation(x.dt()==-x)
y = m.Var(0)
m.Equation(y==m.integral(x))
z = m.Var(0)
m.Equation(z.dt()==x)
m.options.SOLVER=1
m.solve()
# results
print('Numerical x')
print(np.round(x.value,6))
print('Exact x')
print(np.round(5*np.exp(-m.time),6))
print('Numerical Integral y')
print(np.round(y.value,6))
print('Numerical Integral z End Point')
print(np.round(z.value[-1],6))
print('Exact Integral')
print(np.round(-5*(np.exp(-2)-np.exp(0)),6))
结果有 1e-6 的差异,因为它们是仅在请求的时间点计算的数值解。解决方案在增加时间点时会更准确,但解决方案会更慢(尤其是对于大问题)。
Numerical x
[5. 3.032654 1.839398 1.115651 0.676677]
Exact x
[5. 3.032653 1.839397 1.115651 0.676676]
Numerical Integral y
[0. 1.967346 3.160602 3.884349 4.323323]
Numerical Integral z End Point
4.323323
Exact Integral
4.323324