comparison src/DLD-FUNCTIONS/lsode.cc @ 5729:e065f7c18bdc

[project @ 2006-04-03 19:03:30 by jwe]
author jwe
date Mon, 03 Apr 2006 19:03:31 +0000
parents 95d90f781ca8
children 080c08b192d8
comparison
equal deleted inserted replaced
5728:4ff0cb3e1dd1 5729:e065f7c18bdc
36 #include "defun-dld.h" 36 #include "defun-dld.h"
37 #include "error.h" 37 #include "error.h"
38 #include "gripes.h" 38 #include "gripes.h"
39 #include "oct-obj.h" 39 #include "oct-obj.h"
40 #include "ov-fcn.h" 40 #include "ov-fcn.h"
41 #include "ov-cell.h"
41 #include "pager.h" 42 #include "pager.h"
42 #include "pr-output.h" 43 #include "pr-output.h"
43 #include "unwind-prot.h" 44 #include "unwind-prot.h"
44 #include "utils.h" 45 #include "utils.h"
45 #include "variables.h" 46 #include "variables.h"
189 corresponding to an element of the vector @var{t}. The first element\n\ 190 corresponding to an element of the vector @var{t}. The first element\n\
190 of @var{t} should be @math{t_0} and should correspond to the initial\n\ 191 of @var{t} should be @math{t_0} and should correspond to the initial\n\
191 state of the system @var{x_0}, so that the first row of the output\n\ 192 state of the system @var{x_0}, so that the first row of the output\n\
192 is @var{x_0}.\n\ 193 is @var{x_0}.\n\
193 \n\ 194 \n\
194 The first argument, @var{fcn}, is a string that names the function to\n\ 195 The first argument, @var{fcn}, is a string, or cell array of strings,\n\
195 call to compute the vector of right hand sides for the set of equations.\n\ 196 inline or function handles, that names the function to call to compute\n\
196 The function must have the form\n\ 197 the vector of right hand sides for the set of equations. The function\n\
198 must have the form\n\
197 \n\ 199 \n\
198 @example\n\ 200 @example\n\
199 @var{xdot} = f (@var{x}, @var{t})\n\ 201 @var{xdot} = f (@var{x}, @var{t})\n\
200 @end example\n\ 202 @end example\n\
201 \n\ 203 \n\
284 286
285 int nargin = args.length (); 287 int nargin = args.length ();
286 288
287 if (nargin > 2 && nargin < 5 && nargout < 4) 289 if (nargin > 2 && nargin < 5 && nargout < 4)
288 { 290 {
291 std::string fcn_name, fname, jac_name, jname;
289 lsode_fcn = 0; 292 lsode_fcn = 0;
290 lsode_jac = 0; 293 lsode_jac = 0;
291 294
292 octave_value f_arg = args(0); 295 octave_value f_arg = args(0);
293 296
294 switch (f_arg.rows ()) 297 if (f_arg.is_cell ())
295 { 298 {
296 case 1: 299 Cell c = f_arg.cell_value ();
297 lsode_fcn = extract_function 300 if (c.length() == 1)
298 (f_arg, "lsode", "__lsode_fcn__", 301 f_arg = c(0);
299 "function xdot = __lsode_fcn__ (x, t) xdot = ", 302 else if (c.length() == 2)
300 "; endfunction"); 303 {
301 break; 304 if (c(0).is_function_handle () || c(0).is_inline_function ())
302 305 lsode_fcn = c(0).function_value ();
303 case 2: 306 else
304 { 307 {
305 string_vector tmp = f_arg.all_strings (); 308 fcn_name = unique_symbol_name ("__lsode_fcn__");
306 309 fname = "function y = ";
307 if (! error_state) 310 fname.append (fcn_name);
308 { 311 fname.append (" (x, t) y = ");
309 lsode_fcn = extract_function 312 lsode_fcn = extract_function
310 (tmp(0), "lsode", "__lsode_fcn__", 313 (c(0), "lsode", fcn_name, fname, "; endfunction");
311 "function xdot = __lsode_fcn__ (x, t) xdot = ", 314 }
312 "; endfunction"); 315
313 316 if (lsode_fcn)
314 if (lsode_fcn) 317 {
318 if (c(1).is_function_handle () || c(1).is_inline_function ())
319 lsode_jac = c(1).function_value ();
320 else
321 {
322 jac_name = unique_symbol_name ("__lsode_jac__");
323 jname = "function jac = ";
324 jname.append(jac_name);
325 jname.append (" (x, t) jac = ");
326 lsode_jac = extract_function
327 (c(1), "lsode", jac_name, jname, "; endfunction");
328
329 if (!lsode_jac)
330 {
331 if (fcn_name.length())
332 clear_function (fcn_name);
333 lsode_fcn = 0;
334 }
335 }
336 }
337 }
338 else
339 LSODE_ABORT1 ("incorrect number of elements in cell array");
340 }
341
342 if (!lsode_fcn && ! f_arg.is_cell())
343 {
344 if (f_arg.is_function_handle () || f_arg.is_inline_function ())
345 lsode_fcn = f_arg.function_value ();
346 else
347 {
348 switch (f_arg.rows ())
349 {
350 case 1:
351 do
352 {
353 fcn_name = unique_symbol_name ("__lsode_fcn__");
354 fname = "function y = ";
355 fname.append (fcn_name);
356 fname.append (" (x, t) y = ");
357 lsode_fcn = extract_function
358 (f_arg, "lsode", fcn_name, fname, "; endfunction");
359 }
360 while (0);
361 break;
362
363 case 2:
315 { 364 {
316 lsode_jac = extract_function 365 string_vector tmp = f_arg.all_strings ();
317 (tmp(1), "lsode", "__lsode_jac__", 366
318 "function jac = __lsode_jac__ (x, t) jac = ", 367 if (! error_state)
319 "; endfunction"); 368 {
320 369 fcn_name = unique_symbol_name ("__lsode_fcn__");
321 if (! lsode_jac) 370 fname = "function y = ";
322 lsode_fcn = 0; 371 fname.append (fcn_name);
372 fname.append (" (x, t) y = ");
373 lsode_fcn = extract_function
374 (tmp(0), "lsode", fcn_name, fname, "; endfunction");
375
376 if (lsode_fcn)
377 {
378 jac_name = unique_symbol_name ("__lsode_jac__");
379 jname = "function jac = ";
380 jname.append(jac_name);
381 jname.append (" (x, t) jac = ");
382 lsode_jac = extract_function
383 (tmp(1), "lsode", jac_name, jname,
384 "; endfunction");
385
386 if (!lsode_jac)
387 {
388 if (fcn_name.length())
389 clear_function (fcn_name);
390 lsode_fcn = 0;
391 }
392 }
393 }
323 } 394 }
324 } 395 break;
325 } 396
326 break; 397 default:
327 398 LSODE_ABORT1
328 default: 399 ("first arg should be a string or 2-element string array");
329 LSODE_ABORT1 400 }
330 ("first arg should be a string or 2-element string array"); 401 }
331 } 402 }
332 403
333 if (error_state || ! lsode_fcn) 404 if (error_state || ! lsode_fcn)
334 LSODE_ABORT (); 405 LSODE_ABORT ();
335 406
370 if (crit_times_set) 441 if (crit_times_set)
371 output = ode.integrate (out_times, crit_times); 442 output = ode.integrate (out_times, crit_times);
372 else 443 else
373 output = ode.integrate (out_times); 444 output = ode.integrate (out_times);
374 445
446 if (fcn_name.length())
447 clear_function (fcn_name);
448 if (jac_name.length())
449 clear_function (jac_name);
450
375 if (! error_state) 451 if (! error_state)
376 { 452 {
377 std::string msg = ode.error_message (); 453 std::string msg = ode.error_message ();
378 454
379 retval(2) = msg; 455 retval(2) = msg;