Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

ode - MATLAB: Is it possible to have two event values whilst using ode45?

I want two limitations to my ode45 calculation of a movement equation: position and time. I have already got the time event to work but I am not sure if and how I can add another event for limiting the position. EDIT: I also have many different particles coupled together in one ODE equation and need them to stop individually once they reach a 'roof' as they all travel at different speeds... would I be able to achieve this through events? I have an idea on how I would do this but its very complicated and would probably be very slow...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm not sure if you can do exactly what you want, but it is possible to do quite a lot with events. First, this sounds like some sort of numerical calculation of first passage time (a.k.a first hitting time). If these "particles" are stochastic, stop and don't use ode45 but rather a a method appropriate for SDEs.

As far as I know there is no limit on how many event functions you can have - or rather the dimension of the event function (similar to the dimension of your ODE function) - and their number is not tied to how many ODE equations you have. The events function receives both the current time and the current state vector. You can any or all of the elements of those to create each event. You are correct that more events functions and more complex events will slow down integration. The performance also depends on how often events are detected. If each of your particles reaches the "roof," as you call it, and triggers just a single event then that won't be too bad.

In terms of implementation, here a simple example based on Matlab's ballode example, that simulates N ballistic particles in the vertical alone. There are N non-terminating events to catch the time and speed of each particle as it passes through y = 0. One additional terminating event is added to check if all of the particles have passed through y = 0 (if we knew which particle this would be, as we do here, we could just make that event a terminating one).

function eventsdemo

% Initial conditions for n balls
n = 10;
y0(2*n,1) = 0;
y0(n+1:end) = linspace(20,40,n);

% Specify events function
options = odeset('Events',@(t,y)efun(t,y,n));

% Integrate
[t,y,te,ye,ie] = ode45(@(t,y)f(t,y,n),[0 10],y0,options);

figure;
plot(t,y(:,1:n),'b',te(1:n),ye(sub2ind(size(ye),ie(1:n),(1:n).')),'r.');

function dydt = f(t,y,n)
% Differential equations for ballistic motion
dydt = [y(n+1:end);zeros(n,1)-9.8];

function [value,isterminal,direction] = efun(t,y,n)
% Last event checks that all balls have hit ground and terminates integration
yn = y(1:n);
value = [yn;all(yn < 0)];
zn = zeros(n,1);
isterminal = [zn;1];
direction = [zn-1;1];

In some ways this is slightly inefficient because we keep simulating all N systems even after some of them have passed through y = 0. However, it is simple and the output arrays are rectangular rather than ragged.

I'm not clear what you mean precisely by "coupled together" and needing the particles to "stop." If you need to do more than just record the the event data, such as change system parameters or change the the differential equation(s) in some other way, then you'll need to terminate after each event and restart the integration. Look at the ballode example (type edit ballode in the Matlab command window) to see some suggestions on to make this a bit more efficient.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...