Mercurial > hg > octave-lojdl
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; |