How can I save the values inside ODE solver?

11 visualizaciones (últimos 30 días)
Qiming
Qiming el 24 de Dic. de 2012
Comentada: Matteo Giovanni Perego el 30 de En. de 2018
Hi:
I have a question using ODE45. I generate a "random" value inside the my ODE function. I also need this random value in my main function. How can I save these random values? I cannot regenerate those random values after calling ODE45 since they will change.
Thanks for any help.
Paler

Respuestas (3)

Jan
Jan el 24 de Dic. de 2012
If the random value influences the integration, ODE45 is driven outside its specifications: The function to be integrated must be smooth, otherwise the stepsize control fails and ridiculously small stepsizes will at first slow down the calculations dramatically and at second the accumulated roundoff errors will dominate the result of the integration. Therefore these commands are massive DONTs in the integrand: IF, RAND, NOW (or any other time related functions), and even ABS is "evil", when the zero limit is crossed.
If you want to integrate a function, which has random parts, use a fixed step solver.
  1 comentario
Matteo Giovanni Perego
Matteo Giovanni Perego el 30 de En. de 2018
There's actually a solution to this problem: generating the random parts of the function only when we get a successful integration step.
Here's an example:
% Main:
y0 = 5; tspan = [0 100]; b = 10;
OutputFcn(0,0,'clear');
opts = odeset('OutputFcn',@OutputFcn,'refine',1);
[ts,ys] = ode45(@(t,y)odefun(t,y,b),tspan,y0,opts);
[~,rands] = OutputFcn(0,0,'allout');
figure(1)
subplot(2,1,1)
plot(ts,ys,'o-')
ylabel('y')
xlabel('x')
subplot(2,1,2)
plot(ts,rands,'ro-')
ylabel('random part')
xlabel('x')
% Functions:
function dy_dt = odefun(t,y,b)
% ODE:
[~,k] = OutputFcn(t,y,'pass2ode');
dy_dt = b*k;
end
function [status,out_rand] = OutputFcn(t,y,flag)
%OUTPUT FUNCTION:
persistent random
% Initialize random:
if isempty(random)
random = rand;
end
% Random number generation and output:
if isempty(flag)
% Successful integration step! Generate a new value:
random = [random; rand];
elseif strcmp(flag,'pass2ode')
out_rand = random(end);
elseif strcmp(flag,'allout')
out_rand = random;
elseif strcmp(flag,'clear')
clear random
end
% Always keep integrating:
status = 0;
end
Also, we need to set the 'refine' property to 1 since interpolated values between our integration steps would be complete nonsense due to the randomness of the increments.
Hope it helps!

Iniciar sesión para comentar.


Laura Proctor
Laura Proctor el 24 de Dic. de 2012
Editada: Laura Proctor el 24 de Dic. de 2012
Does the random value need to be generated inside your ODE function? In other words, can you pass it in as an input variable?
For example, suppose that your ODE function will now have the declaration:
function y = odefun(t,randValue)
Then, in your main function, you can generate the random value and create an anonymous function handle to embed it into the function so that you can call your ODE solver with this anonymous function handle:
randValue = rand;
afh = @(t) odefun(t,randValue);
[t,y] = ode45(afh,tspan,y0);
And now you have access to the random value inside your main function as the variable randValue.
  3 comentarios
Laura Proctor
Laura Proctor el 24 de Dic. de 2012
That's an interesting problem... you could use a global variable. But, I hate to recommend it, because global variables are generally not the best solution. I hope that someone else can provide a more elegant solution!
Laura Proctor
Laura Proctor el 24 de Dic. de 2012
Another idea is to use assignin to assign the value to a variable in your main function.

Iniciar sesión para comentar.


Image Analyst
Image Analyst el 24 de Dic. de 2012
I don't know anything about ODE45, but if your question is about how to share variables among other functions (because normally variables are just local to the function in which they live), you can see the FAQ for several suggestions of how to share variables. http://matlab.wikia.com/wiki/FAQ#How_can_I_share_data_between_callback_functions_in_my_GUI.28s.29.3F

Categorías

Más información sobre Ordinary Differential Equations en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by