Using an external array in ode45
2 views (last 30 days)
Show older comments
I am trying to use an external array for use in ode45. The code should be like for the first iteration of the ode45, it picks up the first element and for the second iteration it picks up the second one. I have limited the size of ode45 using a predetermined time array (right now upto 200 iterations for 10 seconds). Can someone guide me how to do this?
I tried using an external variable "n" which was set to value 1. It would get incremented upon the finishing of the iteration but on the next iteration, it would be set to 1 again. I even used a for loop and got the same results.
2 Comments
Jan
on 25 Feb 2022
The question is not clear.
"I have limited the size of ode45 using a predetermined time array" - do you mean the input tspan? This determines the number of output points, not the number of steps or of calls of the function to be integrated.
What do you call "first iteration"? What is iterated? What do you call "an external variable 'n'"?
Please post your code.
Accepted Answer
Jan
on 25 Feb 2022
This cannot work for several reasons:
- ODE45 is designe to integrate smooth functions with a certain accuracy. Using non-smooth parameters let the function follower() be non-differentiable. Therefore the stepsize controller of ODE45 can drive mad. You might get a final value, but there is a chance, that it is dominated by rounding errors.
- ODE45 rejects steps, if the error tolerance is not met. Then a step is repeated with a smaller step size. If this happens, your n is still increased.
- The number of elements in tspan does not mean, that the function to be integrated is called the same number of times. For one step of the integration, the function to be integrated is called multiple times. The step size is determined automatically controlled by the given tolerances. So the output it the steps of tspan should be created by an interpolation of the trajectory.
- n is provided as input argument. Then increaing n inside the function does not change the value outside the function magically. If this would be the case, programming would force the user to know all internally used variables of a function to avoid collisions.
You need a completely different design.
0 Comments
More Answers (1)
Walter Roberson
on 25 Feb 2022
The mathematics of the Runge-Kutta methods require that the function and two derivatives of the function are continuous. When you modify the parameters of the function on the fly, you make the function discontinuous. If you are lucky ode45 will notice and quit the function. If you are not lucky, ode45 will just return incorrect results.
Also, as Jan indicated, ode45() calls the function multiple times at each location. Typically it calls 6 times per at each location and proposed step size. If it decides that the change in function values is too large, it will reject the proposal and try again with a smaller step. No information is passed to the ode function about which sub-evaluation is being done, or about whether a step was rejected or not. ode45 and some of the other RK functions sometimes go backwards in time even without having rejected anything. (Also, the points that are actually output are generally interpolated: when it notices that it has successfully passed one of the times output is requested for, then it will interpolate the results for the requested time.)
So... Your approach is all wrong.
In your situation what might possibly work is to use interp1 to interpolate the value of the variable over time. However you need an interpolation of at least degree 3, such as spline: the default linear interpolation will not satisfy the continuity requirements.
2 Comments
Walter Roberson
on 25 Feb 2022
Also note that if your variable represents discrete events such as impulses or injection of chemicals, then you cannot use interpolation.
See Also
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!