ode45 with short timesteps not working - matlab

I am using ode45 and I can't figure out what to do in this case. I have a differential equation where my paramters change very quickly with time. Ideally, I would like to choose tspan to be like 0:epsilon:10*epsilon where epsilon is of an appropriately small order considering whatever I have in the factors of my DE. However, this does not work and MATLAB simply gives me a plot where nothing changes from my initial conditions.
I did the obvious thing to fix it which was the following. Say I have xdot(t)=10^9*x(t). I rewrite it as xdot(t)=x(t) and label my time axis as nanoseconds instead of seconds.
Just curious if MATLAB can do this on its own.

You can set a maximum time step using ODE options.
opt = odeset('MaxStep',epsilon)
[t,y] = ode45(odeFun,tSpan,y0,opt)
To get an idea of all the options that you can change when customizing an ODE solver look at docsearch odeset.

Related

Matlab ode15s: postive dx/dt, decreasing x(t)

In my script, I call the ODE solver ode15s which solves a system of 9 ODE's. A simplified structure of the code:
[t, x] = ode15s(#odefun,tini:tend,options)
...
function dx = odefun(t,x)
r1=... %rate equation 1, dependent on x(1) and x(3) for example
r2=... %rate equation 2
...
dx(1) = r1+r2-...
dx(2) = ...
...
dx(9) = ...
end
When reviewing the results I was curious why the profile of one state variable was increasing at a certain range. In order to investigate this, I used conditional debugging within the ode function so I could check all the rates and all the dx(i)/dt equations.
To my big surprise, I found out that the differential equation of the decreasing state variable was positive. So, I simulated multiple rounds with the F5-debug function, and noticed that indeed the state variable consistently decreased, while the dx(i)/dt would always remain positive.
Can anyone explain me how this is possible?
It is not advisable to pause the integration in the middle like that and examine the states and derivatives. ode15s does not simply step through the solution like a naive ODE solver. It makes a bunch of calls to the ODE function with semi-random states in order to compute higher-order derivatives. These states are not solutions to system but are used internally by ode15s to get a more accurate solution later.
If you want to get the derivative of your system at particular times, first compute the entire solution and then call your ODE function with slices of that solution at the times you are interested in.

Matlab - ODE45 - change the number of time steps

I have a function with the handle #func with initial condition y0 that I want to test over t = [0, tspan]. What, exactly, do I need to do to increase the number of time steps ode45 uses, without changing tspan?
I saw the MATLAB documentation of ode45 and saw that I need to somehow change the options input to ode45. However, I do not really understand how to do this because no example code was provided.
You need to look at odeset which creates an options structure to be used in ODE solvers, like ode45. You're looking at changing the MaxStep parameter.
The documentation for this (MATLAB R2015a) says:
MaxStep - Upper bound on step size [ positive scalar ]
MaxStep defaults to one-tenth of the tspan interval in all solvers.
Therefore, you can make it something smaller than 0.1*tspan... something like 1e-6 or something like that. This depends on what tspan is, so you'll need to make it smaller than 0.1*tspan if you want to increase the total number of time steps / output points.
As such, create an odeset structure and override the MaxStep parameter. The rest of the values will remain as default:
options = odeset('MaxStep', 1e-6);
Now that you're done, call ode45 on your problem:
[tout,yout] = ode45(#func, tspan, y0, options);
Simply play around with the MaxStep until you get the desired granularity.
Minor Note
Though a bit buried, the documentation does tell you on how to change the options. This is the section that talks about how to call ode45 with options. Please take note of what is highlighted in bold. This is the documentation for MATLAB R2015a:
[TOUT,YOUT] = ode45(ODEFUN,TSPAN,Y0,OPTIONS) solves as above with default
integration properties replaced by values in OPTIONS, an argument created
with the ODESET function. See ODESET for details. Commonly used options
are scalar relative error tolerance 'RelTol' (1e-3 by default) and vector
of absolute error tolerances 'AbsTol' (all components 1e-6 by default).
If certain components of the solution must be non-negative, use
ODESET to set the 'NonNegative' property to the indices of these
components.

how to use Euler method for numerical integration of differential equation?

I want to numerically solve a stochastic differential equation (SDE) in MATLAB, The code I have written just simply does not recognize sde function!
The question is as below:
dz=v*dt +sqrt(2*Ds)*dw_t
where v = 1/(N*delta) * sigma f_i (i=1- N)
N= 100,
delta = e6,
and f_i is calculated form this equation:
for z>=z0 , f_i = -kappa*(z0_i -z) and kappa = .17
for z<z0 , f_i = -kappaT*(z0_i -z) and kappaT = 60
note that the initial values for z0_i is randomly distributed over 60nm range.
Ds = 4e4
and dw_t is an increment in Wiener process.
Firstly I don't know how to set the conditions for z while I don't have the value for it!
Secondly, the Euler algorithm is exactly matching the equation but I don't know why the code with sde function is not working!
In order to numerically solve a SDE, you would need a Initial Condition (IC) for the function you want to code. In your case, I guess it's z. If you want to do so without explicitly declaring the IC, you can write it as a function that takes an IC. Then to test, you would input random ICs in.
Also, it is not clear to me whether your z0 is also stochastic and changes with time, is randomly generated every time step, or a constant that was only randomly generated once. Even simpler, if z0 is just the IC of z, then your f_i just inspects whether z has increased or decreased through the time step to decide how z would change the next time step. Please clarify this and your problem will seem much clearer.
It is not too hard to simulate your SDE without the use of the solver. You can try it out and achieve better result since sometimes you will really need to learn the behavior of the solver in order for it to work. I would suggest Monte Carlo method if you choose to write your own solver to ensure accuracy.
I hope my answer helps. If you still have any questions, feel free to ask.

Matlab understanding ode solver

I have a system of linked differential equations that I am solving with the ode23 solver. When a certain threshold is reached one of the parameters changes which reverses the slope of my function.
I followed the behavior of the ode with the debugging function and noticed that it starts to jump back in "time" around this point. Basically it generates more data points.However, these are not all represented in the final solution vector.
Can somebody explain this behavior, especially why not all calculated values find their way into the solution vector?
//Edit: To clarify, the behavior starts when v changes from 0 to any other value. (When I write every value of v to a vector it has more than a 1000 components while the ode solver solution only has ~300).
Find the code of my equations below:
%chemostat model, based on:
%DCc=-v0*Cc/V + umax*Cs*Cc/(Ks+Cs)-rd
%Dcs=(v0/V)*(Cs0-Cs) - Cc*(Ys*umax*Cs/(Ks+Cs)-m)
function dydt=systemEquationsRibose(t,y,funV0Ribose,V,umax,Ks,rd,Cs0,Ys,m)
v=funV0Ribose(t,y); %funV0Ribose determines v dependent on y(1)
if y(2)<0
y(2)=0
end
dydt=[-(v/V)*y(1)+(umax*y(1)*y(2))/(Ks+y(2))-rd;
(v/V)*(Cs0-y(2))-((1/Ys)*(umax*y(2)*y(1))/(Ks+y(2)))];
Thanks in advance!
Cheers,
dahlai
The first conditional can also be expressed as
y(2) = max(0, y(2)).
As one can see, this is still a continuous function, but with a kink, i.e., a discontinuity in the first derivative. One can this also interpret as a point with curvature radius 0, i.e., infinite curvature.
ode23 uses an order 2 method to integrate, an order 3 method to estimate the error and probably the order 1 Euler step to estimate stiffness.
An integration step over the kink renders all discretization errors to be order 1 (or 2, depending on the convention), confounding the logic of the step size control. This forces a rather radical step-size reduction, but since that small step then falls, most probably, short of the kink, the correct orders are found again, resulting in a step-size increase in the next step which could again go over the kink etc.
The return array only contains successful integration steps, not the failed attempts of the step-size control.

Forcing matlab ODE solvers to use dy/dx = 0 IF dy/dx is negative

I need to numerically integrate the following system of ODEs:
dA/dR = f(R,A,B)
dB/dR = g(R,A,B)
I'm solving the ODEs for a Initial-value stability problem. In this problem, the system is initially stable but goes unstable at some radius. However, whilst stable, I don't want the amplitude to decay away from the starting value (to O(10^-5) for example) as this is non-physical since the system's stability is limited to the background noise amplitude. The amplitude should remain at the starting value of 1 until the system destabilises. Hence, I want to overwrite the derivative estimate to zero whenever it is negative.
I've written some 4th order Runge-Kutta code that achieves this, but I'd much prefer to simply pass ODE45 (or any of the built in solvers) a parameter to make it overwrite the derivative whenever it is negative. Is this possible?
A simple, fast, efficient way to implement this is via the max function. For example, if you want to make sure all of your derivatives remain non-negative, in your integration function:
function ydot = f(x,y)
ydot(1) = ...
ydot(2) = ...
...
ydot = max(ydot,0);
Note that this is not the same thing as the output states returned by ode45 remaining non-negative. The above should ensure that your state variables never decay.
Note, however, that that this effectively makes your integration function stiff. You might consider using a solver like ode15s instead, or at least confirming that the results are consistent with those from ode45. Alternatively, you could use a continuous sigmoid function, instead of the discontinuous, step-like max. This is partly a modeling decision.