85 if (tlen > 0 && tmp(0).is_defined ())
87 if (! warned_fcn_imaginary && tmp(0).is_complex_type ())
89 warning (
"daspk: ignoring imaginary part returned from user-supplied function");
90 warned_fcn_imaginary =
true;
96 ires = tmp(1).int_value ();
134 if (tlen > 0 && tmp(0).is_defined ())
136 if (! warned_jac_imaginary && tmp(0).is_complex_type ())
138 warning (
"daspk: ignoring imaginary part returned from user-supplied jacobian function");
139 warned_jac_imaginary =
true;
142 retval = tmp(0).matrix_value ();
154 #define DASPK_ABORT() \
157 #define DASPK_ABORT1(msg) \
160 ::error ("daspk: " msg); \
165 #define DASPK_ABORT2(fmt, arg) \
168 ::error ("daspk: " fmt, arg); \
173 DEFUN (daspk, args, nargout,
175 @deftypefn {Built-in Function} {[@var{x}, @var{xdot}, @var{istate}, @var{msg}] =} daspk (@var{fcn}, @var{x_0}, @var{xdot_0}, @var{t}, @var{t_crit})\n\
176 Solve the set of differential-algebraic equations\n\
178 $$ 0 = f (x, \\dot{x}, t) $$\n\
180 $$ x(t_0) = x_0, \\dot{x}(t_0) = \\dot{x}_0 $$\n\
185 0 = f (x, xdot, t)\n\
192 x(t_0) = x_0, xdot(t_0) = xdot_0\n\
196 The solution is returned in the matrices @var{x} and @var{xdot},\n\
197 with each row in the result matrices corresponding to one of the\n\
198 elements in the vector @var{t}. The first element of @var{t}\n\
199 should be @math{t_0} and correspond to the initial state of the\n\
200 system @var{x_0} and its derivative @var{xdot_0}, so that the first\n\
201 row of the output @var{x} is @var{x_0} and the first row\n\
202 of the output @var{xdot} is @var{xdot_0}.\n\
204 The first argument, @var{fcn}, is a string, inline, or function handle\n\
205 that names the function @math{f} to call to compute the vector of\n\
206 residuals for the set of equations. It must have the form\n\
209 @var{res} = f (@var{x}, @var{xdot}, @var{t})\n\
213 in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\
216 If @var{fcn} is a two-element string array or a two-element cell array\n\
217 of strings, inline functions, or function handles, the first element names\n\
218 the function @math{f} described above, and the second element names a\n\
219 function to compute the modified Jacobian\n\
222 J = {\\partial f \\over \\partial x}\n\
223 + c {\\partial f \\over \\partial \\dot{x}}\n\
231 jac = -- + c ------\n\
238 The modified Jacobian function must have the form\n\
243 @var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})\n\
248 The second and third arguments to @code{daspk} specify the initial\n\
249 condition of the states and their derivatives, and the fourth argument\n\
250 specifies a vector of output times at which the solution is desired,\n\
251 including the time corresponding to the initial condition.\n\
253 The set of initial states and derivatives are not strictly required to\n\
254 be consistent. If they are not consistent, you must use the\n\
255 @code{daspk_options} function to provide additional information so\n\
256 that @code{daspk} can compute a consistent starting point.\n\
258 The fifth argument is optional, and may be used to specify a set of\n\
259 times that the DAE solver should not integrate past. It is useful for\n\
260 avoiding difficulties with singularities and points where there is a\n\
261 discontinuity in the derivative.\n\
263 After a successful computation, the value of @var{istate} will be\n\
264 greater than zero (consistent with the Fortran version of @sc{daspk}).\n\
266 If the computation is not successful, the value of @var{istate} will be\n\
267 less than zero and @var{msg} will contain additional information.\n\
269 You can use the function @code{daspk_options} to set optional\n\
270 parameters for @code{daspk}.\n\
276 warned_fcn_imaginary =
false;
277 warned_jac_imaginary =
false;
287 int nargin = args.length ();
289 if (nargin > 3 && nargin < 6)
291 std::string fcn_name, fname, jac_name, jname;
302 else if (c.
length () == 2)
304 if (c(0).is_function_handle () || c(0).is_inline_function ())
305 daspk_fcn = c(0).function_value ();
309 fname =
"function y = ";
310 fname.append (fcn_name);
311 fname.append (
" (x, xdot, t) y = ");
313 (c(0),
"daspk", fcn_name, fname,
"; endfunction");
318 if (c(1).is_function_handle () || c(1).is_inline_function ())
319 daspk_jac = c(1).function_value ();
323 jname =
"function jac = ";
324 jname.append (jac_name);
325 jname.append (
" (x, xdot, t, cj) jac = ");
327 jname,
"; endfunction");
331 if (fcn_name.length ())
339 DASPK_ABORT1 (
"incorrect number of elements in cell array");
342 if (!daspk_fcn && ! f_arg.
is_cell ())
348 switch (f_arg.
rows ())
354 fname =
"function y = ";
355 fname.append (fcn_name);
356 fname.append (
" (x, xdot, t) y = ");
358 fname,
"; endfunction");
370 fname =
"function y = ";
371 fname.append (fcn_name);
372 fname.append (
" (x, xdot, t) y = ");
374 fname,
"; endfunction");
379 jname =
"function jac = ";
380 jname.append (jac_name);
381 jname.append (
" (x, xdot, t, cj) jac = ");
388 if (fcn_name.length ())
405 DASPK_ABORT1 (
"expecting state vector as second argument");
410 DASPK_ABORT1 (
"expecting derivative vector as third argument");
415 DASPK_ABORT1 (
"expecting output time vector as fourth argument");
418 int crit_times_set = 0;
424 DASPK_ABORT1 (
"expecting critical time vector as fifth argument");
432 double tzero = out_times (0);
438 DASPK dae (state, deriv, tzero, func);
445 output = dae.
integrate (out_times, deriv_output, crit_times);
447 output = dae.
integrate (out_times, deriv_output);
449 if (fcn_name.length ())
451 if (jac_name.length ())
463 retval(1) = deriv_output;
472 error (
"daspk: %s", msg.c_str ());