How can I stop ode45

15 views (last 30 days)
Mark S
Mark S on 11 Nov 2020
Commented: Walter Roberson on 13 Nov 2020
Hi, how can I stop ode45 when the function is on the lowest point:
I have tried that.
options = odeset('Events', @deep);
[t, u] = ode45(@bet, [0 80], [0 0 L], options)
function [val, term, dir] x= deep (L)
[t, u]=ode45(@bet, [0 80], [0 0 L]);
x = max(u(:,1));
term = 1;
dir = -1;
But i got an error and for me is not sure why:
Error: File: deep.m Line: 1 Column: 27
Invalid expression. Check for missing multiplication operator, missing or unbalanced delimiters, or other syntax error. To
construct matrices, use brackets instead of parentheses.
Error in odeevents (line 28)
eventValue = feval(eventFcn,t0,y0,eventArgs{:});
Error in ode45 (line 148)

Accepted Answer

Walter Roberson
Walter Roberson on 11 Nov 2020
function [val, term, dir] x= deep (L)
What is the intention of the "x=" part of that line?
function [val, term, dir] x= deep (L)
[t, u]=ode45(@bet, [0 80], [0 0 L]);
x = max(u(:,1));
No no no! That code runs the entire ode inside the event function, but this time without any event function. After the entire ode finishes, it finds the maximum of the values returned for the first boundary value. Then it does nothing with that calculated value, and returns from the function without having assigned anything to val
If you were to assign val = x where x is the result of that max(), then you would be asking the event function to signal a termination of the maximum value returned for the first variable descends to 0.
Well... except that you would never have reached any of this: you would have gotten an error message because the event function will be passed two values, not one.
If you want to stop when the first input descends to 0, then just use
function [val, term, dir] = deep(t, x)
val = x(1);
term = 1;
dir = 1;
If you are trying to stop when the function reaches its minimum, then you have the potential problem that the event function is only ever looking at local values, and examination of a local value can never tell you about the overall behavior of the function. You can, with some minor work, get it to stop when it has reached a local minima, but in many many functions, local minima are common. It is seldom possible to mechanically figure out whether an arbitrary function has reached its global minima.... but with sufficient knowledge of the function being integrated, it might be possible with some coding.
You cannot directly tell whether a point being evaluated has an associated value that is less than the "previous" value -- and using something like "persistent" to record the previous value will not work, as points are not evaluated in order. You can, though, carry around derivatives, and check for derivative 0 and second derivative positive to determine if you are at a local minima.
Walter Roberson
Walter Roberson on 13 Nov 2020
You cannot do that in the general case. ode45 cannot know where the lowest spot is until the entire run is made and then the output structure is analyzed to figure out where the lowest point of the approximation would be, by doing piecewise derivative of the quintic (degree 5) interpolation polynomial, figuring out which ones were minima, and comparing results across all segments.
However, for some systems, you just need to test if the first derivative is 0 and the second derivative is positive. This requires that you already know that the function only has one minimum over the interval of interest.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!