changeset 5729:e065f7c18bdc

[project @ 2006-04-03 19:03:30 by jwe]
author jwe
date Mon, 03 Apr 2006 19:03:31 +0000
parents 4ff0cb3e1dd1
children 109fdf7b3dcb
files src/ChangeLog src/DLD-FUNCTIONS/daspk.cc src/DLD-FUNCTIONS/dasrt.cc src/DLD-FUNCTIONS/dassl.cc src/DLD-FUNCTIONS/fsolve.cc src/DLD-FUNCTIONS/lsode.cc
diffstat 6 files changed, 548 insertions(+), 160 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Apr 03 18:57:51 2006 +0000
+++ b/src/ChangeLog	Mon Apr 03 19:03:31 2006 +0000
@@ -1,5 +1,13 @@
 2006-04-03  David Bateman  <dbateman@free.fr>
 
+	* DLD-FUNCTIONS/daspk.cc (Fdaspk): Allow functions to be passed
+	using function handles, inline functions, and cell arrays of
+	strings, inline and function handles.
+	* DLD-FUNCTIONS/dasrtk.cc (Fdasrt): Likewise.
+	* DLD-FUNCTIONS/dassl.cc (Fdassl): Likewise.
+	* DLD-FUNCTIONS/fsolve.cc (Ffsolve): Likewise.
+	* DLD-FUNCTIONS/lsode.cc (Flsode):  Likewise.
+
 	* ls-hdf5.h (hdf5_fstreambase::open): Remove unused arg prot.
 
 2006-03-30  Bill Denney  <denney@seas.upenn.edu>
--- a/src/DLD-FUNCTIONS/daspk.cc	Mon Apr 03 18:57:51 2006 +0000
+++ b/src/DLD-FUNCTIONS/daspk.cc	Mon Apr 03 19:03:31 2006 +0000
@@ -37,6 +37,7 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov-fcn.h"
+#include "ov-cell.h"
 #include "pager.h"
 #include "unwind-prot.h"
 #include "utils.h"
@@ -205,9 +206,10 @@
 row of the output @var{x} is @var{x_0} and the first row\n\
 of the output @var{xdot} is @var{xdot_0}.\n\
 \n\
-The first argument, @var{fcn}, is a string that names the function to\n\
-call to compute the vector of residuals for the set of equations.\n\
-It must have the form\n\
+The first argument, @var{fcn}, is a string or a two element cell array\n\
+of strings, inline or function handle, that names the function, to call\n\
+to compute the vector of residuals for the set of equations. It must\n\
+have the form\n\
 \n\
 @example\n\
 @var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
@@ -286,43 +288,112 @@
 
   if (nargin > 3 && nargin < 6)
     {
+      std::string fcn_name, fname, jac_name, jname;
       daspk_fcn = 0;
       daspk_jac = 0;
 
       octave_value f_arg = args(0);
 
-      switch (f_arg.rows ())
-	{
-	case 1:
-	  daspk_fcn = extract_function
-	    (args(0), "daspk", "__daspk_fcn__",
-	     "function res = __daspk_fcn__ (x, xdot, t) res = ",
-	     "; endfunction");
-	  break;
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		daspk_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__daspk_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x, xdot, t) y = ");
+		  daspk_fcn = extract_function
+		    (c(0), "daspk", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (daspk_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    daspk_jac = c(1).function_value ();
+		  else
+		    {
+		      jac_name = unique_symbol_name ("__daspk_jac__");
+		      jname = "function jac = ";
+		      jname.append(jac_name);
+		      jname.append (" (x, xdot, t, cj) jac = ");
+		      daspk_jac = extract_function
+			(c(1), "daspk", jac_name, jname, "; endfunction");
 
-	case 2:
-	  {
-	    string_vector tmp = f_arg.all_strings ();
+		      if (!daspk_jac)
+			{
+			  if (fcn_name.length())
+			    clear_function (fcn_name);
+			  daspk_fcn = 0;
+			}
+		    }
+		}
+	    }
+	  else
+	    DASPK_ABORT1 ("incorrect number of elements in cell array");
+	}
 
-	    if (! error_state)
-	      {
-		daspk_fcn = extract_function
-		  (tmp(0), "daspk", "__daspk_fcn__",
-		   "function res = __daspk_fcn__ (x, xdot, t) res = ",
-		   "; endfunction");
+      if (!daspk_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    daspk_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__daspk_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x, xdot, t) y = ");
+		      daspk_fcn = extract_function
+			(f_arg, "daspk", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
 
-		if (daspk_fcn)
+		case 2:
 		  {
-		    daspk_jac = extract_function
-		      (tmp(1), "daspk", "__daspk_jac__",
-		       "function jac = __daspk_jac__ (x, xdot, t, cj) jac = ",
-		       "; endfunction");
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__daspk_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x, xdot, t) y = ");
+			daspk_fcn = extract_function
+			  (tmp(0), "daspk", fcn_name, fname, "; endfunction");
 
-		    if (! daspk_jac)
-		      daspk_fcn = 0;
+			if (daspk_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__daspk_jac__");
+			    jname = "function jac = ";
+			    jname.append(jac_name);
+			    jname.append (" (x, xdot, t, cj) jac = ");
+			    daspk_jac = extract_function
+			      (tmp(1), "daspk", jac_name, jname,
+			       "; endfunction");
+
+			    if (!daspk_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				daspk_fcn = 0;
+			      }
+			  }
+		      }
 		  }
-	      }
-	  }
+		}
+	    }
 	}
 
       if (error_state || ! daspk_fcn)
@@ -375,6 +446,11 @@
       else
 	output = dae.integrate (out_times, deriv_output);
 
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
       if (! error_state)
 	{
 	  std::string msg = dae.error_message ();
--- a/src/DLD-FUNCTIONS/dasrt.cc	Mon Apr 03 18:57:51 2006 +0000
+++ b/src/DLD-FUNCTIONS/dasrt.cc	Mon Apr 03 19:03:31 2006 +0000
@@ -36,6 +36,7 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov-fcn.h"
+#include "ov-cell.h"
 #include "pager.h"
 #include "parse.h"
 #include "unwind-prot.h"
@@ -249,9 +250,9 @@
 @var{t_out} will be the point at which the stopping condition was met,\n\
 and may not correspond to any element of the vector @var{t}.\n\
 \n\
-The first argument, @var{fcn}, is a string that names the function to\n\
-call to compute the vector of residuals for the set of equations.\n\
-It must have the form\n\
+The first argument, @var{fcn}, is a string, or cell array of strings or\n\
+inline or function handles, that names the function to call to compute\n\
+the vector of residuals for the set of equations. It must have the form\n\
 \n\
 @example\n\
 @var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
@@ -261,9 +262,9 @@
 in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\
 scalar.\n\
 \n\
-If @var{fcn} is a two-element string array, the first element names\n\
-the function @math{f} described above, and the second element names\n\
-a function to compute the modified Jacobian\n\
+If @var{fcn} is a two-element string array, or two element cell array,\n\
+the first element names the function @math{f} described above, and the\n\
+second element names a function to compute the modified Jacobian\n\
 \n\
 @tex\n\
 $$\n\
@@ -367,6 +368,7 @@
       return retval;
     }
 
+  std::string fcn_name, fname, jac_name, jname;
   dasrt_f = 0;
   dasrt_j = 0;
   dasrt_cf = 0;
@@ -377,43 +379,102 @@
 
   octave_value f_arg = args(0);
 
-  switch (f_arg.rows ())
+  if (f_arg.is_cell ())
     {
-    case 1:
-      dasrt_f = extract_function
-	(args(0), "dasrt", "__dasrt_fcn__",
-	 "function res = __dasrt_fcn__ (x, xdot, t) res = ",
-	 "; endfunction");
-      break;
+      Cell c = f_arg.cell_value ();
+      if (c.length() == 1)
+	f_arg = c(0);
+      else if (c.length() == 2)
+	{
+	  if (c(0).is_function_handle () || c(0).is_inline_function ())
+	    dasrt_f = c(0).function_value ();
+	  else
+	    {
+	      fcn_name = unique_symbol_name ("__dasrt_fcn__");
+	      fname = "function y = ";
+	      fname.append (fcn_name);
+	      fname.append (" (x, xdot, t) y = ");
+	      dasrt_f = extract_function
+		(c(0), "dasrt", fcn_name, fname, "; endfunction");
+	    }
+
+	  if (dasrt_f)
+	    {
+	      if (c(1).is_function_handle () || c(1).is_inline_function ())
+		dasrt_j = c(1).function_value ();
+	      else
+		{
+		  jac_name = unique_symbol_name ("__dasrt_jac__");
+		  jname = "function jac = ";
+		  jname.append(jac_name);
+		  jname.append (" (x, xdot, t, cj) jac = ");
+		  dasrt_j = extract_function
+		    (c(1), "dasrt", jac_name, jname, "; endfunction");
+
+		  if (!dasrt_j)
+		    {
+		      if (fcn_name.length())
+			clear_function (fcn_name);
+		      dasrt_f = 0;
+		    }
+		}
+	    }
+	}
+      else
+	DASRT_ABORT1 ("incorrect number of elements in cell array");
+    }
+
+  if (!dasrt_f && ! f_arg.is_cell())
+    {
+      if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	dasrt_f = f_arg.function_value ();
+      else
+	{
+	  switch (f_arg.rows ())
+	    {
+	    case 1:
+	      fcn_name = unique_symbol_name ("__dasrt_fcn__");
+	      fname = "function y = ";
+	      fname.append (fcn_name);
+	      fname.append (" (x, xdot, t) y = ");
+	      dasrt_f = extract_function
+		(f_arg, "dasrt", fcn_name, fname, "; endfunction");
+	      break;
       
-    case 2:
-      {
-	string_vector tmp = args(0).all_strings ();
+	    case 2:
+	      {
+		string_vector tmp = args(0).all_strings ();
 	
-	if (! error_state)
-	  {
-	    dasrt_f = extract_function
-	      (tmp(0), "dasrt", "__dasrt_fcn__",
-	       "function res = __dasrt_fcn__ (x, xdot, t) res = ",
-	       "; endfunction");
+		if (! error_state)
+		  {
+		    fcn_name = unique_symbol_name ("__dasrt_fcn__");
+		    fname = "function y = ";
+		    fname.append (fcn_name);
+		    fname.append (" (x, xdot, t) y = ");
+		    dasrt_f = extract_function
+		      (tmp(0), "dasrt", fcn_name, fname, "; endfunction");
 	    
-	    if (dasrt_f)
-	      {
-		dasrt_j = extract_function
-		  (tmp(1), "dasrt", "__dasrt_jac__",
-		   "function jac = __dasrt_jac__ (x, xdot, t, cj) jac = ",
-		   "; endfunction");
-		
-		if (! dasrt_j)
-		  dasrt_f = 0;
+		    if (dasrt_f)
+		      {
+			jac_name = unique_symbol_name ("__dasrt_jac__");
+			jname = "function jac = ";
+			jname.append(jac_name);
+			jname.append (" (x, xdot, t, cj) jac = ");
+			dasrt_j = extract_function
+			  (tmp(1), "dasrt", jac_name, jname, "; endfunction");
+
+			if (! dasrt_j)
+			  dasrt_f = 0;
+		      }
+		  }
 	      }
-	  }
-      }
-      break;
+	      break;
       
-    default:
-      DASRT_ABORT1
-	("first arg should be a string or 2-element string array");
+	    default:
+	      DASRT_ABORT1
+		("first arg should be a string or 2-element string array");
+	    }
+	}
     }
   
   if (error_state || (! dasrt_f))
@@ -423,10 +484,20 @@
   
   argp++;
   
-  if (args(1).is_string ())
+  if (args(1).is_function_handle() || args(1).is_inline_function())
+    {
+      dasrt_cf = args(1).function_value();
+
+      if (! dasrt_cf)
+	DASRT_ABORT1 ("expecting function name as argument 2");
+
+      argp++;
+
+      func.set_constraint_function (dasrt_user_cf);
+    }
+  else if (args(1).is_string ())
     {
       dasrt_cf = is_valid_function (args(1), "dasrt", true);
-
       if (! dasrt_cf)
 	DASRT_ABORT1 ("expecting function name as argument 2");
 
@@ -483,6 +554,11 @@
   else
     output = dae.integrate (out_times);
 
+  if (fcn_name.length())
+    clear_function (fcn_name);
+  if (jac_name.length())
+    clear_function (jac_name);
+
   if (! error_state)
     {
       std::string msg = dae.error_message ();
--- a/src/DLD-FUNCTIONS/dassl.cc	Mon Apr 03 18:57:51 2006 +0000
+++ b/src/DLD-FUNCTIONS/dassl.cc	Mon Apr 03 19:03:31 2006 +0000
@@ -37,6 +37,7 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov-fcn.h"
+#include "ov-cell.h"
 #include "pager.h"
 #include "unwind-prot.h"
 #include "utils.h"
@@ -208,9 +209,10 @@
 row of the output @var{x} is @var{x_0} and the first row\n\
 of the output @var{xdot} is @var{xdot_0}.\n\
 \n\
-The first argument, @var{fcn}, is a string that names the function to\n\
-call to compute the vector of residuals for the set of equations.\n\
-It must have the form\n\
+The first argument, @var{fcn}, is a string or a two element cell array\n\
+of strings, inline or function handle, that names the function, to call\n\
+to compute the vector of residuals for the set of equations. It must\n\
+have the form\n\
 \n\
 @example\n\
 @var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
@@ -291,43 +293,112 @@
 
   if (nargin > 3 && nargin < 6 && nargout < 5)
     {
+      std::string fcn_name, fname, jac_name, jname;
       dassl_fcn = 0;
       dassl_jac = 0;
 
       octave_value f_arg = args(0);
 
-      switch (f_arg.rows ())
-	{
-	case 1:
-	  dassl_fcn = extract_function
-	    (f_arg, "dassl", "__dassl_fcn__",
-	     "function res = __dassl_fcn__ (x, xdot, t) res = ",
-	     "; endfunction");
-	  break;
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		dassl_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__dassl_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x, xdot, t) y = ");
+		  dassl_fcn = extract_function
+		    (c(0), "dassl", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (dassl_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    dassl_jac = c(1).function_value ();
+		  else
+		    {
+			jac_name = unique_symbol_name ("__dassl_jac__");
+			jname = "function jac = ";
+			jname.append(jac_name);
+			jname.append (" (x, xdot, t, cj) jac = ");
+			dassl_jac = extract_function
+			  (c(1), "dassl", jac_name, jname, "; endfunction");
 
-	case 2:
-	  {
-	    string_vector tmp = f_arg.all_strings ();
+			if (!dassl_jac)
+			  {
+			    if (fcn_name.length())
+			      clear_function (fcn_name);
+			    dassl_fcn = 0;
+			  }
+		    }
+		}
+	    }
+	  else
+	    DASSL_ABORT1 ("incorrect number of elements in cell array");
+	}
 
-	    if (! error_state)
-	      {
-		dassl_fcn = extract_function
-		  (tmp(0), "dassl", "__dassl_fcn__",
-		   "function res = __dassl_fcn__ (x, xdot, t) res = ",
-		   "; endfunction");
+      if (!dassl_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    dassl_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__dassl_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x, xdot, t) y = ");
+		      dassl_fcn = extract_function
+			(f_arg, "dassl", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
 
-		if (dassl_fcn)
+		case 2:
 		  {
-		    dassl_jac = extract_function
-		      (tmp(1), "dassl", "__dassl_jac__",
-		       "function jac = __dassl_jac__ (x, xdot, t, cj) jac = ",
-		       "; endfunction");
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__dassl_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x, xdot, t) y = ");
+			dassl_fcn = extract_function
+			  (tmp(0), "dassl", fcn_name, fname, "; endfunction");
 
-		    if (! dassl_jac)
-		      dassl_fcn = 0;
+			if (dassl_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__dassl_jac__");
+			    jname = "function jac = ";
+			    jname.append(jac_name);
+			    jname.append (" (x, xdot, t, cj) jac = ");
+			    dassl_jac = extract_function
+			      (tmp(1), "dassl", jac_name, jname, 
+			       "; endfunction");
+
+			    if (!dassl_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				dassl_fcn = 0;
+			      }
+			  }
+		      }
 		  }
-	      }
-	  }
+		}
+	    }
 	}
 
       if (error_state || ! dassl_fcn)
@@ -381,6 +452,11 @@
       else
 	output = dae.integrate (out_times, deriv_output);
 
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
       if (! error_state)
 	{
 	  std::string msg = dae.error_message ();
--- a/src/DLD-FUNCTIONS/fsolve.cc	Mon Apr 03 18:57:51 2006 +0000
+++ b/src/DLD-FUNCTIONS/fsolve.cc	Mon Apr 03 19:03:31 2006 +0000
@@ -37,6 +37,7 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov-fcn.h"
+#include "ov-cell.h"
 #include "pager.h"
 #include "unwind-prot.h"
 #include "utils.h"
@@ -220,10 +221,11 @@
 and an initial starting point @var{x0}, @code{fsolve} solves the set of\n\
 equations such that @code{f(@var{x}) == 0}.\n\
 \n\
-If @var{fcn} is a two-element string array, the first element names\n\
-the function @math{f} described above, and the second element names\n\
-a function of the form @code{j (@var{x})} to compute the Jacobian\n\
-matrix with elements\n\
+If @var{fcn} is a two-element string array, or a two element cell array\n\
+containing either the function name or inline or function handle. The\n\
+first element names the function @math{f} described above, and the second\n\
+element names a function of the form @code{j (@var{x})} to compute the\n\
+Jacobian matrix with elements\n\
 @tex\n\
 $$ J = {\\partial f_i \\over \\partial x_j} $$\n\
 @end tex\n\
@@ -257,43 +259,112 @@
 
   if (nargin == 2 && nargout < 4)
     {
+      std::string fcn_name, fname, jac_name, jname;
       fsolve_fcn = 0;
       fsolve_jac = 0;
 
       octave_value f_arg = args(0);
 
-      switch (f_arg.rows ())
-	{
-	case 1:
-	  fsolve_fcn = extract_function
-	    (f_arg, "fsolve", "__fsolve_fcn__",
-	     "function y = __fsolve_fcn__ (x) y = ",
-	     "; endfunction");
-	  break;
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		fsolve_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__fsolve_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x) y = ");
+		  fsolve_fcn = extract_function
+		    (c(0), "fsolve", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (fsolve_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    fsolve_jac = c(1).function_value ();
+		  else
+		    {
+		      jac_name = unique_symbol_name ("__fsolve_jac__");
+		      jname = "function y = ";
+		      jname.append (jac_name);
+		      jname.append (" (x) jac = ");
+		      fsolve_jac = extract_function
+			(c(1), "fsolve", jac_name, jname, "; endfunction");
 
-	case 2:
-	  {
-	    string_vector tmp = f_arg.all_strings ();
+		      if (!fsolve_jac)
+			{
+			  if (fcn_name.length())
+			    clear_function (fcn_name);
+			  fsolve_fcn = 0;
+			}
+		    }
+		}
+	    }
+	  else
+	    FSOLVE_ABORT1 ("incorrect number of elements in cell array");
+	}
 
-	    if (! error_state)
-	      {
-		fsolve_fcn = extract_function
-		  (tmp(0), "fsolve", "__fsolve_fcn__",
-		   "function y = __fsolve_fcn__ (x) y = ",
-		   "; endfunction");
+      if (!fsolve_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    fsolve_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__fsolve_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x) y = ");
+		      fsolve_fcn = extract_function
+			(f_arg, "fsolve", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
 
-		if (fsolve_fcn)
+		case 2:
 		  {
-		    fsolve_jac = extract_function
-		      (tmp(1), "fsolve", "__fsolve_jac__",
-		       "function jac = __fsolve_jac__ (x) jac = ",
-		       "; endfunction");
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__fsolve_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x) y = ");
+			fsolve_fcn = extract_function
+			  (tmp(0), "fsolve", fcn_name, fname, "; endfunction");
 
-		    if (! fsolve_jac)
-		      fsolve_fcn = 0;
+			if (fsolve_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__fsolve_jac__");
+			    jname = "function y = ";
+			    jname.append (jac_name);
+			    jname.append (" (x) jac = ");
+			    fsolve_jac = extract_function
+			      (tmp(1), "fsolve", jac_name, jname, 
+			       "; endfunction");
+
+			    if (!fsolve_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				fsolve_fcn = 0;
+			      }
+			  }
+		      }
 		  }
-	      }
-	  }
+		}
+	    }
 	}
 
       if (error_state || ! fsolve_fcn)
@@ -320,6 +391,11 @@
       octave_idx_type info;
       ColumnVector soln = nleqn.solve (info);
 
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
       if (! error_state)
 	{
 	  std::string msg = nleqn.error_message ();
--- a/src/DLD-FUNCTIONS/lsode.cc	Mon Apr 03 18:57:51 2006 +0000
+++ b/src/DLD-FUNCTIONS/lsode.cc	Mon Apr 03 19:03:31 2006 +0000
@@ -38,6 +38,7 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov-fcn.h"
+#include "ov-cell.h"
 #include "pager.h"
 #include "pr-output.h"
 #include "unwind-prot.h"
@@ -191,9 +192,10 @@
 state of the system @var{x_0}, so that the first row of the output\n\
 is @var{x_0}.\n\
 \n\
-The first argument, @var{fcn}, is a string that names the function to\n\
-call to compute the vector of right hand sides for the set of equations.\n\
-The function must have the form\n\
+The first argument, @var{fcn}, is a string, or cell array of strings,\n\
+inline or function handles, that names the function to call to compute\n\
+the vector of right hand sides for the set of equations. The function\n\
+must have the form\n\
 \n\
 @example\n\
 @var{xdot} = f (@var{x}, @var{t})\n\
@@ -286,48 +288,117 @@
 
   if (nargin > 2 && nargin < 5 && nargout < 4)
     {
+      std::string fcn_name, fname, jac_name, jname;
       lsode_fcn = 0;
       lsode_jac = 0;
 
       octave_value f_arg = args(0);
 
-      switch (f_arg.rows ())
-	{
-	case 1:
-	  lsode_fcn = extract_function
-	    (f_arg, "lsode", "__lsode_fcn__",
-	     "function xdot = __lsode_fcn__ (x, t) xdot = ",
-	     "; endfunction");
-	  break;
+      if (f_arg.is_cell ())
+  	{
+	  Cell c = f_arg.cell_value ();
+	  if (c.length() == 1)
+	    f_arg = c(0);
+	  else if (c.length() == 2)
+	    {
+	      if (c(0).is_function_handle () || c(0).is_inline_function ())
+		lsode_fcn = c(0).function_value ();
+	      else
+		{
+		  fcn_name = unique_symbol_name ("__lsode_fcn__");
+		  fname = "function y = ";
+		  fname.append (fcn_name);
+		  fname.append (" (x, t) y = ");
+		  lsode_fcn = extract_function
+		    (c(0), "lsode", fcn_name, fname, "; endfunction");
+		}
+	      
+	      if (lsode_fcn)
+		{
+		  if (c(1).is_function_handle () || c(1).is_inline_function ())
+		    lsode_jac = c(1).function_value ();
+		  else
+		    {
+			jac_name = unique_symbol_name ("__lsode_jac__");
+			jname = "function jac = ";
+			jname.append(jac_name);
+			jname.append (" (x, t) jac = ");
+			lsode_jac = extract_function
+			  (c(1), "lsode", jac_name, jname, "; endfunction");
 
-	case 2:
-	  {
-	    string_vector tmp = f_arg.all_strings ();
+		      if (!lsode_jac)
+			{
+			  if (fcn_name.length())
+			    clear_function (fcn_name);
+			  lsode_fcn = 0;
+			}
+		    }
+		}
+	    }
+	  else
+	    LSODE_ABORT1 ("incorrect number of elements in cell array");
+	}
 
-	    if (! error_state)
-	      {
-		lsode_fcn = extract_function
-		  (tmp(0), "lsode", "__lsode_fcn__",
-		   "function xdot = __lsode_fcn__ (x, t) xdot = ",
-		   "; endfunction");
+      if (!lsode_fcn && ! f_arg.is_cell())
+	{
+	  if (f_arg.is_function_handle () || f_arg.is_inline_function ())
+	    lsode_fcn = f_arg.function_value ();
+	  else
+	    {
+	      switch (f_arg.rows ())
+		{
+		case 1:
+		  do
+		    {
+		      fcn_name = unique_symbol_name ("__lsode_fcn__");
+		      fname = "function y = ";
+		      fname.append (fcn_name);
+		      fname.append (" (x, t) y = ");
+		      lsode_fcn = extract_function
+			(f_arg, "lsode", fcn_name, fname, "; endfunction");
+		    }
+		  while (0);
+		  break;
 
-		if (lsode_fcn)
+		case 2:
 		  {
-		    lsode_jac = extract_function
-		      (tmp(1), "lsode", "__lsode_jac__",
-		       "function jac = __lsode_jac__ (x, t) jac = ",
-		       "; endfunction");
+		    string_vector tmp = f_arg.all_strings ();
+
+		    if (! error_state)
+		      {
+			fcn_name = unique_symbol_name ("__lsode_fcn__");
+			fname = "function y = ";
+			fname.append (fcn_name);
+			fname.append (" (x, t) y = ");
+			lsode_fcn = extract_function
+			  (tmp(0), "lsode", fcn_name, fname, "; endfunction");
 
-		    if (! lsode_jac)
-		      lsode_fcn = 0;
+			if (lsode_fcn)
+			  {
+			    jac_name = unique_symbol_name ("__lsode_jac__");
+			    jname = "function jac = ";
+			    jname.append(jac_name);
+			    jname.append (" (x, t) jac = ");
+			    lsode_jac = extract_function
+			      (tmp(1), "lsode", jac_name, jname,
+			      "; endfunction");
+
+			    if (!lsode_jac)
+			      {
+				if (fcn_name.length())
+				  clear_function (fcn_name);
+				lsode_fcn = 0;
+			      }
+			  }
+		      }
 		  }
-	      }
-	  }
-	  break;
+		  break;
 
-	default:
-	  LSODE_ABORT1
-	    ("first arg should be a string or 2-element string array");
+		default:
+		  LSODE_ABORT1
+		    ("first arg should be a string or 2-element string array");
+		}
+	    }
 	}
 
       if (error_state || ! lsode_fcn)
@@ -372,6 +443,11 @@
       else
 	output = ode.integrate (out_times);
 
+      if (fcn_name.length())
+	clear_function (fcn_name);
+      if (jac_name.length())
+	clear_function (jac_name);
+
       if (! error_state)
 	{
 	  std::string msg = ode.error_message ();