changeset 3955:dc970f5941ee

[project @ 2002-05-23 20:28:56 by jwe]
author jwe
date Thu, 23 May 2002 20:28:56 +0000
parents 8194e0b10a9a
children 8a5596d6f7c4
files liboctave/ChangeLog liboctave/LSODE.cc liboctave/LSODE.h src/ChangeLog src/DLD-FUNCTIONS/lsode.cc
diffstat 5 files changed, 126 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,7 +1,8 @@
 2002-05-23  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
-	* LSODE.cc (LSODE::do_integrate): Define method flag and iopt
-	here, not as class data members.	
+	* LSODE.cc (LSODE_options::x_integration_method): New data member.
+	(LSODE_options::set_integration_method,
+	LSODE_options::integration_method): New functions.
 
 	* LSODE.h (LSODE_options::x_absolute_tolerance): Now Array<double>.
 	Change all uses.
--- a/liboctave/LSODE.cc
+++ b/liboctave/LSODE.cc
@@ -37,6 +37,18 @@
 #include "f77-fcn.h"
 #include "lo-error.h"
 
+void
+LSODE_options::set_integration_method (const std::string& val)
+{
+  if (val == "stiff" || val == "bdf")
+    x_integration_method = "stiff";
+  else if (val == "non-stiff" || val == "adams")
+    x_integration_method = "non-stiff";
+  else
+    (*current_liboctave_error_handler)
+      ("lsode_options: method must be \"stiff\", \"bdf\", \"non-stiff\", or \"adams\"");
+}
+
 typedef int (*lsode_fcn_ptr) (const int&, const double&, double*,
 			      double*, int&);
 
@@ -66,9 +78,7 @@
 
   istate = 1;
   itask = 1;
-
-  liw = 20 + n;
-  lrw = 22 + n * (9 + n);
+  iopt = 0;
 
   sanity_checked = 0;
 }
@@ -86,9 +96,7 @@
 
   istate = 1;
   itask = 1;
-
-  liw = 20 + n;
-  lrw = 22 + n * (9 + n);
+  iopt = 0;
 
   sanity_checked = 0;
 }
@@ -165,6 +173,24 @@
       istate = 1;
     }
 
+  if (integration_method () == "stiff")
+    {
+      if (jac)
+	method_flag = 21;
+      else
+	method_flag = 22;
+
+      liw = 20 + n;
+      lrw = 22 + n * (9 + n);
+    }
+  else
+    {
+      method_flag = 10;
+
+      liw = 20;
+      lrw = 22 + 16 * n;
+    }
+
   if (iwork.length () != liw)
     {
       iwork.resize (liw);
@@ -181,9 +207,6 @@
 	rwork.elem (i) = 0;
     }
 
-  int method_flag = jac ? 21 : 22;
-  int iopt = 0;
-
   integration_error = 0;
 
   double *xp = x.fortran_vec ();
--- a/liboctave/LSODE.h
+++ b/liboctave/LSODE.h
@@ -57,6 +57,7 @@
       x_absolute_tolerance.resize (1);
       x_absolute_tolerance(0) = sqrt_eps;
       x_initial_step_size = -1.0;
+      x_integration_method = "stiff";
       x_maximum_step_size = -1.0;
       x_minimum_step_size = 0.0;
       x_relative_tolerance = sqrt_eps;
@@ -71,10 +72,10 @@
     {
       x_absolute_tolerance = opt.x_absolute_tolerance;
       x_initial_step_size = opt.x_initial_step_size;
+      x_integration_method = opt.x_integration_method;
       x_maximum_step_size = opt.x_maximum_step_size;
       x_minimum_step_size = opt.x_minimum_step_size;
       x_relative_tolerance = opt.x_relative_tolerance;
-
       x_step_limit = opt.x_step_limit;
     }
 
@@ -92,6 +93,8 @@
   void set_initial_step_size (double val)
     { x_initial_step_size = (val >= 0.0) ? val : -1.0; }
 
+  void set_integration_method (const std::string& val);
+
   void set_maximum_step_size (double val)
     { x_maximum_step_size = (val >= 0.0) ? val : -1.0; }
 
@@ -110,6 +113,9 @@
   double initial_step_size (void) const
     { return x_initial_step_size; }
 
+  std::string integration_method (void) const
+    { return x_integration_method; }
+
   double maximum_step_size (void) const
     { return x_maximum_step_size; }
 
@@ -126,6 +132,7 @@
 
   Array<double> x_absolute_tolerance;
   double x_initial_step_size;
+  std::string x_integration_method;
   double x_maximum_step_size;
   double x_minimum_step_size;
   double x_relative_tolerance;
@@ -165,10 +172,12 @@
   int n;
   int integration_error;
   int restart;
+  int method_flag;
   Array<int> iwork;
   Array<double> rwork;
   int istate;
   int itask;
+  int iopt;
   int liw;
   int lrw;
   int sanity_checked;
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -9,6 +9,15 @@
 	(show_lsode_option_list): Likewise.
 	(Flsode_options): Likewise.
 
+	* DLD-FUNCTIONS/lsode.cc (LSODE_options::s_set_opt_mf,
+	LSODE_options::s_get_opt_mf): New typedefs.
+	(LSODE_OPTIONS::s_set_fcn, LSODE_OPTIONS::s_get_fcn): New fields.
+	(lsode_option_table): Fill them in.
+	(set_lsode_option (const std::string&)): New function.
+	(print_lsode_option_list): Handle string options.
+	(show_lsode_option_list): Likewise.
+	(Flsode_options): Likewise.
+
 2002-05-22  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* c-file-ptr-stream.h (c_file_ptr_buf::fclose): New function.
--- a/src/DLD-FUNCTIONS/lsode.cc
+++ b/src/DLD-FUNCTIONS/lsode.cc
@@ -298,9 +298,12 @@
 typedef void (LSODE_options::*da_set_opt_mf) (const Array<double>&);
 typedef void (LSODE_options::*d_set_opt_mf) (double);
 typedef void (LSODE_options::*i_set_opt_mf) (int);
+typedef void (LSODE_options::*s_set_opt_mf) (const std::string&);
+
 typedef Array<double> (LSODE_options::*da_get_opt_mf) (void) const;
 typedef double (LSODE_options::*d_get_opt_mf) (void) const;
 typedef int (LSODE_options::*i_get_opt_mf) (void) const;
+typedef std::string (LSODE_options::*s_get_opt_mf) (void) const;
 
 #define MAX_TOKENS 3
 
@@ -313,9 +316,11 @@
   da_set_opt_mf da_set_fcn;
   d_set_opt_mf d_set_fcn;
   i_set_opt_mf i_set_fcn;
+  s_set_opt_mf s_set_fcn;
   da_get_opt_mf da_get_fcn;
   d_get_opt_mf d_get_fcn;
   i_get_opt_mf i_get_fcn;
+  s_get_opt_mf s_get_fcn;
 };
 
 static LSODE_OPTIONS lsode_option_table [] =
@@ -323,43 +328,50 @@
   { "absolute tolerance",
     { "absolute", "tolerance", 0, 0, },
     { 1, 0, 0, 0, }, 1,
-    &LSODE_options::set_absolute_tolerance, 0, 0,
-    &LSODE_options::absolute_tolerance, 0, 0, },
+    &LSODE_options::set_absolute_tolerance, 0, 0, 0,
+    &LSODE_options::absolute_tolerance, 0, 0, 0, },
 
   { "initial step size",
     { "initial", "step", "size", 0, },
-    { 1, 0, 0, 0, }, 1,
-    0, &LSODE_options::set_initial_step_size, 0,
-    0, &LSODE_options::initial_step_size, 0, },
+    { 3, 0, 0, 0, }, 1,
+    0, &LSODE_options::set_initial_step_size, 0, 0,
+    0, &LSODE_options::initial_step_size, 0, 0, },
+
+  { "integration method",
+    { "integration", "method", 0, 0, },
+    { 3, 0, 0, 0, }, 1,
+    0, 0, 0, &LSODE_options::set_integration_method,
+    0, 0, 0, &LSODE_options::integration_method, },
 
   { "maximum step size",
     { "maximum", "step", "size", 0, },
     { 2, 0, 0, 0, }, 1,
-    0, &LSODE_options::set_maximum_step_size, 0,
-    0, &LSODE_options::maximum_step_size, 0, },
+    0, &LSODE_options::set_maximum_step_size, 0, 0,
+    0, &LSODE_options::maximum_step_size, 0, 0, },
 
   { "minimum step size",
     { "minimum", "step", "size", 0, },
     { 2, 0, 0, 0, }, 1,
-    0, &LSODE_options::set_minimum_step_size, 0,
-    0, &LSODE_options::minimum_step_size, 0, },
+    0, &LSODE_options::set_minimum_step_size, 0, 0,
+    0, &LSODE_options::minimum_step_size, 0, 0, },
 
   { "relative tolerance",
     { "relative", "tolerance", 0, 0, },
     { 1, 0, 0, 0, }, 1,
-    0, &LSODE_options::set_relative_tolerance, 0,
-    0, &LSODE_options::relative_tolerance, 0, },
+    0, &LSODE_options::set_relative_tolerance, 0, 0,
+    0, &LSODE_options::relative_tolerance, 0, 0, },
 
   { "step limit",
     { "step", "limit", 0, 0, },
     { 1, 0, 0, 0, }, 1,
-    0, 0, &LSODE_options::set_step_limit,
-    0, 0, &LSODE_options::step_limit, },
+    0, 0, &LSODE_options::set_step_limit, 0,
+    0, 0, &LSODE_options::step_limit, 0, },
 
   { 0,
     { 0, 0, 0, 0, },
     { 0, 0, 0, 0, }, 0,
-    0, 0, 0, 0, 0, 0, },
+    0, 0, 0, 0,
+    0, 0, 0, 0, },
 };
 
 static void
@@ -410,7 +422,7 @@
 	  else
 	    os << val;
 	}
-      else
+      else if (list->i_get_fcn)
 	{
 	  int val = (lsode_opts.*list->i_get_fcn) ();
 	  if (val < 0)
@@ -418,6 +430,13 @@
 	  else
 	    os << val;
 	}
+      else if (list->s_get_fcn)
+	{
+	  os << (lsode_opts.*list->s_get_fcn) ();
+	}
+      else
+	panic_impossible ();
+
       os << "\n";
       list++;
     }
@@ -478,6 +497,29 @@
   warning ("lsode_options: no match for `%s'", keyword.c_str ());
 }
 
+static void
+set_lsode_option (const std::string& keyword, const std::string& val)
+{
+  LSODE_OPTIONS *list = lsode_option_table;
+
+  while (list->keyword != 0)
+    {
+      if (keyword_almost_match (list->kw_tok, list->min_len, keyword,
+				list->min_toks_to_match, MAX_TOKENS))
+	{
+	  if (list->s_set_fcn)
+	    (lsode_opts.*list->s_set_fcn) (val);
+	  else
+	    error ("lsode_options: no function to handle string option");
+
+	  return;
+	}
+      list++;
+    }
+
+  warning ("lsode_options: no match for `%s'", keyword.c_str ());
+}
+
 static octave_value_list
 show_lsode_option (const std::string& keyword)
 {
@@ -511,7 +553,7 @@
 	      else
 		retval = val;
 	    }
-	  else
+	  else if (list->i_get_fcn)
 	    {
 	      int val = (lsode_opts.*list->i_get_fcn) ();
 	      if (val < 0)
@@ -519,6 +561,12 @@
 	      else
 		retval = static_cast<double> (val);
 	    }
+	  else if (list->s_get_fcn)
+	    {
+	      retval = (lsode_opts.*list->s_get_fcn) ();
+	    }
+	  else
+	    panic_impossible ();
 
 	  return retval;
 	}
@@ -558,7 +606,14 @@
 	    retval = show_lsode_option (keyword);
 	  else
 	    {
-	      if (args(1).is_scalar_type ())
+	      if (args(1).is_string ())
+		{
+		  std::string val = args(1).string_value ();
+
+		  if (! error_state)
+		    set_lsode_option (keyword, val);
+		}
+	      else if (args(1).is_scalar_type ())
 		{
 		  double val = args(1).double_value ();