85 if (tlen > 0 && tmp(0).is_defined ())
89 warning (
"daspk: ignoring imaginary part returned from user-supplied function");
96 ires = tmp(1).int_value ();
134 if (tlen > 0 && tmp(0).is_defined ())
138 warning (
"daspk: ignoring imaginary part returned from user-supplied jacobian function");
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\
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 ());
Matrix integrate(const ColumnVector &tout, Matrix &xdot_out)
virtual octave_value_list do_multi_index_op(int nargout, const octave_value_list &idx)
octave_idx_type rows(void) const
bool integration_ok(void) const
static uint32_t state[624]
OCTINTERP_API void print_usage(void)
octave_idx_type length(void) const
static octave_function * daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
#define DASPK_ABORT1(msg)
static bool warned_fcn_imaginary
bool is_function_handle(void) const
string_vector all_strings(bool pad=false) const
std::string unique_symbol_name(const std::string &basename)
Cell cell_value(void) const
void clear_function(const std::string &nm)
Matrix daspk_user_jacobian(const ColumnVector &x, const ColumnVector &xdot, double t, double cj)
bool is_inline_function(void) const
void set_options(const DASPK_options &opt)
octave_idx_type capacity(void) const
Number of elements in the array.
octave_function * function_value(bool silent=false) const
void warning(const char *fmt,...)
octave_idx_type length(void) const
Number of elements in the array.
std::string error_message(void) const
octave_function * extract_function(const octave_value &arg, const std::string &warn_for, const std::string &fname, const std::string &header, const std::string &trailer)
static bool warned_jac_imaginary
octave_idx_type integration_state(void) const
ColumnVector daspk_user_function(const ColumnVector &x, const ColumnVector &xdot, double t, octave_idx_type &ires)
static octave_function * daspk_jac
static DASPK_options daspk_opts
void gripe_user_supplied_eval(const char *name)
F77_RET_T const double * x
DAEFunc & set_jacobian_function(DAEJacFunc j)