4

假设在matlab中如下:

[t, x, te, xe, ie] = ode15s(@myfunc, [tStart tFinal], x0, odeset('Events', @events));

问题 1

1a) 该函数在求解器成功执行后events调用。这是真的?

1b)在求解器成功执行步骤之后,是否有可能最后一次调用myfunc 不是导致成功步骤的调用?

1c) 如果events函数包含多个终端事件,并且在成功的步骤中检测到其中两个(不仅仅是一个)已经发生,求解器的行为是什么?

问题2

假设myfunc包含以下代码

if (check(x) > 2)
    dx(3) = x(1)*x(2);
else
    dx(3) = x(2)^2;
end

check的某个函数在哪里x

解决此问题的一种方法是使用事件函数。根据我的经验,ode 求解器可以通过这种方式解决此类问题。

解决此问题的另一种方法是使用事件函数进行定位check(x) - 2 == 0,一个终端事件用于定位,direction = 1另一个用于定位direction = -1。在求解器在任一事件上停止后,全局变量例如myvar被适当地设置以区分这两个事件,然后模拟从它停止的地方继续。在这种情况下,代码myfunc将是

if (myvar == 1)
    dx(3) = x(1)*x(2);
else
    dx(3) = x(2)^2;
end

在简单的情况下,两种方式都会产生正确的结果。但是我正在尝试解决一个非常复杂的问题(除上述之外的其他事件以及微分方程的不连续右手部分在某些情况下被证明是可解的)并且我试图找出一种方法是否会产生不同的结果比第二个。

有人可能会说 ode 之前要么无法返回解决方案,tFinal要么返回正确的解决方案,但由于右手部分的不连续性,当存在解决方案时,求解器可能不会返回解决方案。

所以从某种意义上说,问题是:使用第一种方式和第二种方式之间的实际理论区别是什么?

4

1 回答 1

1

由于我在这些问题上花费了一些精力,因此我正在回复一些反馈。

问题 1

1a) 是的,这是真的。有关参考,请参见例如ode15s.mmatlab 求解器。但是请注意,在求解器继续求解之前,为了获得更准确的值events,可能会多次调用该函数。te

1b) 是的,这也是正确的。

1c) 在这种情况下,求解器将终止返回一个ie向量,该向量包含停止求解器的事件的两个(甚至更多)索引。在这种情况下,te向量将包含相等的元素(te(1) == te(2) 将始终返回 true)。这是区分“双重事件”(即在同一成功步骤后同时停止求解器的事件)与 ode 求解器在终端事件后继续求解时记录的“假”事件的唯一方法(以更好地理解我的内容) m 说还阅读MATLAB 中的 ode 求解器事件位置索引)。

跟踪odezero函数将使 1c 的答案非常清楚。

问题2

现在这是一个棘手的答案。**一般*两种方式都返回正确的结果。但是(并且最自然地)它们不一定会在确切的时间点以确切的步数返回确切的解点。

两种方式之间的显着区别在于,在第二种方式中,仅当仅使用当前活动check(x)-2的分支发生符号更改时,我们才会进行分支更改。例如,假设当前活动的分支是第一个。当求解器在仅使用分支生成的成功步骤之后注意到符号更改时,才会更改到第二个分支。简而言之,成功和不成功的步骤都是在使用另一个分支之前使用相同的分支计算的。但是,如果我们使用第一种方式,我们可能会注意到在(例如)不成功的步骤期间使用了非活动分支。check(x) - 2

With these in mind comes the verdict; the most general and strictly correct way to choose is the second one (using events). The first way should also return correct results. HOWEVER, due to the difference between the two ways, the first one could fail in very specific/extreme problems. I'm very tempted to provide information about my case, in which ONLY the second way could be safely used, but it truly is a long way to go.

于 2011-10-19T21:43:01.997 回答