84 if (tmp.
length () > 0 && tmp(0).is_defined ())
86 if (! warned_fcn_imaginary && tmp(0).is_complex_type ())
88 warning (
"dasrt: ignoring imaginary part returned from user-supplied function");
89 warned_fcn_imaginary =
true;
124 if (tmp.
length () > 0 && tmp(0).is_defined ())
126 if (! warned_cf_imaginary && tmp(0).is_complex_type ())
128 warning (
"dasrt: ignoring imaginary part returned from user-supplied constraint function");
129 warned_cf_imaginary =
true;
170 if (tlen > 0 && tmp(0).is_defined ())
172 if (! warned_jac_imaginary && tmp(0).is_complex_type ())
174 warning (
"dasrt: ignoring imaginary part returned from user-supplied jacobian function");
175 warned_jac_imaginary =
true;
178 retval = tmp(0).matrix_value ();
190 #define DASRT_ABORT \
193 #define DASRT_ABORT1(msg) \
196 ::error ("dasrt: " msg); \
201 #define DASRT_ABORT2(fmt, arg) \
204 ::error ("dasrt: " fmt, arg); \
209 DEFUN (dasrt, args, nargout,
211 @deftypefn {Built-in Function} {[@var{x}, @var{xdot}, @var{t_out}, @var{istat}, @var{msg}] =} dasrt (@var{fcn}, [], @var{x_0}, @var{xdot_0}, @var{t})\n\
212 @deftypefnx {Built-in Function} {@dots{} =} dasrt (@var{fcn}, @var{g}, @var{x_0}, @var{xdot_0}, @var{t})\n\
213 @deftypefnx {Built-in Function} {@dots{} =} dasrt (@var{fcn}, [], @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})\n\
214 @deftypefnx {Built-in Function} {@dots{} =} dasrt (@var{fcn}, @var{g}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})\n\
215 Solve the set of differential-algebraic equations\n\
217 $$ 0 = f (x, \\dot{x}, t) $$\n\
219 $$ x(t_0) = x_0, \\dot{x}(t_0) = \\dot{x}_0 $$\n\
224 0 = f (x, xdot, t)\n\
231 x(t_0) = x_0, xdot(t_0) = xdot_0\n\
235 with functional stopping criteria (root solving).\n\
237 The solution is returned in the matrices @var{x} and @var{xdot},\n\
238 with each row in the result matrices corresponding to one of the\n\
239 elements in the vector @var{t_out}. The first element of @var{t}\n\
240 should be @math{t_0} and correspond to the initial state of the\n\
241 system @var{x_0} and its derivative @var{xdot_0}, so that the first\n\
242 row of the output @var{x} is @var{x_0} and the first row\n\
243 of the output @var{xdot} is @var{xdot_0}.\n\
245 The vector @var{t} provides an upper limit on the length of the\n\
246 integration. If the stopping condition is met, the vector\n\
247 @var{t_out} will be shorter than @var{t}, and the final element of\n\
248 @var{t_out} will be the point at which the stopping condition was met,\n\
249 and may not correspond to any element of the vector @var{t}.\n\
251 The first argument, @var{fcn}, is a string, inline, or function handle\n\
252 that names the function @math{f} to call to compute the vector of\n\
253 residuals for the set of equations. It must have the form\n\
256 @var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
260 in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\
263 If @var{fcn} is a two-element string array or a two-element cell array\n\
264 of strings, inline functions, or function handles, the first element names\n\
265 the function @math{f} described above, and the second element names a\n\
266 function to compute the modified Jacobian\n\
270 J = {\\partial f \\over \\partial x}\n\
271 + c {\\partial f \\over \\partial \\dot{x}}\n\
279 jac = -- + c ------\n\
286 The modified Jacobian function must have the form\n\
291 @var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})\n\
296 The optional second argument names a function that defines the\n\
297 constraint functions whose roots are desired during the integration.\n\
298 This function must have the form\n\
301 @var{g_out} = g (@var{x}, @var{t})\n\
305 and return a vector of the constraint function values.\n\
306 If the value of any of the constraint functions changes sign, @sc{dasrt}\n\
307 will attempt to stop the integration at the point of the sign change.\n\
309 If the name of the constraint function is omitted, @code{dasrt} solves\n\
310 the same problem as @code{daspk} or @code{dassl}.\n\
312 Note that because of numerical errors in the constraint functions\n\
313 due to round-off and integration error, @sc{dasrt} may return false\n\
314 roots, or return the same root at two or more nearly equal values of\n\
315 @var{T}. If such false roots are suspected, the user should consider\n\
316 smaller error tolerances or higher precision in the evaluation of the\n\
317 constraint functions.\n\
319 If a root of some constraint function defines the end of the problem,\n\
320 the input to @sc{dasrt} should nevertheless allow integration to a\n\
321 point slightly past that root, so that @sc{dasrt} can locate the root\n\
324 The third and fourth arguments to @code{dasrt} specify the initial\n\
325 condition of the states and their derivatives, and the fourth argument\n\
326 specifies a vector of output times at which the solution is desired,\n\
327 including the time corresponding to the initial condition.\n\
329 The set of initial states and derivatives are not strictly required to\n\
330 be consistent. In practice, however, @sc{dassl} is not very good at\n\
331 determining a consistent set for you, so it is best if you ensure that\n\
332 the initial values result in the function evaluating to zero.\n\
334 The sixth argument is optional, and may be used to specify a set of\n\
335 times that the DAE solver should not integrate past. It is useful for\n\
336 avoiding difficulties with singularities and points where there is a\n\
337 discontinuity in the derivative.\n\
339 After a successful computation, the value of @var{istate} will be\n\
340 greater than zero (consistent with the Fortran version of @sc{dassl}).\n\
342 If the computation is not successful, the value of @var{istate} will be\n\
343 less than zero and @var{msg} will contain additional information.\n\
345 You can use the function @code{dasrt_options} to set optional\n\
346 parameters for @code{dasrt}.\n\
347 @seealso{dasrt_options, daspk, dasrt, lsode}\n\
352 warned_fcn_imaginary =
false;
353 warned_jac_imaginary =
false;
354 warned_cf_imaginary =
false;
366 int nargin = args.length ();
368 if (nargin < 4 || nargin > 6)
374 std::string fcn_name, fname, jac_name, jname;
390 else if (c.
length () == 2)
392 if (c(0).is_function_handle () || c(0).is_inline_function ())
393 dasrt_f = c(0).function_value ();
397 fname =
"function y = ";
398 fname.append (fcn_name);
399 fname.append (
" (x, xdot, t) y = ");
406 if (c(1).is_function_handle () || c(1).is_inline_function ())
407 dasrt_j = c(1).function_value ();
411 jname =
"function jac = ";
412 jname.append (jac_name);
413 jname.append (
" (x, xdot, t, cj) jac = ");
419 if (fcn_name.length ())
427 DASRT_ABORT1 (
"incorrect number of elements in cell array");
430 if (!dasrt_f && ! f_arg.
is_cell ())
436 switch (f_arg.
rows ())
440 fname =
"function y = ";
441 fname.append (fcn_name);
442 fname.append (
" (x, xdot, t) y = ");
454 fname =
"function y = ";
455 fname.append (fcn_name);
456 fname.append (
" (x, xdot, t) y = ");
458 fname,
"; endfunction");
463 jname =
"function jac = ";
464 jname.append (jac_name);
465 jname.append (
" (x, xdot, t, cj) jac = ");
467 jname,
"; endfunction");
478 (
"first arg should be a string or 2-element string array");
490 if (args(1).is_function_handle () || args(1).is_inline_function ())
501 else if (args(1).is_string ())
515 DASRT_ABORT2 (
"expecting state vector as argument %d", argp);
520 DASRT_ABORT2 (
"expecting time derivative of state vector as argument %d",
526 DASRT_ABORT2 (
"expecting output time vector as %s argument %d", argp);
528 double tzero = out_times (0);
532 bool crit_times_set =
false;
536 crit_times =
ColumnVector (args(argp++).vector_value ());
539 DASRT_ABORT2 (
"expecting critical time vector as argument %d", argp);
541 crit_times_set =
true;
549 DASRT dae =
DASRT (state, stateprime, tzero, func);
554 output = dae.
integrate (out_times, crit_times);
558 if (fcn_name.length ())
560 if (jac_name.length ())
572 retval(2) = output.
times ();
573 retval(1) = output.
deriv ();
574 retval(0) = output.
state ();
583 error (
"dasrt: %s", msg.c_str ());