在 ipopt 的等式中使用 scipy Odeint 的灵活性
flexibility using scipy Odeint in equation for ipopt
我正在验证我在 pyoptsparse 和 scipy 中编写的几个模型。我希望能够在 Gekko 中测试相同的代码,看看结果是否与我最初制作的更具象征意义的 Gekko 版本一致。为此,我尝试使用 Odeint 并与我自己的代码集成,而不是使用内置的 Gekko 功能。可以这样做吗?优化器采用 Odeint 梯度的能力有问题吗?
import numpy as np
from scipy.integrate import odeint
from gekko import GEKKO
nhrs = 24
time = np.arange(nhrs)
m = GEKKO(remote=True)
gen = m.Array(m.Param, nhrs)
for geni in gen:
geni.value = 1
tes_store = m.Array(m.Var, nhrs)
for tesi in tes_store:
tesi.value = 0
tesi.lower = -1
tesi.upper = 1
T = m.Array(m.SV, nhrs)
for testi in T:
testi.upper = 24
testi.lower = 0
def tes_T_dt(t, T, gen, tes_store):
return gen*tes_store
def tes_T(gen, tes_store, t):
T_hist = [0]
T_new = 0
for i in range(len(t)):
step = odeint(tes_T_dt, T_new, [0, 1], args=(gen[i].value, tes_store[i].value))
T_new = step[1][0]
T_hist.append(T_new)
return T_hist
Temp = tes_T(gen, tes_store, time)[1:]
equations = []
m.Equation(T == tes_T(gen, tes_store, time)[1:])
m.Obj(-T[23])
Temp = tes_T(gen, tes_store, time)[1:]
m.options.SOLVER = 3
m.solve()
for i in range(len(T)):
print(f'{i} gen={gen[i].value}, tes_store={tes_store[i].value}, T={T[i].value}, Temp={Temp[i]}')
我收到以下错误
@error: Equation Definition
Equation without an equality (=) or inequality (>,<)
false
STOPPING...
Traceback (most recent call last):
File "gekkopyoptsimpleTEST.py", line 54, in <module>
m.solve()
File "/home/prism/miniconda3/lib/python3.7/site-packages/gekko/gekko.py", line 2103, in solve
raise Exception(response)
Exception: @error: Equation Definition
Equation without an equality (=) or inequality (>,<)
false
STOPPING...
Gekko 中的所有表达式都必须使用 Gekko 变量,以便模型可以编译为字节码。如果您打开 运行 文件夹和 gk_model0.apm
,您将看到您使用此脚本创建的模型:
Model
Parameters
p1 = 1
p2 = 1
p3 = 1
p4 = 1
! removed p5-p21
p22 = 1
p23 = 1
p24 = 1
End Parameters
Variables
v1 = 0, <= 1, >= -1
v2 = 0, <= 1, >= -1
v3 = 0, <= 1, >= -1
v4 = 0, <= 1, >= -1
! removed v5-v45
v46 = 0, <= 24, >= 0
v47 = 0, <= 24, >= 0
v48 = 0, <= 24, >= 0
End Variables
Equations
False
minimize (-v48)
End Equations
End Model
如您所见 Equations
- End Equations
部分,公式:
m.Equation(T == tes_T(gen, tes_store, time)[1:])
计算为 False
因为它正在将一个数组与另一个不相等的数组进行比较。您需要在那里使用 Gekko 表达式,例如 m.Equation(T[i] == tes_T(gen, tes_store, time)[i+1])
。然而,tes_T
不能被 gekko 调用,所以等式的右边只是模型中永远不会更新的数字。 gekko 目前不支持黑盒函数。
Gekko 可以对微分方程进行积分。这是否接近您要通过调整 gen
并服从微分方程 dT/dt==gen*tes_store
来最大化 T
的最终值?
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
nhrs = 24
m = GEKKO(remote=False)
m.time = np.arange(nhrs)
gen = m.Param(value=1)
tes_store = m.Var(value=0,lb=-1,ub=1)
T = m.SV(lb=0,ub=24)
m.Equation(T.dt()==gen*tes_store)
p = np.zeros(nhrs); p[-1]=1
final = m.Param(p)
m.Maximize(T*final)
m.options.SOLVER = 3
m.options.NODES = 2
m.options.IMODE = 6
m.solve()
plt.plot(m.time,T.value,'k-',label='T')
plt.plot(m.time,gen.value,'b.-',label='gen')
plt.plot(m.time,tes_store,'r--',label='tes_store')
plt.legend()
plt.show()
我正在验证我在 pyoptsparse 和 scipy 中编写的几个模型。我希望能够在 Gekko 中测试相同的代码,看看结果是否与我最初制作的更具象征意义的 Gekko 版本一致。为此,我尝试使用 Odeint 并与我自己的代码集成,而不是使用内置的 Gekko 功能。可以这样做吗?优化器采用 Odeint 梯度的能力有问题吗?
import numpy as np
from scipy.integrate import odeint
from gekko import GEKKO
nhrs = 24
time = np.arange(nhrs)
m = GEKKO(remote=True)
gen = m.Array(m.Param, nhrs)
for geni in gen:
geni.value = 1
tes_store = m.Array(m.Var, nhrs)
for tesi in tes_store:
tesi.value = 0
tesi.lower = -1
tesi.upper = 1
T = m.Array(m.SV, nhrs)
for testi in T:
testi.upper = 24
testi.lower = 0
def tes_T_dt(t, T, gen, tes_store):
return gen*tes_store
def tes_T(gen, tes_store, t):
T_hist = [0]
T_new = 0
for i in range(len(t)):
step = odeint(tes_T_dt, T_new, [0, 1], args=(gen[i].value, tes_store[i].value))
T_new = step[1][0]
T_hist.append(T_new)
return T_hist
Temp = tes_T(gen, tes_store, time)[1:]
equations = []
m.Equation(T == tes_T(gen, tes_store, time)[1:])
m.Obj(-T[23])
Temp = tes_T(gen, tes_store, time)[1:]
m.options.SOLVER = 3
m.solve()
for i in range(len(T)):
print(f'{i} gen={gen[i].value}, tes_store={tes_store[i].value}, T={T[i].value}, Temp={Temp[i]}')
我收到以下错误
@error: Equation Definition
Equation without an equality (=) or inequality (>,<)
false
STOPPING...
Traceback (most recent call last):
File "gekkopyoptsimpleTEST.py", line 54, in <module>
m.solve()
File "/home/prism/miniconda3/lib/python3.7/site-packages/gekko/gekko.py", line 2103, in solve
raise Exception(response)
Exception: @error: Equation Definition
Equation without an equality (=) or inequality (>,<)
false
STOPPING...
Gekko 中的所有表达式都必须使用 Gekko 变量,以便模型可以编译为字节码。如果您打开 运行 文件夹和 gk_model0.apm
,您将看到您使用此脚本创建的模型:
Model
Parameters
p1 = 1
p2 = 1
p3 = 1
p4 = 1
! removed p5-p21
p22 = 1
p23 = 1
p24 = 1
End Parameters
Variables
v1 = 0, <= 1, >= -1
v2 = 0, <= 1, >= -1
v3 = 0, <= 1, >= -1
v4 = 0, <= 1, >= -1
! removed v5-v45
v46 = 0, <= 24, >= 0
v47 = 0, <= 24, >= 0
v48 = 0, <= 24, >= 0
End Variables
Equations
False
minimize (-v48)
End Equations
End Model
如您所见 Equations
- End Equations
部分,公式:
m.Equation(T == tes_T(gen, tes_store, time)[1:])
计算为 False
因为它正在将一个数组与另一个不相等的数组进行比较。您需要在那里使用 Gekko 表达式,例如 m.Equation(T[i] == tes_T(gen, tes_store, time)[i+1])
。然而,tes_T
不能被 gekko 调用,所以等式的右边只是模型中永远不会更新的数字。 gekko 目前不支持黑盒函数。
Gekko 可以对微分方程进行积分。这是否接近您要通过调整 gen
并服从微分方程 dT/dt==gen*tes_store
来最大化 T
的最终值?
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt
nhrs = 24
m = GEKKO(remote=False)
m.time = np.arange(nhrs)
gen = m.Param(value=1)
tes_store = m.Var(value=0,lb=-1,ub=1)
T = m.SV(lb=0,ub=24)
m.Equation(T.dt()==gen*tes_store)
p = np.zeros(nhrs); p[-1]=1
final = m.Param(p)
m.Maximize(T*final)
m.options.SOLVER = 3
m.options.NODES = 2
m.options.IMODE = 6
m.solve()
plt.plot(m.time,T.value,'k-',label='T')
plt.plot(m.time,gen.value,'b.-',label='gen')
plt.plot(m.time,tes_store,'r--',label='tes_store')
plt.legend()
plt.show()