Approximating derivative of numerical solution within event function
Afficher commentaires plus anciens
The issue I have is having to compute the derivative (in real time) of the solution produced by ode45 within the events function.
Some pseudo-code to explain what I'm mean is,
function dx = myfunc(t,x,xevent)
persistent xevent
% xevent is the solution at the event
dx(1) = x(2);
dx(2) = complicated function of x(1),x(2), and xevent;
end
function [value,isterminal,direction] = myeventfcn(t,x)
position = function of x(1), x(2), and dx(2);
isterminal = 1;
direction = 0;
end
I know that if I didn't need to use the solution at the event within `myfunc` I could just compute dx=myfunc(t,x) within my event function and use `dx(2)`, yet since `xevent` is used within `myfunc` I can't input `xevent`.
I know there is a way of inputting constant parameters within the event function, but since it's the solution at the event location, which also changes, I'm not sure how to go about doing that.
My work around to this is to approximate `dx(2)` using the solution `x`. What I wanted to know is if it will be satisfactory to just use a finite difference approximation here, using a small fixed step size relative to the step size od45 takes, which is a variable step size.
Thanks for any help!
10 commentaires
Torsten
le 11 Juil 2017
To compute dx(2), you need "xevent" even before the event occured (i.e. starting from t=0) ?
In this case, you will have to solve your ODE several times in order to iteratively determine tevent and xevent.
Best wishes
Torsten.
Shant Danielian
le 11 Juil 2017
Walter Roberson
le 11 Juil 2017
If you have duplicate calculations then put them into a function that is called by both myfunc and the event function.
Shant Danielian
le 11 Juil 2017
Modifié(e) : Shant Danielian
le 11 Juil 2017
Walter Roberson
le 11 Juil 2017
Calculations that are the same in both places.
Instead of trying to have myfunc estimate a value and push it out somewhere that the event function can read it, put the calculations into a routine and have both of them call that routine.
If you have R2017a or later, you could try memoize() to see if that helps -- it avoids recomputing values that have already been computed. However, the event function is not certain to be called with the same parameters as the ode function, and when ode45 is trying to find a place that is inside the boundary it can call the event function a number of times in a row looking for a place that is not rejected, which could be a problem for you if the calculation depends upon the derivative of places you have not yet evaluated.
ode45 is, by the way, permitted to move forwards and backwards in time or in boundary conditions. It mostly moves forward in time but when x is not a scalar then at times ode45 will call more than once with the same time and different boundary conditions.
Shant Danielian
le 11 Juil 2017
Walter Roberson
le 12 Juil 2017
"Do you mean have the myeventfcn and myfunc be nested in the same file?"
That would be one approach, but I am not talking about sharing variables (like would be possible with nested functions). You need to get rid of the reliance of the event function on a value calculated by the ode function, so you need to be able to perform the same calculation in both routines: I am saying to create a common routine (could be in a different file) to call from both to do the common work.
With regards to using memoize:
memoized_calc_dx2 = memoize(@calc_dx2);
memoized_calc_dx2.CacheSize = 25; %a guess
memoized_calc_dx2.CachePolicy = 'LFU'; %release least frequently used
memoized_calc_dx2.clearCache;
...
options = ... 'event', @(t, x) event_function(t, x, xevent, memoized_calc_dx2) )
[T, X] ode45(@(t, x) myfunc(t, x, xevent, memoized_calc_dx2), .... options)
%did the cache help?
memoized_calc_dx2.stats.Cache
function dx = myfunc(t, x, xevent, calc_dx2)
dx(1) = x(2);
dx(2) = calc_dx2(x, xevent);
function [value, isterminal, direction] = event_function(t, x, xevent, calc_dx2)
...
dx2 = calc_dx2(x, xevent);
...
Shant Danielian
le 24 Juil 2017
Walter Roberson
le 24 Juil 2017
Change CachePolicy to CachingPolicy
See toolbox/matlab/lang/+matlab/+lang/MemoizedFunction.m near line 138
Shant Danielian
le 24 Juil 2017
Réponse acceptée
Plus de réponses (0)
Catégories
En savoir plus sur Platform and License dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!