From octave-sources-request at bevo dot che dot wisc dot edu Sun Aug 26 22:54:18 2001 Subject: Added pass-through arguments to fsolve From: "Boleslaw Ciesielski" To: Date: Sun, 26 Aug 2001 23:53:54 -0400 Hi, Below is the patch to implement the following entry from the PROJECTS file: * Allow parameters to be passed through the call to fsolve() to the user-supplied function for Matlab compatibility. Don't place an upper limit on the number of arguments. The patch is against CVS sources as of 2001/08/26. There is also a new file at the end which I wasn't sure how to include in the patch directly. Questions: Is octave-sources the right list for this kind of stuff or is bug-octave better? Is there a newer version of the PROJECTS file? I noticed that some of the stuff listed there is already implemented. Thanks, Boleslaw Ciesielski Index: src/ChangeLog =================================================================== RCS file: /cvs/octave/src/ChangeLog,v retrieving revision 1.498 diff -u -r1.498 ChangeLog --- src/ChangeLog 2001/07/23 20:07:45 1.498 +++ src/ChangeLog 2001/08/27 03:24:49 at @ -1,3 +1,10 @@ +2001-08-26 Boleslaw Ciesielski + + * fsolve.cc: Allow parameters to be passed through the call to + fsolve() to the user-supplied function for Matlab compatibility. + * nonlin.exp: Added new test fsolve-3.m + * fsolve-3.m: New file - regression test for the above functionality. + 2001-07-23 John W. Eaton * parse.y: Clear help_buf after documenting function. Index: src/DLD-FUNCTIONS/fsolve.cc =================================================================== RCS file: /cvs/octave/src/DLD-FUNCTIONS/fsolve.cc,v retrieving revision 1.15 diff -u -r1.15 fsolve.cc --- src/DLD-FUNCTIONS/fsolve.cc 2000/12/07 05:47:07 1.15 +++ src/DLD-FUNCTIONS/fsolve.cc 2001/08/27 03:24:49 at @ -44,6 +44,9 @@ // Global pointer for user defined function required by hybrd1. static octave_function *fsolve_fcn; +// Extra pass-through arguments for the user defined function. +static octave_value_list fsolve_extra_args; + static NLEqn_options fsolve_opts; // Is this a recursive call? at @ -108,6 +111,9 @@ args(0) = vars; } + // Append the pass-through arguments at the end. + args.append (fsolve_extra_args); + if (fsolve_fcn) { octave_value_list tmp = fsolve_fcn->do_multi_index_op (1, args); at @ -151,10 +157,12 @@ DEFUN_DLD (fsolve, args, nargout, "-*- texinfo -*-\n\ - at deftypefn {Loadable Function} {[@var{x}, @var{info}] =} fsolve (@var{fcn}, at var{x0})\n\ -Given at var{fcn}, the name of a function of the form @code{f (@var{x})}\n\ + at deftypefn {Loadable Function} {[@var{x}, @var{info}] =} fsolve (@var{fcn}, at var{x0}, ...)\n\ +Given at var{fcn}, the name of a function of the form @code{f (@var{x}, ...)}\n\ and an initial starting point at var{x0}, @code{fsolve} solves the set of\n\ -equations such that at code{f(@var{x}) == 0}.\n\ +equations such that at code{f(@var{x}, ...) == 0}.\n\ +Any optional arguments specified in the call to at code{fsolve}\n\ +are passed directly to at var{fcn} dot \n\ at end deftypefn") { octave_value_list retval; at @ -169,7 +177,7 @@ int nargin = args.length (); - if (nargin == 2 && nargout < 4) + if (nargin >= 2 && nargout < 4) { fsolve_fcn = extract_function (args(0), "fsolve", "__fsolve_fcn__", "function y = __fsolve_fcn__ (x) y = ", at @ -182,8 +190,11 @@ if (error_state) FSOLVE_ABORT1 ("expecting vector as second argument"); - if (nargin > 2) - warning ("fsolve: ignoring extra arguments"); + // Save the optional pass-through arguments. + int nextra = nargin - 2; + fsolve_extra_args.resize (nextra); + for (int i = 0; i < nextra; i++) + fsolve_extra_args (i) = args (2 + i); if (nargout > 2) warning ("fsolve: can't compute path output yet"); Index: test/octave.test/nonlin/nonlin.exp =================================================================== RCS file: /cvs/octave/test/octave.test/nonlin/nonlin.exp,v retrieving revision 1.4 diff -u -r1.4 nonlin.exp --- test/octave.test/nonlin/nonlin.exp 1997/02/27 09:01:43 1.4 +++ test/octave.test/nonlin/nonlin.exp 2001/08/27 03:24:49 at @ -6,6 +6,10 @@ set prog_output "info good\nsolution good\nvalue good" do_test fsolve-2.m +set test fsolve-3 +set prog_output "info good\nsolution good\nvalue good" +do_test fsolve-3.m + set test fsolve_options-1 set prog_output "ans = 1" do_test fsolve_options-1.m New file: test/octave.test/nonlin/fsolve-3.m ---------------------------------------------------------------------------- x_opt = [ 0.599054; 2.395931; 2.005014 ]; tol = 1.0e-5; function retval = f (p, a, b, c, d) x = p(1); y = p(2); z = p(3); retval = zeros (3, 1); retval(1) = sin(x) + y**2 + log(z) + a; retval(2) = b*x + 2**y -z**3 + c; retval(3) = x + y + z + d; end [x, info] = fsolve ("f", [ 0.5, 2.0, 2.5 ], -7, 3, 1, -5); val = f (x, -7, 3, 1, -5); info_bad = (info != 1); solution_bad = sum (abs (x - x_opt) > tol); value_bad = sum (abs (val) > tol); if (info_bad) printf ("info bad\n"); else printf ("info good\n"); endif if (solution_bad) printf ("solution bad\n"); else printf ("solution good\n"); endif if (value_bad) printf ("value bad\n"); else printf ("value good\n"); endif ---------------------------------------------------------------------------- -----