diff scripts/ode/private/integrate_adaptive.m @ 20596:87b557ee8e5d

clean up and vectorize code for dense output in ode45 * scripts/ode/private/ode_rk_interpolate.m: new file * scripts/ode/private/ode_rk_interpolate.m(hermite_quartic_interpolation): move to internal function, use vectorization and broadcasting. * scripts/ode/private/hermite_quartic_interpolation.m: remove file * scripts/ode/module.mk: list added and removed files * scripts/ode/private/integrate_adaptive.m: use new interpolation code.
author Carlo de Falco <carlo.defalco@polimi.it>
date Tue, 06 Oct 2015 19:28:59 +0200
parents b7ac1e94266e
children a22d8a2eb0e5
line wrap: on
line diff
--- a/scripts/ode/private/integrate_adaptive.m	Tue Oct 06 00:20:02 2015 -0400
+++ b/scripts/ode/private/integrate_adaptive.m	Tue Oct 06 19:28:59 2015 +0200
@@ -1,3 +1,4 @@
+## Copyright (C) 2015, Carlo de Falco
 ## Copyright (C) 2013, Roberto Porcu' <roberto.porcu@polimi.it>
 ##
 ## This file is part of Octave.
@@ -147,8 +148,7 @@
     ## Solution accepted only if the error is less or equal to 1.0
     if (err <= 1)
       
-      [tk, comp] = kahan (tk, comp, dt);
-      options.comp = comp;
+      [tk, options.comp] = kahan (tk, options.comp, dt);
       s(end) = tk;
 
       ## values on this interval for time and solution
@@ -182,73 +182,12 @@
           while ((counter <= k)
                  && (vdirection * z(i) > vdirection * tspan(counter)))
             ## choose interpolation scheme according to order of the solver
-            switch (order)
-              case 1
-                u_interp = linear_interpolation ([z(i-1) z(i)],
-                                                 [u(:,i-1) u(:,i)],
-                                                 tspan(counter));
-              case 2
-                if (! isempty (k_vals))
-                  der = k_vals(:,1);
-                else
-                  der = feval (func, z(i-1) , u(:,i-1),
-                               options.vfunarguments{:});
-                endif
-                u_interp = quadratic_interpolation ([z(i-1) z(i)],
-                                                    [u(:,i-1) u(:,i)],
-                                                    der, tspan(counter));
-              case 3
-                u_interp = ...
-                hermite_cubic_interpolation ([z(i-1) z(i)],
-                                             [u(:,i-1) u(:,i)],
-                                             [k_vals(:,1) k_vals(:,end)],
-                                             tspan(counter));
-              case 4
-                ## if ode45 is used without local extrapolation this function
-                ## doesn't require a new function evaluation.
-                u_interp = dorpri_interpolation ([z(i-1) z(i)],
-                                                 [u(:,i-1) u(:,i)],
-                                                 k_vals, tspan(counter));
-              case 5
-                ## ode45 with Dormand-Prince scheme:
-                ## 4th order approximation of y in t+dt/2 as proposed by
-                ## Shampine in Lawrence, Shampine, "Some Practical
-                ## Runge-Kutta Formulas", 1986.
-                u_half = u(:,i-1) ...
-                         + 1/2*dt*((6025192743/30085553152) * k_vals(:,1)
-                                   + (51252292925/65400821598) * k_vals(:,3)
-                                   - (2691868925/45128329728) * k_vals(:,4)
-                                   + (187940372067/1594534317056) * k_vals(:,5)
-                                   - (1776094331/19743644256) * k_vals(:,6)
-                                   + (11237099/235043384) * k_vals(:,7));
-                u_interp = ...
-                hermite_quartic_interpolation ([z(i-1) z(i)],
-                                               [u(:,i-1) u_half u(:,i)],
-                                               [k_vals(:,1) k_vals(:,end)],
-                                               tspan(counter));
 
-                ## it is also possible to do a new function evaluation and use
-                ## the quintic hermite interpolator
-                ## f_half = feval (func, t+1/2*dt, u_half,
-                ##                 options.vfunarguments{:});
-                ## u_interp =
-                ##   hermite_quintic_interpolation ([z(i-1) z(i)],
-                ##                                  [u(:,i-1) u_half u(:,i)],
-                ##                                  [k_vals(:,1) f_half ...
-                ##                                   k_vals(:,end)],
-                ##                                  tspan(counter));
-              otherwise
-                warning ("High order interpolation not yet implemented: ",
-                         "using cubic interpolation instead");
-                der(:,1) = feval (func, z(i-1) , u(:,i-1),
-                                  options.vfunarguments{:});
-                der(:,2) = feval (func, z(i) , u(:,i),
-                                  options.vfunarguments{:});
-                u_interp = ...
-                hermite_cubic_interpolation ([z(i-1) z(i)],
-                                             [u(:,i-1) u(:,i)],
-                                             der, tspan(counter));
-            endswitch
+            u_interp = ...
+            ode_rk_interpolate (order, [z(i-1) z(i)], [u(:,i-1) u(:,i)],
+                                tspan(counter), k_vals, dt,
+                                options.vfunarguments{:});
+            
 
             ## add the interpolated value of the solution
             u = [u(:,1:i-1), u_interp, u(:,i:end)];