changeset 22638:0128795eeac6 stable

odeplot.m: Recode for performance. * odeplot.m: Rename output argument to "retval". Rename Van der Pol function to fvdp. Remove unused varargin from function prototype. Move most common case to be first in if/elseif tree. Remove call to plot and instead just update the "xdata", "ydata" properties of line objects. Use a filled marker, '.', rather than unfilled marker 'o'. Clean up by setting variables to empty matrix rather than using clear function.
author Rik <rik@octave.org>
date Mon, 17 Oct 2016 14:03:45 -0700
parents c44d57c0a925
children 7efa2d0e22c9
files scripts/ode/odeplot.m
diffstat 1 files changed, 34 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ode/odeplot.m	Mon Oct 17 16:24:55 2016 -0400
+++ b/scripts/ode/odeplot.m	Mon Oct 17 14:03:45 2016 -0700
@@ -19,7 +19,7 @@
 ## Author: Thomas Treichl <treichl@users.sourceforge.net>
 
 ## -*- texinfo -*-
-## @deftypefn {} {@var{ret} =} odeplot (@var{t}, @var{y}, @var{flag})
+## @deftypefn {} {@var{retval} =} odeplot (@var{t}, @var{y}, @var{flag})
 ##
 ## Open a new figure window and plot input @var{y} over time during the
 ## solving of an ode problem.
@@ -54,45 +54,50 @@
 ##
 ## @example
 ## @group
-## fvdb = @@(t,y) [y(2); (1 - y(1)^2) * y(2) - y(1)];
+## fvdp = @@(t,y) [y(2); (1 - y(1)^2) * y(2) - y(1)];
 ##
 ## opt = odeset ("OutputFcn", @@odeplot, "RelTol", 1e-6);
-## sol = ode45 (fvdb, [0 20], [2 0], opt);
+## sol = ode45 (fvdp, [0 20], [2 0], opt);
 ## @end group
 ## @end example
 ##
 ## @seealso{odeset, odeget}
 ## @end deftypefn
 
-function ret = odeplot (t, y, flag, varargin)
+function retval = odeplot (t, y, flag)
 
-  ## No input argument check is done for a higher processing speed
-  persistent fig told yold counter;
+  ## No input argument checking is done for better performance
+  persistent hlines num_lines told yold;
+  persistent idx = 1;   # Don't remove.  Required for Octave parser.
 
-  if (strcmp (flag, "init"))
-    ## Nothing to return, t is either the time slot [tstart tstop]
-    ## or [t0, t1, ..., tn], y is the initial value vector "init"
-    counter = 1;
-    fig = figure ();
+  if (isempty (flag))
+    ## Default case, plot and return a value
+    ## FALSE for "not stopping the integration"
+    ## TRUE  for "stopping the integration"
+    idx += 1;
+    told(idx,1) = t(1,1);
+    yold(:,idx) = y(:,1);
+    for i = 1:num_lines
+      set (hlines(i), "xdata", told, "ydata", yold(i,:));
+    endfor
+    drawnow;
+
+    retval = false;
+
+  elseif (strcmp (flag, "init"))
+    ## Nothing to return
+    ## t is either the time slot [tstart tstop] or [t0, t1, ..., tn]
+    ## y is the initial value vector "init"
+    idx = 1;
     told = t(1,1);
     yold = y(:,1);
-
-  elseif (isempty (flag))
-    ## Return something, either false for "not stopping
-    ## the integration" or true for "stopping the integration"
-    counter += 1;
-    figure (fig);
-    told(counter,1) = t(1,1);
-    yold(:,counter) = y(:,1);
-    ## FIXME: Why not use '.' rather than 'o' and skip the markersize?
-    ## FIXME: Why not just update the xdata, ydata properties?
-    ##        Calling plot involves a lot of overhead.
-    plot (told, yold, "-o", "markersize", 1); drawnow;
-    ret = false;
+    figure ();
+    hlines = plot (told, yold, "-", "marker", ".", "markersize", 9);
+    num_lines = numel (hlines);
 
   elseif (strcmp (flag, "done"))
     ## Cleanup after ode solver has finished.
-    clear ("figure", "told", "yold", "counter");
+    hlines = num_lines = told = yold = idx = [];
 
   endif
 
@@ -100,9 +105,9 @@
 
 
 %!demo
-%! # Solve an anonymous implementation of the Van der Pol equation
-%! # and display the results while solving
-%! fvdb = @(t,y) [y(2); (1 - y(1)^2) * y(2) - y(1)];
+%! ## Solve an anonymous implementation of the Van der Pol equation
+%! ## and display the results while solving
+%! fvdp = @(t,y) [y(2); (1 - y(1)^2) * y(2) - y(1)];
 %! opt = odeset ("OutputFcn", @odeplot, "RelTol", 1e-6);
-%! sol = ode45 (fvdb, [0 20], [2 0], opt);
+%! sol = ode45 (fvdp, [0 20], [2 0], opt);