这是我上一篇关于用壁虎解颂歌时的线性插值法的后续问题.基本上,我有一个参数k
作为时间的线性函数,k(t)
,类似于:
我想包括此参数,以便在ODE积分过程中自动内插.
以下是运行模拟的代码:
from gekko import GEKKO
import numpy as np
kt = np.array([0,0.2,0.45,0.75,1.0])
kv = np.array([0.5,1.0,0.2,1.2,1.0])
m = GEKKO()
m.time = np.linspace(0, 1, 11)
# include kt time points in m.time
m.time = np.concatenate((m.time, kt))
m.time = np.sort(m.time)
m.time = np.unique(m.time)
k = np.interp(m.time, kt, kv)
k = m.Param(value=k)
x = m.Var(value=0)
m.Equation(x.dt() == k)
m.options.IMODE = 4
m.solve(disp=False)
import matplotlib.pyplot as plt
plt.figure(figsize=(5,2.5))
plt.plot(kt,kv,'bo-',label='k data')
plt.plot(m.time,k.value,'rx-',label='k interp')
plt.plot(m.time,x.value,'k-',label='x')
plt.plot(); plt.legend(); plt.grid()
##plt.tight_layout(); plt.savefig('p.png',dpi=300)
plt.show()
我的后续问题是,我现在想计算k(t)
,即优化,以实现某个目标函数.
所以,我修改了上面的代码,将k
从Param
改为MV
,并切换到IMODE = 6
.
from gekko import GEKKO
import numpy as np
kt = np.array([0,0.2,0.45,0.75,1.0])
kv = np.array([0.5,1.0,0.2,1.2,1.0])
m = GEKKO()
m.time = np.linspace(0, 1, 11)
# include kt time points in m.time
m.time = np.concatenate((m.time, kt))
m.time = np.sort(m.time)
m.time = np.unique(m.time)
k = np.interp(m.time, kt, kv)
k = m.MV(value=k,lb = 0, ub = 2,fixed_initial=False)
k.STATUS = 1
x = m.Var(value=0)
m.Equation(x.dt() == k)
m.options.IMODE = 6
m.Minimize(x)
m.solve(disp=False)
import matplotlib.pyplot as plt
plt.figure(figsize=(5,2.5))
plt.plot(kt,kv,'bo-',label='k data')
plt.plot(m.time,k.value,'rx-',label='k interp')
plt.plot(m.time,x.value,'k-',label='x')
plt.plot(); plt.legend(); plt.grid()
plt.show()
问题是,上面的代码为对应于m时间长度的13个点计算k
.但是,我希望求解器只计算对应于原始长度kv
的5个点的k
.原因是,在实际问题中,只有5分就够优化了,所以计算13分太昂贵了.这是一个卡通例子,所以原因可能不是很明显,但在真正的问题中,kv
分是15分,m.time
分是150分(颂歌非常僵硬),所以这真的很重要.
我try 的另一种方法是强迫k
得5分:
from gekko import GEKKO
import numpy as np
kt = np.array([0,0.2,0.45,0.75,1.0])
kv = np.array([0.5,1.0,0.2,1.2,1.0])
m = GEKKO()
m.time = np.linspace(0, 1, 11)
k = m.MV(value=kv, lb = 0, ub = 2,fixed_initial=False)
k.STATUS = 1
x = m.Var(value=0)
m.Equation(x.dt() == k)
m.options.IMODE = 6
m.Minimize(x)
m.solve(disp=False)
import matplotlib.pyplot as plt
plt.figure(figsize=(5,2.5))
plt.plot(kt,kv,'bo-',label='k data')
plt.plot(m.time,k.value,'rx-',label='k interp')
plt.plot(m.time,x.value,'k-',label='x')
plt.plot(); plt.legend(); plt.grid()
plt.show()
但得到了一个错误:数据数组必须具有相同的长度,并在动态问题中匹配时间离散化,这是可以理解的.
真的很感激有人能帮助解决这个问题.
谢谢!