这是我上一篇关于用壁虎解颂歌时的线性插值法的后续问题.基本上,我有一个参数k作为时间的线性函数,k(t),类似于:

k profile

我想包括此参数,以便在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),即优化,以实现某个目标函数.

所以,我修改了上面的代码,将kParam改为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()

但得到了一个错误:数据数组必须具有相同的长度,并在动态问题中匹配时间离散化,这是可以理解的.

真的很感激有人能帮助解决这个问题.

谢谢!

推荐答案

设置m.options.MV_STEP_HOR可从默认值1(每步移动一次)调整为更高的值,例如4以使被操纵的变量每4步移动一次.要在该区间内保持相同的斜率,请将新的操作变量ks定义为斜率,并将k定义为变量.

k = m.Var(lb=0, ub=2, fixed_initial=False)
ks = m.MV(value=0,lb=-10,ub=10); ks.STATUS=1
m.Equation(k.dt()==ks)

ks的下限lb和上界ub设置了k的最小和最大变化率.对目标函数进行了修改,使结果更加有趣.蓝色虚线是坡度ks,红线是k.当ks每4个时间点改变一次时,k的斜率改变.在这个问题中有10个时间步长,所以变化发生在t=0t=0.4t=0.8,有0.1个时间间隔.

m.Minimize((x-0.5)**2)

slope results

以下是完整的脚本:

from gekko import GEKKO
import numpy as np

m = GEKKO()
m.time = np.linspace(0, 1, 11)
k = m.Var(lb=0, ub=2, fixed_initial=False)
ks = m.MV(value=0,lb=-10,ub=10); ks.STATUS=1
m.Equation(k.dt()==ks)

x = m.Var(value=0)
m.Equation(x.dt() == k)

m.options.IMODE = 6
m.options.MV_STEP_HOR=4

m.Minimize((x-0.5)**2)
m.solve(disp=False)

import matplotlib.pyplot as plt
plt.figure(figsize=(5,2.5))
plt.step(m.time,ks.value,'b:',label='ks')
plt.plot(m.time,k.value,'rx-',label='k')
plt.plot(m.time,x.value,'k-',label='x')
plt.plot(); plt.legend(); plt.grid()
plt.show()

Python相关问答推荐

@Property方法上的inspect.getmembers出现意外行为,引发异常

avxspan与pandas period_range

部分视图的DataFrame

driver. find_element无法通过class_name找到元素'""

给定高度约束的旋转角解析求解

启用/禁用shiny 的自动重新加载

如何从需要点击/切换的网页中提取表格?

将标签移动到matplotlib饼图中楔形块的开始处

在代码执行后关闭ChromeDriver窗口

用两个字符串构建回文

根据客户端是否正在传输响应来更改基于Flask的API的行为

在电影中向西北方向对齐""

获取PANDA GROUP BY转换中的组的名称

我可以不带视频系统的pygame,只用于游戏手柄输入吗?''

如何训练每一个pandaprame行的线性回归并生成斜率

如何在Python中解析特定的文本,这些文本包含了同一行中的所有内容,

两个名称相同但值不同的 Select 都会产生相同的值(discord.py)

#将多条一维曲线计算成其二维数组(图像)表示

对包含JSON列的DataFrame进行分组

Python:使用asyncio.StreamReader.readline()读取长行