I have a system of ODE's. The ODE takes a couple of seconds to run in a particular parameter range. For another parameter range, however, MATLAB suddenly takes an infinite amount of time to run (well, ok, only tested to half a day).
This is a complex, multiply coupled ODE with hyperbolic functions; solving it analytically is impossible, solving it numerically would be a master's thesis, so I'm looking for a computational solution. I need to throw out such parameters and move to the next (random) set of parameters.
How would I debug or catch this semantic error in MATLAB? I'm just not sure what odesolver doesn't like about it. So far, I've used profiler to narrow it down to these lines in odesolver:
f(:,2) = feval(odeFcn,t+hA(1),y+f*hB(:,1),odeArgs{:});
f(:,3) = feval(odeFcn,t+hA(2),y+f*hB(:,2),odeArgs{:});
f(:,4) = feval(odeFcn,t+hA(3),y+f*hB(:,3),odeArgs{:});
f(:,5) = feval(odeFcn,t+hA(4),y+f*hB(:,4),odeArgs{:});
f(:,6) = feval(odeFcn,t+hA(5),y+f*hB(:,5),odeArgs{:});\
(which is essentially the core solver method). Obviously the source of the error is my choice of parameters, but profiler does not show any noticeable time taken up by my function (I pass a script function of the ODE as an anonymous function to ode45).
Related
I tried to use ode45 to solve an equation, and get output like the following. I get the idea it is trying to estimate using nearby points (as explained here https://www.mathworks.com/videos/solving-odes-in-matlab-6-ode45-117537.html). By my understanding, it should solve the equation in one round of computation? but the output looks like ode45 is an iterative algorithm (so that it generates output that repeat the '... steps ... failed attempt ... function evaluations' over and over again)? If it is iterative, could you help give some detail or references? Thanks!
ode45 is an iterative adaptive ODE solver. That is, it uses a 5th order (FSAL) method to propose the an update using some stepsize h. Then it does the same again, but now with a 4th order method, then it compared those two updates to one another, if the difference is less than some local tolerance, it accepts the proposed update. If the difference is larger than some local tolerance, the update is rejected and the stepsize is lowered (in some smart way).
To reduce the cost of using both a 4th and 5th order method, those two methods uses (roughly) the same function evaluations.
As for your output, it is, as also noted by #LutzL, not the standard output, which might point to an error in your code.
In my model each agent solves a system of ODEs at each tick. I have employed Eulers method (similar to the systems dynamics modeler in NetLogo) to solve these first order ODEs. However, for a stable solution, I am forced to use a very small time step (dt), which means the simulation proceeds very slowly with this method. I´m curious if anyone has advice on a method to solve the ODEs more quickly? I am considering implementing Runge-Kutta (with a larger time step?) as was done here (http://academic.evergreen.edu/m/mcavityd/netlogo/Bouncing_Ball.html). I would also consider using the R extension and using an ODE solver in R. But again, the ODEs are solved by each agent, so I don´t know if this is an efficient method.
I´m hoping someone has a feel for the performance of these methods and could offer some advice. If not, I will try to share what I find out.
In general your idea is correct. For a method of order p to reach a global error level tol over an integration interval of length T you will need a step size in the magnitude range
h=pow(tol/T,1.0/p).
However, not only the discretization error accumulates over the N=T/h steps, but also the floating point error. This gives a lower bound for useful step sizes of magnitude h=pow(T*mu,1.0/(p+1)).
Example: For T=1, mu=1e-15 and tol=1e-6
the Euler method of order 1 would need a step size of about h=1e-6 and thus N=1e+6 steps and function evaluations. The range of step sizes where reasonable results can be expected is bounded below by h=3e-8.
the improved Euler or Heun method has order 2, which implies a step size 1e-3, N=1000 steps and 2N=2000 function evaluations, the lower bound for useful step sizes is 1e-3.
the classical Runge-Kutta method has order 4, which gives a required step size of about h=3e-2 with about N=30 steps and 4N=120 function evaluations. The lower bound is 1e-3.
So there is a significant gain to be had by using higher order methods. At the same time the range where step size reduction results in a lower global error also gets significantly narrower for increasing order. But at the same time the achievable accuracy increases. So one has to knowingly care when the point is reached to leave well enough alone.
The implementation of RK4 in the ball example, as in general for the numerical integration of ODE, is for an ODE system x'=f(t,x), where x is the, possibly very large, state vector
A second order ODE (system) is transformed to a first order system by making the velocities members of the state vector. x''=a(x,x') gets transformed to [x',v']=[v, a(x,v)]. The big vector of the agent system is then composed of the collection of the pairs [x,v] or, if desired, as the concatenation of the collection of all x components and the collection of all v components.
In an agent based system it is reasonable to store the components of the state vector belonging to the agent as internal variables of the agent. Then the vector operations are performed by iterating over the agent collection and computing the operation tailored to the internal variables.
Taking into consideration that in the LOGO language there are no explicit parameters for function calls, the evaluation of dotx = f(t,x) needs to first fix the correct values of t and x before calling the function evaluation of f
save t0=t, x0=x
evaluate k1 = f_of_t_x
set t=t0+h/2, x=x0+h/2*k1
evaluate k2=f_of_t_x
set x=x0+h/2*k2
evaluate k3=f_of_t_x
set t=t+h, x=x0+h*k3
evaluate k4=f_of_t_x
set x=x0+h/6*(k1+2*(k2+k3)+k4)
I made a design in simulink to implement PID using embedded matlab function.
My function is :
function [u,integral,previous_error] = fcn(Kp,Td,Ti,error,previous_error1,integral1)
dt = 1;
Ki= Kp/Ti;
Kd=Kp*Td;
integral = integral1 + error*dt; % integral term
derivative = (error-previous_error1)/dt; % derivative term
u = Kp*error+Ki*integral+Kd*derivative; % action of control
previous_error=error;
%integral=integral;
end
This is how my model looks:(a part of the entire model)
I am getting the following error :
Simulink cannot solve the algebraic loop containing 'pid_block1/MATLAB Function' at time 2.2250754336053813E-8 using the TrustRegion-based algorithm due to one of the following reasons: the model is ill-defined i.e., the system equations do not have a solution; or the nonlinear equation solver failed to converge due to numerical issues.
To rule out solver convergence as the cause of this error, either
a) switch to LineSearch-based algorithm using
set_param('pid_block1','AlgebraicLoopSolver','LineSearch')
b) reducing the ode45 solver RelTol parameter so that the solver takes smaller time steps.
If the error persists in spite of the above changes, then the model is likely ill-defined and requires modification.
Any idea, why am I getting it?
Should i use global variables for integral and previous_error here?
Thanks in advance.
Erm.. Unless there is a specific reason why you need it in this form, I would strongly recommend replacing your MATLAB Function block with Simulink blocks such as:
Gain blocks for Kp, KI, and KD
Sum blocks for all addition and subtraction
Derivative block for derivative
Integrator block for integration
etc....
I've found that Algebraic loop problems are really hard to get rid of and are usually just best to avoid. The method I suggest above can be used for most any controller type and has worked quite nicely for me in the past.
If the issue is neatness, you can always create your own "PID controller" subsystem or library part.
Let me know if you need some more detail or a diagram on how you might do this.
I have a Simulink model that includes the following subsystem.
The bm_train_adapter block will call a MATLAB function of the same name, passing all the input arguments in a single vector.
The subsystem has been given a sample time of 900 (secs), which is why all the signals are colored in red (for discrete signals).
However, in the debugger I have observed that the bm_train_adapter function gets called twice at each simulation timestep. This yields horribly wrong results since the function includes side-effects.
Why is Simulink calling my interpreted MATLAB function more than once per timestep? How can I prevent this?
I think this is because of your solver setup. In your Configuration Parameters window, check out the Solver Options pane.
I believe the discrete and ode1 solvers will call once per timestep. ode2 will call twice per timestep, ode4 will call 4 times per timestep, etc.
This behavior is very helpful for simulating continuous dynamics, but it can be confusing when interacting with discrete elements.
The reason was that my model had algebraic loops caused by unit delay blocks in subsystems. To solve these loops, the solver had no choice but to evaluate some blocks more than once.
The solution was to move out all unit delays from their subsystems.
I am trying to run my simulink file which have pid controller connected to s-function block.
When i set three values parameters of pid which are proportional, integral and derivatives it takes too long to run the whole process. Why this is happened?
In the dialog box of my pid diagram, for porportional value, its equal to the value which correspond to the constant amplitude oscillation.
Then for integral, its equal to Kcu/Ti. Ti is the ultimate period(Pu)/2 and
lastly for derivatives, its equal tu Kcu*Td and Td is Pu /8. This is refer to ziegler nichols method. and again my question is why it takes too long to running this file?
MATLAB S-functions are slow because they run in the MATLAB interpreter. Consider implementing it using Simulink blocks or using a "Embedded MATLAB Function" (pre-R2011a) or "MATLAB Function" (R2011a+) block.
Read Guy and Seth's thoughts on Simulation performance.
#Nzbuu is right about the Matlab S-functions.
But I think the problem here could be somewhere else: #Syarina are you saying that the Simulink simulation gets slower after you set the proportional coefficient for the controller? If you simulate the plant alone, in this case the S-function, do you notice a significant difference in the execution speed? If it is really so, I suppose the PID controller makes the ODE system stiff. This means that the different states of the ODE system have really different dynamics - some are very fast, some are very slow. Using an ode-solver that is not suited for stiff equations you will find the simulation much slower (actually you would have luck if it converges at all).
My suggestion is try to change the solver - for example ode15s.