Matlab:将myODEfun用于odeset的'Vectorized'属性

时间:2013-09-06 12:04:24

标签: matlab vector ode

我有一个僵化的耦合ODE系统,我正在为MATLAB的ode15s解算器提供支持。它工作得很好,但现在我正在努力优化集成的速度。我在N个不同的空间位置上建模了5个不同的变量,给出了5N耦合方程。目前,N=20和积分时间约为25秒,但我希望更大的N值。

我使用分析器看到绝大部分时间用于评估myODEfun。我尽了最大努力来优化代码,但这并没有改变这样一个事实,即函数中有相当多的事情,并且它被评估〜50,000次。我读到使用'Vectorized'的{​​{1}}属性可以减少所需的评估次数。

但我不太清楚我需要更改我的ODEfunction到底是什么让它符合Matlab想要ODEfun 'vectorized'的样子。< / p>

From the documentation我看到你可以改变示例Van der Pol系统的正常形式:

ODEfun

到矢量化形式:

function dydt = vdp1000(t,y)
dydt = [y(2); 1000*(1-y(1)^2)*y(2)-y(1)];

我并不确切地知道这个function dydt = vdp1000(t,y) dydt = [y(2,:); 1000*(1-y(1,:).^2).*y(2,:)-y(1,:)]; 的新矩阵应该代表什么,以及第二维的大小是如何定义的。我几乎可以只添加“y”而不考虑它,但我遇到了问题,因为我已经在我的代码中进行了一些向量操作。

以下是我当前功能的简化示例,尚未,:。它模拟2个变量,制作vectorized方程。请不要试图理解这里生成的ODE:它们不会。我在谈论正在发生的行动。

2*N

显然,在实际功能中,function dydt = exampleODEfun(t,y,N) dydt = zeros(2*N,1); dTdt = zeros(N,1); dXdt = zeros(N,1); T = y(1:N); X = y(N+1:2*N); a = [T(2:N).^2 T(2:N) ones(N-1,1)]; b = [3 5 -2]; dTdt(1:N) = 0; dXdt(1) = 0; dXdt(2:N) = a*b'; dydt(1:N) = dTdt; dydt(N+1:2*N) = dXdt; end T都会发生更多事情。如您所见,X是一个边界条件,需要自己计算。

盲目地传递odeset dXdt(1)并且仅向所有索引添加“'Vectorized','on'”不起作用。例如,我需要将,:dTdt初始化为什么尺寸?我该怎么做dXdt?我需要做些什么才能使(ones(N-1,1))仍然有意义?

我正在使用Matlab R2006a。

1 个答案:

答案 0 :(得分:2)

来自help odeset

  

矢量化 - 矢量化ODE函数[on | {off}]

Set this property 'on' if the ODE function F is coded so that 
F(t,[y1 y2 ...]) returns [F(t,y1) F(t,y2) ...].

对于van der Pol的例子:

没有矢量化:

function dydt = vdp1000(t,y)             %// 'y' is passed as [y1 
                                         %//                   y2]

    dydt = [y(2);                        %// 'dydt' is computed as [y1´
            1000*(1-y(1)^2)*y(2)-y(1)]   %//                        y2´]
                                         %// where the ´ indicates d/dt
带有矢量化的

function dydt = vdp1000(t,y)            %// 'y' is passed as [y11 y21 y31 ...
                                        %//                   y12 y22 y32 ...] 

    dydt = [y(2,:);                             %// 'dydt' is computed as 
            1000*(1-y(1,:).^2).*y(2,:)-y(1,:)]; %//   [y11´ y21´ y31´ ...
                                                %//    y12´ y22´ y32´ ...]

其中y1y2y3等同时引用不同的向量y t ode15sy用来计算下一步。

对于您的示例,您必须考虑到您传递的function dydt = exampleODEfun(t,y,N) %// Adjust sizes to meet size of y dydt = zeros(2*N, size(y,2)); dTdt = zeros(N, size(y,2)); dXdt = zeros(N, size(y,2)); %// Adjust indices to extract proper vales of ALL vectors T = y(1:N,:); X = y(N+1:2*N,:); %// This sort of section is usually where all the "thought" goes into: %// you can't use a*b' anymore, so I sum over the third dimension of the % 3D array I built from your original vector b = [3 5 -2]; ab = sum(cat(3, b(1)*T(2:N,:).^2, b(2)*T(2:N,:), b(3)*ones(N-1, size(y,2))), 3); %// and finish it off dTdt(1:N,:) = 0; dXdt(1,:) = 0; dXdt(2:N,:) = ab; dydt(1:N,:) = dTdt; dydt(N+1:2*N,:) = dXdt; end 不再是矢量,而是一个矩阵,其中每列代表您需要计算衍生物的不同矢量:

{{1}}