我有一个MATLAB代码,可以解决以下类型的大规模ODE系统
function [F] = myfun(t,C,u)
这里是一个时间相关向量,用作函数myfun中的输入。我当前的代码读作: -
u = zeros(4,1);
u(1) = 0.1;
u(2) = 0.1;
u(3) = 5.01/36;
u(4) = 0.1;
C0 = zeros(15*4*20+12,1);
options = odeset('Mass',Mf,'RelTol',1e-5,'AbsTol',1e-5);
[T,C] = ode15s(@OCFDonecolumnA, [0,5000] ,C0,options,u);
我希望将整个时域划分为5个不同的部分,并且u的元素在不同的时间采用不同的值(类似于多步函数)。考虑到我后来想要解决一个优化问题以确定域[0,5000]中每个时间间隔的u值,那么编码它的最佳方法是什么。
由于
答案 0 :(得分:1)
ode15s
期望您的模型函数接受时间参数t
和差异状态变量的向量x
(或命名为C
)。由于ode15s
不允许我们传入控件输入的另一个向量u
,因此我通常将ODE函数ffcn
包含在model
函数中:
function [t, x] = model(x0, t_seg, u)
idx_seg = 0;
function y = ffcn(t, x)
% simple example of exponential growth
y(1) = u(idx_seg) * x(1)
end
...
end
在上文中,model
的参数是初始状态值x0
,切换时间向量t_seg
和控制输入值的向量u
不同的细分。您可以看到idx_seg
中可以看到ffcn
。这允许我们将模型集成到所有段上(将上面的...
替换为以下内容):
t_start = 0;
t = t_start;
x = x0;
while idx_seg < length(t_seg)
idx_seg = idx_seg + 1;
t_end = t_seg(idx_seg);
[t_sol, x_sol] = ode15s(@ffcn, [t_start, t_end], x(end, :));
t = [t; t_sol(2 : end)];
x = [x; x_sol(2 : end, :)];
t_start = t_end;
end
在循环的第一次迭代中,t_start
为0,t_end
是第一个切换点。我们现在使用ode15s
仅在此时间间隔内进行整合,我们的ffcn
会使用u(1)
评估ODE。解决方案y_sol
和相应的时间点t_sol
会附加到我们的整体解决方案(t
,x
)。
对于下一次迭代,我们将t_start
设置为当前段的末尾,并将新t_end
设置为下一个切换点。您还可以看到t_seg
的最后一个元素必须是模拟结束的时间。重要的是,我们将模拟轨迹的当前尾ode15s
传递给y(end, :)
作为下一段的初始状态向量。
总之,函数model
将使用ode15s
逐段模拟模型,并返回整体轨迹y
及其时间点t
。你可以通过像
[t, x] = model1(1, [4, 6, 12], [0.4, -0.7, 0.3]);
plot(t, x);
对于我的指数增长示例应该产生
对于优化运行,您需要编写目标函数。此目标函数可以将u
传递给model
,然后通过查看u
来计算与x
相关联的优点。