{"id":983,"date":"2014-05-26T12:00:51","date_gmt":"2014-05-26T17:00:51","guid":{"rendered":"https:\/\/blogs.mathworks.com\/cleve\/?p=983"},"modified":"2014-05-06T16:04:36","modified_gmt":"2014-05-06T21:04:36","slug":"ordinary-differential-equation-solvers-ode23-and-ode45","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/cleve\/2014\/05\/26\/ordinary-differential-equation-solvers-ode23-and-ode45\/","title":{"rendered":"Ordinary Differential Equation Solvers ODE23 and ODE45"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>The functions <tt>ode23<\/tt> and <tt>ode45<\/tt> are the principal MATLAB and Simulink tools for solving nonstiff ordinary differential equations.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#2db405f6-16f7-4292-9eae-10a0ae17cba6\">Single Step Methods<\/a><\/li><li><a href=\"#bb31cd19-1926-421d-9888-4ff43f510746\">ODE23<\/a><\/li><li><a href=\"#5e7907df-c9c7-48fc-8063-3a7c771cfee4\">Error Estimate<\/a><\/li><li><a href=\"#49872c4d-f31e-4df1-9ef6-76d13c308dd1\">Interpolant<\/a><\/li><li><a href=\"#7ec09e2f-f6e3-48c0-aab8-da2dc31f32c9\">Runge-Kutta-Fehlberg<\/a><\/li><li><a href=\"#a495083d-5d4a-4fac-afbc-768444430751\">ODE45<\/a><\/li><li><a href=\"#e82149a3-1a80-4233-93af-914a0c279b14\">Comparison<\/a><\/li><\/ul><\/div><h4>Single Step Methods<a name=\"2db405f6-16f7-4292-9eae-10a0ae17cba6\"><\/a><\/h4><p>The two functions <tt>ode23<\/tt> and <tt>ode45<\/tt> are single step ODE solvers.  They are also known as Runge-Kutta methods.  Each step is almost independent of the previous steps.  Two important pieces of information are passed from one step to the next.  The step size $h$ expected to achieve a desired accuracy is passed from step to step.  And, in a strategy known as FSAL, for First Same as Last, the final function value at the end of a successful step is used at the initial function value at the following step.<\/p><h4>ODE23<a name=\"bb31cd19-1926-421d-9888-4ff43f510746\"><\/a><\/h4><p>The BS23 algorithm is due to Larry Shampine and his student Przemyslaw Bogacki.  Przemyslaw is now a Professor at Old Dominion University. The \" <i>23<\/i> \" in the function name indicates that two simultaneous single-step formulas, one of second order and one of third order, are involved.<\/p><p>The method has three stages, but there are four slopes $s_i$ because, after the first step, the $s_1$ for one step is the $s_4$ from the previous step.  The essentials are<\/p><p>$$ s_1 = f(t_n,y_n) $$<\/p><p>$$ s_2 = f\\left(t_n+{h \\over 2},y_n+{h \\over 2} s_1\\right) $$<\/p><p>$$ s_3 = f\\left(t_n+{3 \\over 4} h, y_n+{3 \\over 4} h s_2\\right) $$<\/p><p>$$ t_{n+1} = t_n + h $$<\/p><p>$$ y_{n+1} = y_n + {h \\over 9} (2 s_1  + 3 s_2 + 4 s_3) $$<\/p><p>$$ s_4 = f(t_{n+1},y_{n+1}) $$<\/p><p>$$ e_{n+1} = {h \\over 72} (-5 s_1 + 6 s_2 + 8 s_3 - 9 s_4) $$<\/p><p>Here is a graphical view of the steps.<\/p><pre class=\"codeinput\">   ode23steps\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/cleve\/odes_2345_01.png\" alt=\"\"> <p>These graphics show the starting situation and the three stages. We start at a point $(t_n,y_n)$ with an initial slope $s_1 = f(t_n,y_n)$ and an estimate of a good step size, $h$. Our goal is to compute an approximate solution $y_{n+1}$ at $t_{n+1} = t_n+h$ that agrees with the true solution $y(t_{n+1})$ to within the specified tolerances.<\/p><p>The first stage uses the initial slope $s_1$ to take an Euler step halfway across the interval.  The function is evaluated there to get the second slope, $s_2$.  This slope is used to take an Euler step three-quarters of the way across the interval.  The function is evaluated again to get the third slope, $s_3$.  A weighted average of the three slopes is used to step all the way across the interval to get a tentative value for $y_{n+1}$.<\/p><p>$$ s = {1 \\over 9} (2 s_1  + 3 s_2 + 4 s_3) $$<\/p><p>The function is evaluated once more to get $s_4$. The error estimate then uses all four slopes.<\/p><p>$$ e_{n+1} = {h \\over 72} (-5 s_1 + 6 s_2 + 8 s_3 - 9 s_4) $$<\/p><p>If the error is within the specified tolerance, the step is successful, the tentative value of $y_{n+1}$ is accepted, and $s_4$ becomes the $s_1$ of the next step.  If the error is too large, then the tentative $y_{n+1}$ is rejected and the step must be redone. In either case, the error estimate $e_{n+1}$ provides the basis for determining the step size $h$ for the next step.<\/p><p>Notice that $y_{n+1}$ is computed before $s_4$.  The final function evaluation is used for the error estimate, but not for the step itself. But this $s_4$ is the $s_1$ in the next step.<\/p><h4>Error Estimate<a name=\"5e7907df-c9c7-48fc-8063-3a7c771cfee4\"><\/a><\/h4><p>The coefficients in the error estimate $e_{n+1}$ result from the difference between the third order formula that is used to compute $y_{n+1}$ and an independent second order formula that involves the same function values. That second order result is not actually computed because its value is not needed.<\/p><h4>Interpolant<a name=\"49872c4d-f31e-4df1-9ef6-76d13c308dd1\"><\/a><\/h4><p>All the solvers in the suite provide an interpolant that can generate values approximating the solution to the differential equation to the desired accuracy anywhere in the interval without requiring further evaluation of the function defining the ode.  In the case of <tt>ode23<\/tt> this interpolant happens to be \"free\".  In turns out that the Hermite cubic polynomial defined by the four values<\/p><p>$$ y_n, \\ F(t_n,y_n), \\ y_{n+1}, \\ F(t_{n+1}, \\ y_{n+1}) $$<\/p><p>does the job.  For other solvers in the suite, providing the accompanying interpolant is an important aspect of the algorithm derivation.<\/p><h4>Runge-Kutta-Fehlberg<a name=\"7ec09e2f-f6e3-48c0-aab8-da2dc31f32c9\"><\/a><\/h4><p>Before today's version of <tt>ode45<\/tt>, there was an earlier one. In a 1969 NASA report, Erwin Fehlberg introduced a so-called six stage Runge-Kutta method that requires six function evaluations per step. These function values can be combined with one set of coefficients to produce a fifth-order accurate approximation and with another set of coefficients to produce an independent fourth-order accurate approximation. Comparing these two approximations provides an error estimate and resulting step size control.<\/p><p>Notice that it takes six stages to get fifth order.  It is not possible to get fifth order with only five function evaluations per step. The combinatorial complexity of the Taylor series in two variables for $F(t,y)$ overpowers the information available from the function evaluations.  In fact, if you continue to investigate the development of Runge-Kutta methods, you will find that, for example, with ten stages it is only possible to achieve seventh order.<\/p><p>In the early 1970's Shampine and his colleague H. A. (Buddy) Watts at Sandia Laboratories published a Fortran code, RKF45, based on Fehlberg's algorithm.  In 1977, we made RKF45 the ODE solver in our text book <i>Computer Methods for Mathematical Computations<\/i>, by Forsythe, Malcolm and Moler. This book is now out of print so I can't provide a decent link to it. But the <a href=\"http:\/\/www.netlib.no\/netlib\/fmm\/rkf45.f\">Fortran source code<\/a> for RKF45 is still available from netlib.<\/p><p>One thing that I will always remember about RKF45 is ${12 \\over 13}$ The fourth function evaluation, $s_4$, is made at the point<\/p><p>$$ t_n + {12 \\over 13} h $$<\/p><p>I doubt that you will ever come across ${12 \\over 13}$ anyplace else in mathematical software.<\/p><p>RKF45 became the basis for the first version of ODE45 in MATLAB in the early 1980s and for early versions of Simulink.  The Felhberg (4,5) pair did a terrific job for almost fifteen years until the late 1990s when Shampine and MathWorker Mark Reichelt modernized the suite and introduced a more efficient algorithm.<\/p><h4>ODE45<a name=\"a495083d-5d4a-4fac-afbc-768444430751\"><\/a><\/h4><p>The new <tt>ode45<\/tt> introduced in the late 1990s is based on an algorithm of Dormand and Prince.  It uses six stages, employs the FSAL strategy, provides fourth and fifth order formulas, has local extrapolation and a companion interpolant.<\/p><p>The new <tt>ode45<\/tt> is so effective that it is the only function in the suite where the default value of the <tt>refine<\/tt> argument is set to 4.  This means that the step size the algorithm naturally wants to choose is so large that the output is more widely spaced than most people prefer.  So the interpolant is called up to produce more finely spaced output at no additional cost measured in function evaluations.<\/p><p>The codes for the two routines <tt>ode23<\/tt> and <tt>ode45<\/tt> are very similar. The most important place they differ is the portion that sets the key parameters.  Here are the parameters in <tt>ode23<\/tt>.<\/p><pre class=\"codeinput\">   dbtype <span class=\"string\">200:209<\/span> <span class=\"string\">ode23<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\n200   % Initialize method parameters.\r\n201   pow = 1\/3;\r\n202   A = [1\/2, 3\/4, 1];\r\n203   B = [\r\n204       1\/2         0               2\/9\r\n205       0           3\/4             1\/3\r\n206       0           0               4\/9\r\n207       0           0               0\r\n208       ]; \r\n209   E = [-5\/72; 1\/12; 1\/9; -1\/8];\r\n<\/pre><p>The parameter <tt>pow<\/tt> is used in the step size calculation. We see that <tt>ode23<\/tt> is a third order method.  The array <tt>A<\/tt> gives the fractions for each partial step. The array <tt>B<\/tt> provides the weights for the slopes. And the array <tt>E<\/tt> provides the coefficients in the error estimate. Here are the corresponding parameters for the Dormand-Prince algorithm used in <tt>ode45<\/tt>.<\/p><pre class=\"codeinput\">   dbtype <span class=\"string\">201:213<\/span> <span class=\"string\">ode45<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\n201   % Initialize method parameters.\r\n202   pow = 1\/5;\r\n203   A = [1\/5, 3\/10, 4\/5, 8\/9, 1, 1];\r\n204   B = [\r\n205       1\/5         3\/40    44\/45   19372\/6561      9017\/3168       35\/384\r\n206       0           9\/40    -56\/15  -25360\/2187     -355\/33         0\r\n207       0           0       32\/9    64448\/6561      46732\/5247      500\/1113\r\n208       0           0       0       -212\/729        49\/176          125\/192\r\n209       0           0       0       0               -5103\/18656     -2187\/6784\r\n210       0           0       0       0               0               11\/84\r\n211       0           0       0       0               0               0\r\n212       ];\r\n213   E = [71\/57600; 0; -71\/16695; 71\/1920; -17253\/339200; 22\/525; -1\/40];\r\n<\/pre><h4>Comparison<a name=\"e82149a3-1a80-4233-93af-914a0c279b14\"><\/a><\/h4><p><tt>ode23<\/tt> is a three-stage, third-order, Runge-Kutta method. <tt>ode45<\/tt> is a six-stage, fifth-order, Runge-Kutta method. <tt>ode45<\/tt> does more work per step than <tt>ode23<\/tt>, but can take much larger steps. For differential equations with smooth solutions, <tt>ode45<\/tt> is often more accurate than <tt>ode23<\/tt>.  In fact, it may be so accurate that the interpolant is required to provide the desired resolution.  That's a good thing.<\/p><p><tt>ode45<\/tt> is the anchor of the differential equation suite. The MATLAB documentation recommends <tt>ode45<\/tt> as the first choice. And Simulink blocks set <tt>ode45<\/tt> as the default solver. But I have a fondness for <tt>ode23<\/tt>.  I like its simplicity. I particularly like it for graphics.  The natural step size that <tt>ode23<\/tt> chooses is frequently just right for display purposes. For example, the plot of the Lorenz chaotic attractor at the end of my previous post is done with <tt>ode23<\/tt> choosing the step size.<\/p><p>So give <tt>ode23<\/tt> a try.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_b5e010e97cc742e0bf3a6620a196e280() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='b5e010e97cc742e0bf3a6620a196e280 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' b5e010e97cc742e0bf3a6620a196e280';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2014 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_b5e010e97cc742e0bf3a6620a196e280()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2014a<br><\/p><\/div><!--\r\nb5e010e97cc742e0bf3a6620a196e280 ##### SOURCE BEGIN #####\r\n%% Ordinary Differential Equation Solvers ODE23 and ODE45\r\n% The functions |ode23| and |ode45| are the principal MATLAB and Simulink\r\n% tools for solving nonstiff ordinary differential equations.\r\n\r\n%% Single Step Methods\r\n% The two functions |ode23| and |ode45| are single step ODE solvers.  They\r\n% are also known as Runge-Kutta methods.  Each step is almost independent\r\n% of the previous steps.  Two important pieces of information are passed\r\n% from one step to the next.  The step size $h$ expected to achieve a desired\r\n% accuracy is passed from step to step.  And, in a strategy known as FSAL,\r\n% for First Same as Last, the final function value at the end of a successful\r\n% step is used at the initial function value at the following step.\r\n\r\n%% ODE23 \r\n% The BS23 algorithm is due to Larry Shampine and his student Przemyslaw\r\n% Bogacki.  Przemyslaw is now a Professor at Old Dominion University.\r\n% The \" _23_ \" in the function name indicates that two simultaneous\r\n% single-step formulas, one of second order and one of\r\n% third order, are involved.\r\n% \r\n% The method has three stages, but there are four slopes $s_i$ because,\r\n% after the first step, the $s_1$ for one step is the $s_4$ from the previous\r\n% step.  The essentials are\r\n% \r\n% $$ s_1 = f(t_n,y_n) $$\r\n%\r\n% $$ s_2 = f\\left(t_n+{h \\over 2},y_n+{h \\over 2} s_1\\right) $$\r\n%\r\n% $$ s_3 = f\\left(t_n+{3 \\over 4} h, y_n+{3 \\over 4} h s_2\\right) $$\r\n%\r\n% $$ t_{n+1} = t_n + h $$\r\n%\r\n% $$ y_{n+1} = y_n + {h \\over 9} (2 s_1  + 3 s_2 + 4 s_3) $$\r\n%\r\n% $$ s_4 = f(t_{n+1},y_{n+1}) $$\r\n%\r\n% $$ e_{n+1} = {h \\over 72} (-5 s_1 + 6 s_2 + 8 s_3 - 9 s_4) $$\r\n\r\n%%\r\n% Here is a graphical view of the steps.\r\n\r\n   ode23steps\r\n\r\n%% \r\n% These graphics show the starting situation and the three stages.\r\n% We start at a point $(t_n,y_n)$ with an initial slope\r\n% $s_1 = f(t_n,y_n)$ and an estimate of a good step size, $h$.\r\n% Our goal is to compute an approximate solution $y_{n+1}$ at\r\n% $t_{n+1} = t_n+h$ that agrees with the true solution\r\n% $y(t_{n+1})$ to within the specified tolerances.\r\n% \r\n% The first stage uses the initial slope $s_1$ to take an Euler step\r\n% halfway across the interval.  The function is evaluated there to get\r\n% the second slope, $s_2$.  This slope is used to take an Euler step\r\n% three-quarters of the way across the interval.  The function is\r\n% evaluated again to get the third slope, $s_3$.  A weighted average of\r\n% the three slopes is used to step all the way across the interval to get\r\n% a tentative value for $y_{n+1}$.\r\n% \r\n% $$ s = {1 \\over 9} (2 s_1  + 3 s_2 + 4 s_3) $$\r\n% \r\n% The function is evaluated once more to get $s_4$.\r\n% The error estimate then uses all four slopes.\r\n% \r\n% $$ e_{n+1} = {h \\over 72} (-5 s_1 + 6 s_2 + 8 s_3 - 9 s_4) $$\r\n% \r\n% If the error is within the specified tolerance, the step\r\n% is successful, the tentative value of $y_{n+1}$ is accepted, and\r\n% $s_4$ becomes the $s_1$ of the next step.  If the error is too large,\r\n% then the tentative $y_{n+1}$ is rejected and the step must be redone.\r\n% In either case, the error estimate $e_{n+1}$ provides the basis\r\n% for determining the step size $h$ for the next step.\r\n\r\n%%\r\n% Notice that $y_{n+1}$ is computed before $s_4$.  The final function\r\n% evaluation is used for the error estimate, but not for the step itself.\r\n% But this $s_4$ is the $s_1$ in the next step.\r\n\r\n%% Error Estimate\r\n% The coefficients in the error estimate $e_{n+1}$ result from the difference\r\n% between the third order formula that is used to compute $y_{n+1}$ and an\r\n% independent second order formula that involves the same function values.\r\n% That second order result is not actually computed because its value is\r\n% not needed.\r\n\r\n%% Interpolant\r\n% All the solvers in the suite provide an interpolant that can generate values\r\n% approximating the solution to the differential equation to the desired\r\n% accuracy anywhere in the interval without requiring further evaluation\r\n% of the function defining the ode.  In the case of |ode23| this interpolant\r\n% happens to be \"free\".  In turns out that the Hermite cubic polynomial\r\n% defined by the four values\r\n%\r\n% $$ y_n, \\ F(t_n,y_n), \\ y_{n+1}, \\ F(t_{n+1}, \\ y_{n+1}) $$\r\n%\r\n% does the job.  For other solvers in the suite, providing the accompanying\r\n% interpolant is an important aspect of the algorithm derivation.\r\n\r\n%% Runge-Kutta-Fehlberg\r\n% Before today's version of |ode45|, there was an earlier one.\r\n% In a 1969 NASA report, Erwin Fehlberg introduced a so-called six stage\r\n% Runge-Kutta method that requires six function evaluations per step.\r\n% These function values can be combined with one set of coefficients to\r\n% produce a fifth-order accurate approximation and with another set of \r\n% coefficients to produce an independent fourth-order accurate approximation.\r\n% Comparing these two approximations provides an error estimate and\r\n% resulting step size control. \r\n\r\n%%\r\n% Notice that it takes six stages to get fifth order.  It is not possible\r\n% to get fifth order with only five function evaluations per step.\r\n% The combinatorial complexity of the Taylor series in two variables\r\n% for $F(t,y)$ overpowers the information available from the function \r\n% evaluations.  In fact, if you continue to investigate the development of\r\n% Runge-Kutta methods, you will find that, for example, with ten stages it is\r\n% only possible to achieve seventh order.\r\n\r\n%%\r\n% In the early 1970's Shampine and his colleague H. A. (Buddy) Watts at\r\n% Sandia Laboratories published a Fortran code, RKF45, based on Fehlberg's\r\n% algorithm.  In 1977, we made RKF45 the ODE solver in our text book\r\n% _Computer Methods for Mathematical Computations_, by Forsythe, Malcolm and\r\n% Moler. This book is now out of print so I can't provide a decent link to it.\r\n% But the <http:\/\/www.netlib.no\/netlib\/fmm\/rkf45.f Fortran source code>\r\n% for RKF45 is still available from netlib.\r\n\r\n%%\r\n% One thing that I will always remember about RKF45 is ${12 \\over 13}$\r\n% The fourth function evaluation, $s_4$, is made at the point\r\n%\r\n% $$ t_n + {12 \\over 13} h $$\r\n%\r\n% I doubt that you will ever come across ${12 \\over 13}$ anyplace else in\r\n% mathematical software.\r\n\r\n%%\r\n% RKF45 became the basis for the first version of ODE45 in MATLAB in the\r\n% early 1980s and for early versions of Simulink.  The Felhberg (4,5)\r\n% pair did a terrific job for almost fifteen years until the late 1990s when\r\n% Shampine and MathWorker Mark Reichelt modernized the suite and introduced\r\n% a more efficient algorithm.\r\n\r\n%% ODE45\r\n% The new |ode45| introduced in the late 1990s is based on an algorithm of\r\n% Dormand and Prince.  It uses six stages, employs the FSAL strategy, provides\r\n% fourth and fifth order formulas, has local extrapolation and a companion\r\n% interpolant.\r\n\r\n%%\r\n% The new |ode45| is so effective that it is the only function in the suite\r\n% where the default value of the |refine| argument is set to 4.  This means\r\n% that the step size the algorithm naturally wants to choose is so large that\r\n% the output is more widely spaced than most people prefer.  So the interpolant\r\n% is called up to produce more finely spaced output at no additional cost\r\n% measured in function evaluations.\r\n\r\n%%\r\n% The codes for the two routines |ode23| and |ode45| are very similar.\r\n% The most important place they differ is the portion that sets the key\r\n% parameters.  Here are the parameters in |ode23|.\r\n\r\n   dbtype 200:209 ode23\r\n\r\n%%\r\n% The parameter |pow| is used in the step size calculation. We see that\r\n% |ode23| is a third order method.  The array |A| gives the fractions for\r\n% each partial step. The array |B| provides the weights for the slopes. \r\n% And the array |E| provides the coefficients in the error estimate.\r\n% Here are the corresponding parameters for the Dormand-Prince algorithm\r\n% used in |ode45|.\r\n%%\r\n\r\n   dbtype 201:213 ode45\r\n\r\n%% Comparison\r\n% |ode23| is a three-stage, third-order, Runge-Kutta method. \r\n% |ode45| is a six-stage, fifth-order, Runge-Kutta method. \r\n% |ode45| does more work per step than |ode23|, but can take much larger steps.\r\n% For differential equations with smooth solutions, |ode45| is often more\r\n% accurate than |ode23|.  In fact, it may be so accurate that the interpolant\r\n% is required to provide the desired resolution.  That's a good thing.\r\n\r\n%%\r\n% |ode45| is the anchor of the differential equation suite.\r\n% The MATLAB documentation recommends |ode45| as the first choice.\r\n% And Simulink blocks set |ode45| as the default solver.\r\n% But I have a fondness for |ode23|.  I like its simplicity.\r\n% I particularly like it for graphics.  The natural step size that |ode23|\r\n% chooses is frequently just right for display purposes.\r\n% For example, the plot of the Lorenz chaotic attractor at the end of my\r\n% previous post is done with |ode23| choosing the step size.\r\n\r\n%%\r\n% So give |ode23| a try.\r\n\r\n##### SOURCE END ##### b5e010e97cc742e0bf3a6620a196e280\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/cleve\/odes_2345_01.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p>The functions <tt>ode23<\/tt> and <tt>ode45<\/tt> are the principal MATLAB and Simulink tools for solving nonstiff ordinary differential equations.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/cleve\/2014\/05\/26\/ordinary-differential-equation-solvers-ode23-and-ode45\/\">read more >><\/a><\/p>","protected":false},"author":78,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[24,16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/983"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/users\/78"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/comments?post=983"}],"version-history":[{"count":5,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/983\/revisions"}],"predecessor-version":[{"id":989,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/983\/revisions\/989"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media?parent=983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/categories?post=983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/tags?post=983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}