# HG changeset patch # User jwe # Date 1144091011 0 # Node ID e065f7c18bdc7c16377f2ae6bf81c1c4f95fb623 # Parent 4ff0cb3e1dd158a6a6b8af6738f21527a9ce5c89 [project @ 2006-04-03 19:03:30 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,13 @@ 2006-04-03 David Bateman + * 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 diff --git a/src/DLD-FUNCTIONS/daspk.cc b/src/DLD-FUNCTIONS/daspk.cc --- a/src/DLD-FUNCTIONS/daspk.cc +++ b/src/DLD-FUNCTIONS/daspk.cc @@ -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 (); diff --git a/src/DLD-FUNCTIONS/dasrt.cc b/src/DLD-FUNCTIONS/dasrt.cc --- a/src/DLD-FUNCTIONS/dasrt.cc +++ b/src/DLD-FUNCTIONS/dasrt.cc @@ -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 (); diff --git a/src/DLD-FUNCTIONS/dassl.cc b/src/DLD-FUNCTIONS/dassl.cc --- a/src/DLD-FUNCTIONS/dassl.cc +++ b/src/DLD-FUNCTIONS/dassl.cc @@ -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 (); diff --git a/src/DLD-FUNCTIONS/fsolve.cc b/src/DLD-FUNCTIONS/fsolve.cc --- a/src/DLD-FUNCTIONS/fsolve.cc +++ b/src/DLD-FUNCTIONS/fsolve.cc @@ -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 (); diff --git a/src/DLD-FUNCTIONS/lsode.cc b/src/DLD-FUNCTIONS/lsode.cc --- a/src/DLD-FUNCTIONS/lsode.cc +++ b/src/DLD-FUNCTIONS/lsode.cc @@ -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 ();