diff src/DLD-FUNCTIONS/lsode.cc @ 3243:dd00769643ae

[project @ 1999-05-28 04:19:00 by jwe]
author jwe
date Fri, 28 May 1999 04:19:24 +0000
parents 9c5160c83bd2
children 6923abb04e16
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/lsode.cc	Fri Apr 09 00:20:06 1999 +0000
+++ b/src/DLD-FUNCTIONS/lsode.cc	Fri May 28 04:19:24 1999 +0000
@@ -37,6 +37,7 @@
 #include "oct-obj.h"
 #include "ov-fcn.h"
 #include "pager.h"
+#include "unwind-prot.h"
 #include "utils.h"
 #include "variables.h"
 
@@ -48,6 +49,9 @@
 
 static LSODE_options lsode_opts;
 
+// Is this a recursive call?
+static int call_depth = 0;
+
 ColumnVector
 lsode_user_function (const ColumnVector& x, double t)
 {
@@ -140,114 +144,126 @@
 {
   octave_value_list retval;
 
-  int nargin = args.length ();
+  unwind_protect::begin_frame ("Flsode");
 
-  if (nargin < 3 || nargin > 4 || nargout > 1)
+  unwind_protect_int (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
     {
-      print_usage ("lsode");
+      error ("lsode: invalid recursive call");
       return retval;
     }
 
-  octave_value f_arg = args(0);
+  int nargin = args.length ();
 
-  switch (f_arg.rows ())
+  if (nargin > 2 && nargin < 5 && nargout < 2)
     {
-    case 1:
-      lsode_fcn = extract_function
-	(args(0), "lsode", "__lsode_fcn__",
-	 "function xdot = __lsode_fcn__ (x, t) xdot = ",
-	 "; endfunction");
-      break;
+      octave_value f_arg = args(0);
 
-    case 2:
-      {
-	string_vector tmp = args(0).all_strings ();
+      switch (f_arg.rows ())
+	{
+	case 1:
+	  lsode_fcn = extract_function
+	    (args(0), "lsode", "__lsode_fcn__",
+	     "function xdot = __lsode_fcn__ (x, t) xdot = ",
+	     "; endfunction");
+	  break;
 
-	if (! error_state)
+	case 2:
 	  {
-	    lsode_fcn = extract_function
-	      (tmp(0), "lsode", "__lsode_fcn__",
-	       "function xdot = __lsode_fcn__ (x, t) xdot = ",
-	       "; endfunction");
+	    string_vector tmp = args(0).all_strings ();
 
-	    if (lsode_fcn)
+	    if (! error_state)
 	      {
-		lsode_jac = extract_function
-		  (tmp(1), "lsode", "__lsode_jac__",
-		   "function jac = __lsode_jac__ (x, t) jac = ",
+		lsode_fcn = extract_function
+		  (tmp(0), "lsode", "__lsode_fcn__",
+		   "function xdot = __lsode_fcn__ (x, t) xdot = ",
 		   "; endfunction");
 
-		if (! lsode_jac)
-		  lsode_fcn = 0;
+		if (lsode_fcn)
+		  {
+		    lsode_jac = extract_function
+		      (tmp(1), "lsode", "__lsode_jac__",
+		       "function jac = __lsode_jac__ (x, t) jac = ",
+		       "; endfunction");
+
+		    if (! lsode_jac)
+		      lsode_fcn = 0;
+		  }
 	      }
 	  }
-      }
-      break;
-
-    default:
-      error ("lsode: first arg should be a string or 2-element string array");
-      break;
-    }
-
-  if (error_state || ! lsode_fcn)
-    return retval;
-
-  ColumnVector state = args(1).vector_value ();
+	  break;
 
-  if (error_state)
-    {
-      error ("lsode: expecting state vector as second argument");
-      return retval;
-    }
-
-  ColumnVector out_times = args(2).vector_value ();
+	default:
+	  error ("lsode: first arg should be a string or 2-element string array");
+	  break;
+	}
 
-  if (error_state)
-    {
-      error ("lsode: expecting output time vector as third argument");
-      return retval;
-    }
+      if (error_state || ! lsode_fcn)
+	return retval;
 
-  ColumnVector crit_times;
-
-  int crit_times_set = 0;
-  if (nargin > 3)
-    {
-      crit_times = args(3).vector_value ();
+      ColumnVector state = args(1).vector_value ();
 
       if (error_state)
 	{
-	  error ("lsode: expecting critical time vector as fourth argument");
+	  error ("lsode: expecting state vector as second argument");
+	  return retval;
+	}
+
+      ColumnVector out_times = args(2).vector_value ();
+
+      if (error_state)
+	{
+	  error ("lsode: expecting output time vector as third argument");
 	  return retval;
 	}
 
-      crit_times_set = 1;
-    }
+      ColumnVector crit_times;
 
-  double tzero = out_times (0);
-  int nsteps = out_times.capacity ();
+      int crit_times_set = 0;
+      if (nargin > 3)
+	{
+	  crit_times = args(3).vector_value ();
 
-  ODEFunc func (lsode_user_function);
-  if (lsode_jac)
-    func.set_jacobian_function (lsode_user_jacobian);
+	  if (error_state)
+	    {
+	      error ("lsode: expecting critical time vector as fourth argument");
+	      return retval;
+	    }
 
-  LSODE ode (state, tzero, func);
+	  crit_times_set = 1;
+	}
 
-  ode.copy (lsode_opts);
+      double tzero = out_times (0);
+      int nsteps = out_times.capacity ();
+
+      ODEFunc func (lsode_user_function);
+      if (lsode_jac)
+	func.set_jacobian_function (lsode_user_jacobian);
 
-  int nstates = state.capacity ();
-  Matrix output (nsteps, nstates + 1);
+      LSODE ode (state, tzero, func);
+
+      ode.copy (lsode_opts);
+
+      int nstates = state.capacity ();
+      Matrix output (nsteps, nstates + 1);
 
-  if (crit_times_set)
-    output = ode.integrate (out_times, crit_times);
+      if (crit_times_set)
+	output = ode.integrate (out_times, crit_times);
+      else
+	output = ode.integrate (out_times);
+
+      if (! error_state)
+	{
+	  retval.resize (1);
+	  retval(0) = output;
+	}
+    }
   else
-    output = ode.integrate (out_times);
+    print_usage ("lsode");
 
-  if (! error_state)
-    {
-      retval.resize (1);
-      retval(0) = output;
-    }
+  unwind_protect::run_frame ("Flsode");
 
   return retval;
 }