我应该如何使用 GEKKO 对 log 或 sqrt 建模?限制

问题描述 投票:0回答:2

我正在尝试使用 GEKKO 开发我的约束,并且我需要包括一些数学运算,如 log、coth 或 sqrt。

我最初尝试使用我的习惯程序,使用 numpy 或 mpmath,但我发现使用 GEKKO 我需要使用它们的运算符定义,如 m.wathever (log,...),一旦 m = GEKKO() 完成

如何发展这一点的最佳方式? 我在更改时是否应该考虑一些因素?

K_t = (1 + m + np.sqrt(1 + m**3)) - mpmath.coth(s/2)  # Ref 2. Same results
python numpy optimization sqrt gekko
2个回答
3
投票

使用这些函数的 Gekko 版本而不是 NumPy 或 Math 版本:

gk = GEKKO()
K_t = (1 + m + gk.sqrt(1 + m**3)) - gk.cosh(s/2)/gk.sinh(s/2)

由于运算符重载,需要 Gekko 版本来计算具有自动微分的求解器的一阶和二阶导数。没有

coth
,因此您需要用
coth(x) = cosh(x)/sinh(x)
代替。我通常将 Gekko 模型定义为
m=GEKKO()
,但你有另一个名为
m
的变量,所以我使用
gk
代替。这是模型构建函数文档中的一部分。

方程函数

通过 GEKKO 函数可以使用除代数运算符之外的特殊函数。必须使用这些(不是 numpy 或其他等效函数):

  • gk.sin(其他)
  • gk.cos(其他)
  • gk.tan(其他)
  • gk.asin(其他)
  • gk.acos(其他)
  • gk.atan(其他)
  • gk.sinh(其他)
  • gk.cosh(其他)
  • gk.tanh(其他)
  • gk.exp(其他)
  • gk.log(其他)
  • gk.log10(其他)
  • gk.sqrt(其他)

0
投票

关于

sqrt
的一个相关观察是,通过防止参数为负的情况,解决方案的稳健性得到了提高。这是一个使用
gekko
的简单系统:

from gekko import GEKKO
import numpy as np
m = GEKKO()
m.time = np.linspace(0,20,100)
k = 5
y = m.Var(value=5.0)
t = m.Param(value=m.time)

m.Equation(k*y.dt()==-m.sqrt(y))
m.options.IMODE = 4
m.solve(disp=True)

它似乎陷入了

sqrt
,可能是因为它可能变得小于零,并且
gekko
求解器需要额外的方程来处理复数。更改方程以用
sqrt
删除
m.Equation((-k*y.dt())**2==y)
是此问题的潜在解决方案:

from gekko import GEKKO
import numpy as np
m = GEKKO()
m.time = np.linspace(0,20,100)
k = 5
y = m.Var(value=5.0)
t = m.Param(value=m.time)

m.Equation((-k*y.dt())**2==y)
m.options.IMODE = 4
m.solve(disp=True)

import matplotlib.pyplot as plt
plt.plot(m.time,y)
plt.show()

另一种策略是将

sqrt
的参数限制为大于零,例如使用
y = m.Var(value=5.0,lb=0)
y.LOWER=0
。这也可以用原始方程找到成功的解。

from gekko import GEKKO
import numpy as np
m = GEKKO()
m.time = np.linspace(0,20,100)
k = 5
y = m.Var(value=5.0,lb=0)
t = m.Param(value=m.time)

m.Equation(k*y.dt()==-m.sqrt(y))
m.options.IMODE = 4
m.solve(disp=True)
© www.soinside.com 2019 - 2024. All rights reserved.