changeset 3959:5a848097fe4a

[project @ 2002-05-24 17:58:16 by jwe]
author jwe
date Fri, 24 May 2002 17:58:17 +0000
parents b88e01ad515e
children b2133db551dd
files liboctave/ChangeLog liboctave/LSODE.cc liboctave/LSODE.h src/ChangeLog src/DLD-FUNCTIONS/lsode.cc
diffstat 5 files changed, 91 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,10 @@
+2002-05-24  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* LSODE.cc (LSODE::error_message): New function.
+	* LSODE.h: Provide decl.
+	(LSODE::integration_state): New function.
+	(LSODE::integration_ok): New function.
+
 2002-05-23  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* LSODE.cc (LSODE_options::x_integration_method): New data member.
--- a/liboctave/LSODE.cc
+++ b/liboctave/LSODE.cc
@@ -316,13 +316,7 @@
 	case -4:  // repeated error test failures (check all inputs).
 	case -3:  // illegal input detected (see printed message).
 	case -2:  // excess accuracy requested (tolerances too small).
-	  integration_error = 1;
-	  break;
-
 	case -1:  // excess work done on this call (perhaps wrong mf).
-	  (*current_liboctave_error_handler)
-	    ("giving up after more than %d steps attempted in lsode",
-	     step_limit ());
 	  integration_error = 1;
 	  break;
 
@@ -341,6 +335,63 @@
   return retval;
 }
 
+std::string
+LSODE::error_message (void) const
+{
+  std::string retval;
+
+  switch (istate)
+    {
+    case -13:
+      retval = "return requested in user-supplied function";
+      break;
+
+    case -6:
+      retval = "Error weight became zero during problem.\
+  (solution component i vanished, and atol or atol(i) == 0)";
+      break;
+
+    case -5:
+      retval = "repeated convergence failures (perhaps bad jacobian\
+ supplied or wrong choice of integration method or tolerances)";
+      break;
+
+    case -4:
+      retval = "repeated error test failures (check all inputs)";
+      break;
+
+    case -3:
+      retval = "invalid input detected (see printed message)";
+      break;
+
+    case -2:
+      retval = "excess accuracy requested (tolerances too small)";
+      break;
+
+    case -1:
+      retval = "excess work on this call (perhaps wrong integration method)";
+      break;
+
+    case 1:
+      retval = "prior to initial call";
+      break;
+
+    case 2:
+      retval = "successful exit";
+      break;
+	  
+    case 3:
+      retval = "prior to continuation call with modified parameters";
+      break;
+	  
+    default:
+      retval = "unknown error state";
+      break;
+    }
+
+  return retval;
+}
+
 Matrix
 LSODE::do_integrate (const ColumnVector& tout)
 {
--- a/liboctave/LSODE.h
+++ b/liboctave/LSODE.h
@@ -164,6 +164,12 @@
 
   Matrix do_integrate (const ColumnVector& tout, const ColumnVector& tcrit);
 
+  int integration_state (void) const { return istate; }
+
+  bool integration_ok (void) const { return ! integration_error; }
+
+  std::string error_message (void) const;
+
 private:
 
   double stop_time;
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
 2002-05-24  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
+	* DLD-FUNCTIONS/lsode.cc (Flsode): Also return istate and error
+	message.  Only generate error if user is not at least requesting
+	the istate output.
+
 	* load-save.cc (hdf5_import_multidim, hdf5_check_attr,
 	hdf5_callback_data, hdf5_read_next_data, read_hdf5_data,
 	add_hdf5_data): Use 0, not NULL in calls to HDF routines.
--- a/src/DLD-FUNCTIONS/lsode.cc
+++ b/src/DLD-FUNCTIONS/lsode.cc
@@ -160,7 +160,7 @@
 
 DEFUN_DLD (lsode, args, nargout,
   "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} lsode (@var{fcn}, @var{x0}, @var{t}, @var{t_crit})\n\
+@deftypefn {Loadable Function} {[@var{x}, @var{istate}, @var{msg}]} lsode (@var{fcn}, @var{x0}, @var{t}, @var{t_crit})\n\
 Return a matrix of @var{x} as a function of @var{t}, given the initial\n\
 state of the system @var{x0}.  Each row in the result matrix corresponds\n\
 to one of the elements in the vector @var{t}.  The first element of\n\
@@ -196,7 +196,7 @@
 
   int nargin = args.length ();
 
-  if (nargin > 2 && nargin < 5 && nargout < 2)
+  if (nargin > 2 && nargin < 5 && nargout < 4)
     {
       octave_value f_arg = args(0);
 
@@ -283,8 +283,21 @@
 
       if (! error_state)
 	{
-	  retval.resize (1);
-	  retval(0) = output;
+	  retval(2) = ode.error_message ();
+	  retval(1) = static_cast<double> (ode.integration_state ());
+
+	  if (ode.integration_ok ())
+	    retval = output;
+	  else
+	    {
+	      output = Matrix ();
+
+	      if (nargout < 2)
+		{
+		  std::string msg = ode.error_message ();
+		  error ("lsode: %s", msg.c_str ());
+		}
+	    }
 	}
     }
   else