Mercurial > hg > octave-nkf
annotate src/DLD-FUNCTIONS/dasrt.cc @ 10154:40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 20 Jan 2010 17:33:41 -0500 |
parents | 2cd940306a06 |
children | d0ce5e973937 |
rev | line source |
---|---|
3990 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 John W. Eaton |
3990 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
3990 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
3990 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
4052 | 27 #include <iostream> |
3990 | 28 #include <string> |
29 | |
30 #include "DASRT.h" | |
31 #include "lo-mappers.h" | |
32 | |
33 #include "defun-dld.h" | |
34 #include "error.h" | |
35 #include "gripes.h" | |
36 #include "oct-obj.h" | |
37 #include "ov-fcn.h" | |
5729 | 38 #include "ov-cell.h" |
3990 | 39 #include "pager.h" |
40 #include "parse.h" | |
41 #include "unwind-prot.h" | |
42 #include "utils.h" | |
43 #include "variables.h" | |
44 | |
3998 | 45 #include "DASRT-opts.cc" |
46 | |
4115 | 47 // Global pointers for user defined function required by dasrt. |
3990 | 48 static octave_function *dasrt_f; |
49 static octave_function *dasrt_j; | |
50 static octave_function *dasrt_cf; | |
51 | |
4140 | 52 // Have we warned about imaginary values returned from user function? |
53 static bool warned_fcn_imaginary = false; | |
54 static bool warned_jac_imaginary = false; | |
55 static bool warned_cf_imaginary = false; | |
56 | |
3990 | 57 // Is this a recursive call? |
58 static int call_depth = 0; | |
59 | |
60 static ColumnVector | |
4628 | 61 dasrt_user_f (const ColumnVector& x, const ColumnVector& xdot, |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
62 double t, octave_idx_type&) |
3990 | 63 { |
64 ColumnVector retval; | |
65 | |
4628 | 66 assert (x.capacity () == xdot.capacity ()); |
3990 | 67 |
4628 | 68 octave_value_list args; |
3990 | 69 |
3993 | 70 args(2) = t; |
4628 | 71 args(1) = xdot; |
72 args(0) = x; | |
3990 | 73 |
74 if (dasrt_f) | |
75 { | |
76 octave_value_list tmp = dasrt_f->do_multi_index_op (1, args); | |
77 | |
78 if (error_state) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
79 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
80 gripe_user_supplied_eval ("dasrt"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
81 return retval; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
82 } |
3990 | 83 |
84 if (tmp.length () > 0 && tmp(0).is_defined ()) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
85 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
86 if (! warned_fcn_imaginary && tmp(0).is_complex_type ()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
87 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
88 warning ("dasrt: ignoring imaginary part returned from user-supplied function"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
89 warned_fcn_imaginary = true; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
90 } |
4140 | 91 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
92 retval = ColumnVector (tmp(0).vector_value ()); |
3990 | 93 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
94 if (error_state || retval.length () == 0) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
95 gripe_user_supplied_eval ("dasrt"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
96 } |
3990 | 97 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
98 gripe_user_supplied_eval ("dasrt"); |
3990 | 99 } |
100 | |
101 return retval; | |
102 } | |
103 | |
104 static ColumnVector | |
105 dasrt_user_cf (const ColumnVector& x, double t) | |
106 { | |
107 ColumnVector retval; | |
108 | |
109 octave_value_list args; | |
110 | |
111 args(1) = t; | |
4628 | 112 args(0) = x; |
3990 | 113 |
114 if (dasrt_cf) | |
115 { | |
116 octave_value_list tmp = dasrt_cf->do_multi_index_op (1, args); | |
117 | |
118 if (error_state) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
119 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
120 gripe_user_supplied_eval ("dasrt"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
121 return retval; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
122 } |
3990 | 123 |
124 if (tmp.length () > 0 && tmp(0).is_defined ()) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
125 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
126 if (! warned_cf_imaginary && tmp(0).is_complex_type ()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
127 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
128 warning ("dasrt: ignoring imaginary part returned from user-supplied constraint function"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
129 warned_cf_imaginary = true; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
130 } |
4140 | 131 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
132 retval = ColumnVector (tmp(0).vector_value ()); |
3990 | 133 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
134 if (error_state || retval.length () == 0) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
135 gripe_user_supplied_eval ("dasrt"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
136 } |
3990 | 137 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
138 gripe_user_supplied_eval ("dasrt"); |
3990 | 139 } |
140 | |
141 return retval; | |
142 } | |
143 | |
144 static Matrix | |
3993 | 145 dasrt_user_j (const ColumnVector& x, const ColumnVector& xdot, |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
146 double t, double cj) |
3990 | 147 { |
148 Matrix retval; | |
149 | |
4628 | 150 assert (x.capacity () == xdot.capacity ()); |
3990 | 151 |
3993 | 152 octave_value_list args; |
153 | |
154 args(3) = cj; | |
155 args(2) = t; | |
4628 | 156 args(1) = xdot; |
157 args(0) = x; | |
3990 | 158 |
3993 | 159 if (dasrt_j) |
160 { | |
161 octave_value_list tmp = dasrt_j->do_multi_index_op (1, args); | |
3990 | 162 |
163 if (error_state) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
164 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
165 gripe_user_supplied_eval ("dasrt"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
166 return retval; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
167 } |
3990 | 168 |
3993 | 169 int tlen = tmp.length (); |
170 if (tlen > 0 && tmp(0).is_defined ()) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
171 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
172 if (! warned_jac_imaginary && tmp(0).is_complex_type ()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
173 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
174 warning ("dasrt: ignoring imaginary part returned from user-supplied jacobian function"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
175 warned_jac_imaginary = true; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
176 } |
4140 | 177 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
178 retval = tmp(0).matrix_value (); |
3990 | 179 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
180 if (error_state || retval.length () == 0) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
181 gripe_user_supplied_eval ("dasrt"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
182 } |
3990 | 183 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
184 gripe_user_supplied_eval ("dasrt"); |
3990 | 185 } |
186 | |
187 return retval; | |
188 } | |
189 | |
190 #define DASRT_ABORT \ | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9377
diff
changeset
|
191 return retval |
3990 | 192 |
193 #define DASRT_ABORT1(msg) \ | |
194 do \ | |
195 { \ | |
4035 | 196 ::error ("dasrt: " msg); \ |
3990 | 197 DASRT_ABORT; \ |
198 } \ | |
199 while (0) | |
200 | |
201 #define DASRT_ABORT2(fmt, arg) \ | |
202 do \ | |
203 { \ | |
4035 | 204 ::error ("dasrt: " fmt, arg); \ |
3990 | 205 DASRT_ABORT; \ |
206 } \ | |
207 while (0) | |
208 | |
3997 | 209 DEFUN_DLD (dasrt, args, nargout, |
3990 | 210 "-*- texinfo -*-\n\ |
4115 | 211 @deftypefn {Loadable Function} {[@var{x}, @var{xdot}, @var{t_out}, @var{istat}, @var{msg}] =} dasrt (@var{fcn} [, @var{g}], @var{x_0}, @var{xdot_0}, @var{t} [, @var{t_crit}])\n\ |
212 Solve the set of differential-algebraic equations\n\ | |
213 @tex\n\ | |
4852 | 214 $$ 0 = f (x, \\dot{x}, t) $$\n\ |
4115 | 215 with\n\ |
216 $$ x(t_0) = x_0, \\dot{x}(t_0) = \\dot{x}_0 $$\n\ | |
217 @end tex\n\ | |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
7017
diff
changeset
|
218 @ifnottex\n\ |
3990 | 219 \n\ |
220 @example\n\ | |
4852 | 221 0 = f (x, xdot, t)\n\ |
4115 | 222 @end example\n\ |
223 \n\ | |
224 with\n\ | |
225 \n\ | |
226 @example\n\ | |
227 x(t_0) = x_0, xdot(t_0) = xdot_0\n\ | |
3990 | 228 @end example\n\ |
229 \n\ | |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
7017
diff
changeset
|
230 @end ifnottex\n\ |
4115 | 231 with functional stopping criteria (root solving).\n\ |
232 \n\ | |
233 The solution is returned in the matrices @var{x} and @var{xdot},\n\ | |
234 with each row in the result matrices corresponding to one of the\n\ | |
235 elements in the vector @var{t_out}. The first element of @var{t}\n\ | |
236 should be @math{t_0} and correspond to the initial state of the\n\ | |
237 system @var{x_0} and its derivative @var{xdot_0}, so that the first\n\ | |
238 row of the output @var{x} is @var{x_0} and the first row\n\ | |
239 of the output @var{xdot} is @var{xdot_0}.\n\ | |
240 \n\ | |
241 The vector @var{t} provides an upper limit on the length of the\n\ | |
242 integration. If the stopping condition is met, the vector\n\ | |
243 @var{t_out} will be shorter than @var{t}, and the final element of\n\ | |
244 @var{t_out} will be the point at which the stopping condition was met,\n\ | |
245 and may not correspond to any element of the vector @var{t}.\n\ | |
246 \n\ | |
8787 | 247 The first argument, @var{fcn}, is a string, inline, or function handle\n\ |
248 that names the function @math{f} to call to compute the vector of\n\ | |
249 residuals for the set of equations. It must have the form\n\ | |
3990 | 250 \n\ |
251 @example\n\ | |
4115 | 252 @var{res} = f (@var{x}, @var{xdot}, @var{t})\n\ |
3990 | 253 @end example\n\ |
254 \n\ | |
255 @noindent\n\ | |
4115 | 256 in which @var{x}, @var{xdot}, and @var{res} are vectors, and @var{t} is a\n\ |
257 scalar.\n\ | |
258 \n\ | |
8787 | 259 If @var{fcn} is a two-element string array or a two-element cell array\n\ |
9067
8970b4b10e9f
Cleanup documentation for quad.texi and diffeq.texi
Rik <rdrider0-list@yahoo.com>
parents:
9064
diff
changeset
|
260 of strings, inline functions, or function handles, the first element names\n\ |
8787 | 261 the function @math{f} described above, and the second element names a\n\ |
262 function to compute the modified Jacobian\n\ | |
3990 | 263 \n\ |
4115 | 264 @tex\n\ |
265 $$\n\ | |
266 J = {\\partial f \\over \\partial x}\n\ | |
267 + c {\\partial f \\over \\partial \\dot{x}}\n\ | |
268 $$\n\ | |
269 @end tex\n\ | |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
7017
diff
changeset
|
270 @ifnottex\n\ |
3990 | 271 \n\ |
4115 | 272 @example\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
273 @group\n\ |
4115 | 274 df df\n\ |
275 jac = -- + c ------\n\ | |
276 dx d xdot\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
277 @end group\n\ |
4115 | 278 @end example\n\ |
279 \n\ | |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
7017
diff
changeset
|
280 @end ifnottex\n\ |
4115 | 281 \n\ |
282 The modified Jacobian function must have the form\n\ | |
283 \n\ | |
284 @example\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
285 @group\n\ |
3990 | 286 \n\ |
4115 | 287 @var{jac} = j (@var{x}, @var{xdot}, @var{t}, @var{c})\n\ |
288 \n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
289 @end group\n\ |
4115 | 290 @end example\n\ |
3990 | 291 \n\ |
4115 | 292 The optional second argument names a function that defines the\n\ |
293 constraint functions whose roots are desired during the integration.\n\ | |
294 This function must have the form\n\ | |
3990 | 295 \n\ |
4115 | 296 @example\n\ |
297 @var{g_out} = g (@var{x}, @var{t})\n\ | |
298 @end example\n\ | |
3990 | 299 \n\ |
4115 | 300 and return a vector of the constraint function values.\n\ |
301 If the value of any of the constraint functions changes sign, @sc{Dasrt}\n\ | |
302 will attempt to stop the integration at the point of the sign change.\n\ | |
303 \n\ | |
304 If the name of the constraint function is omitted, @code{dasrt} solves\n\ | |
4852 | 305 the same problem as @code{daspk} or @code{dassl}.\n\ |
3990 | 306 \n\ |
4115 | 307 Note that because of numerical errors in the constraint functions\n\ |
308 due to roundoff and integration error, @sc{Dasrt} may return false\n\ | |
309 roots, or return the same root at two or more nearly equal values of\n\ | |
310 @var{T}. If such false roots are suspected, the user should consider\n\ | |
311 smaller error tolerances or higher precision in the evaluation of the\n\ | |
312 constraint functions.\n\ | |
3990 | 313 \n\ |
4115 | 314 If a root of some constraint function defines the end of the problem,\n\ |
315 the input to @sc{Dasrt} should nevertheless allow integration to a\n\ | |
316 point slightly past that root, so that @sc{Dasrt} can locate the root\n\ | |
317 by interpolation.\n\ | |
3990 | 318 \n\ |
4115 | 319 The third and fourth arguments to @code{dasrt} specify the initial\n\ |
320 condition of the states and their derivatives, and the fourth argument\n\ | |
321 specifies a vector of output times at which the solution is desired,\n\ | |
322 including the time corresponding to the initial condition.\n\ | |
323 \n\ | |
324 The set of initial states and derivatives are not strictly required to\n\ | |
325 be consistent. In practice, however, @sc{Dassl} is not very good at\n\ | |
326 determining a consistent set for you, so it is best if you ensure that\n\ | |
327 the initial values result in the function evaluating to zero.\n\ | |
3990 | 328 \n\ |
4115 | 329 The sixth argument is optional, and may be used to specify a set of\n\ |
330 times that the DAE solver should not integrate past. It is useful for\n\ | |
331 avoiding difficulties with singularities and points where there is a\n\ | |
332 discontinuity in the derivative.\n\ | |
3990 | 333 \n\ |
4115 | 334 After a successful computation, the value of @var{istate} will be\n\ |
335 greater than zero (consistent with the Fortran version of @sc{Dassl}).\n\ | |
336 \n\ | |
337 If the computation is not successful, the value of @var{istate} will be\n\ | |
338 less than zero and @var{msg} will contain additional information.\n\ | |
3990 | 339 \n\ |
340 You can use the function @code{dasrt_options} to set optional\n\ | |
341 parameters for @code{dasrt}.\n\ | |
5694 | 342 @seealso{daspk, dasrt, lsode}\n\ |
5642 | 343 @end deftypefn") |
3990 | 344 { |
345 octave_value_list retval; | |
346 | |
4140 | 347 warned_fcn_imaginary = false; |
348 warned_jac_imaginary = false; | |
349 warned_cf_imaginary = false; | |
350 | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9377
diff
changeset
|
351 unwind_protect frame; |
3990 | 352 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9377
diff
changeset
|
353 frame.protect_var (call_depth); |
3990 | 354 call_depth++; |
355 | |
356 if (call_depth > 1) | |
357 DASRT_ABORT1 ("invalid recursive call"); | |
358 | |
359 int argp = 0; | |
360 | |
361 int nargin = args.length (); | |
362 | |
363 if (nargin < 4 || nargin > 6) | |
364 { | |
5823 | 365 print_usage (); |
3990 | 366 return retval; |
367 } | |
368 | |
5729 | 369 std::string fcn_name, fname, jac_name, jname; |
3990 | 370 dasrt_f = 0; |
371 dasrt_j = 0; | |
372 dasrt_cf = 0; | |
373 | |
374 // Check all the arguments. Are they the right animals? | |
375 | |
376 // Here's where I take care of f and j in one shot: | |
377 | |
378 octave_value f_arg = args(0); | |
379 | |
5729 | 380 if (f_arg.is_cell ()) |
3990 | 381 { |
5729 | 382 Cell c = f_arg.cell_value (); |
383 if (c.length() == 1) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
384 f_arg = c(0); |
5729 | 385 else if (c.length() == 2) |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
386 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
387 if (c(0).is_function_handle () || c(0).is_inline_function ()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
388 dasrt_f = c(0).function_value (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
389 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
390 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
391 fcn_name = unique_symbol_name ("__dasrt_fcn__"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
392 fname = "function y = "; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
393 fname.append (fcn_name); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
394 fname.append (" (x, xdot, t) y = "); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
395 dasrt_f = extract_function |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
396 (c(0), "dasrt", fcn_name, fname, "; endfunction"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
397 } |
5729 | 398 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
399 if (dasrt_f) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
400 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
401 if (c(1).is_function_handle () || c(1).is_inline_function ()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
402 dasrt_j = c(1).function_value (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
403 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
404 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
405 jac_name = unique_symbol_name ("__dasrt_jac__"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
406 jname = "function jac = "; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
407 jname.append(jac_name); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
408 jname.append (" (x, xdot, t, cj) jac = "); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
409 dasrt_j = extract_function |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
410 (c(1), "dasrt", jac_name, jname, "; endfunction"); |
5729 | 411 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
412 if (!dasrt_j) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
413 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
414 if (fcn_name.length()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
415 clear_function (fcn_name); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
416 dasrt_f = 0; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
417 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
418 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
419 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
420 } |
5729 | 421 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
422 DASRT_ABORT1 ("incorrect number of elements in cell array"); |
5729 | 423 } |
424 | |
425 if (!dasrt_f && ! f_arg.is_cell()) | |
426 { | |
427 if (f_arg.is_function_handle () || f_arg.is_inline_function ()) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
428 dasrt_f = f_arg.function_value (); |
5729 | 429 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
430 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
431 switch (f_arg.rows ()) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
432 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
433 case 1: |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
434 fcn_name = unique_symbol_name ("__dasrt_fcn__"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
435 fname = "function y = "; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
436 fname.append (fcn_name); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
437 fname.append (" (x, xdot, t) y = "); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
438 dasrt_f = extract_function |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
439 (f_arg, "dasrt", fcn_name, fname, "; endfunction"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
440 break; |
3990 | 441 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
442 case 2: |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
443 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
444 string_vector tmp = args(0).all_strings (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
445 |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
446 if (! error_state) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
447 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
448 fcn_name = unique_symbol_name ("__dasrt_fcn__"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
449 fname = "function y = "; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
450 fname.append (fcn_name); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
451 fname.append (" (x, xdot, t) y = "); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
452 dasrt_f = extract_function |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
453 (tmp(0), "dasrt", fcn_name, fname, "; endfunction"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
454 |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
455 if (dasrt_f) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
456 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
457 jac_name = unique_symbol_name ("__dasrt_jac__"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
458 jname = "function jac = "; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
459 jname.append(jac_name); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
460 jname.append (" (x, xdot, t, cj) jac = "); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
461 dasrt_j = extract_function |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
462 (tmp(1), "dasrt", jac_name, jname, "; endfunction"); |
5729 | 463 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
464 if (! dasrt_j) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
465 dasrt_f = 0; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
466 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
467 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
468 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
469 break; |
3990 | 470 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
471 default: |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
472 DASRT_ABORT1 |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
473 ("first arg should be a string or 2-element string array"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
474 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
475 } |
3990 | 476 } |
477 | |
478 if (error_state || (! dasrt_f)) | |
479 DASRT_ABORT; | |
480 | |
481 DAERTFunc func (dasrt_user_f); | |
482 | |
483 argp++; | |
484 | |
5729 | 485 if (args(1).is_function_handle() || args(1).is_inline_function()) |
486 { | |
487 dasrt_cf = args(1).function_value(); | |
488 | |
489 if (! dasrt_cf) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
490 DASRT_ABORT1 ("expecting function name as argument 2"); |
5729 | 491 |
492 argp++; | |
493 | |
494 func.set_constraint_function (dasrt_user_cf); | |
495 } | |
496 else if (args(1).is_string ()) | |
3990 | 497 { |
498 dasrt_cf = is_valid_function (args(1), "dasrt", true); | |
499 if (! dasrt_cf) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
500 DASRT_ABORT1 ("expecting function name as argument 2"); |
3990 | 501 |
502 argp++; | |
503 | |
504 func.set_constraint_function (dasrt_user_cf); | |
505 } | |
506 | |
507 ColumnVector state (args(argp++).vector_value ()); | |
508 | |
509 if (error_state) | |
510 DASRT_ABORT2 ("expecting state vector as argument %d", argp); | |
511 | |
3992 | 512 ColumnVector stateprime (args(argp++).vector_value ()); |
3990 | 513 |
514 if (error_state) | |
515 DASRT_ABORT2 | |
516 ("expecting time derivative of state vector as argument %d", argp); | |
517 | |
3994 | 518 ColumnVector out_times (args(argp++).vector_value ()); |
3990 | 519 |
520 if (error_state) | |
521 DASRT_ABORT2 | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
522 ("expecting output time vector as %s argument %d", argp); |
3990 | 523 |
3994 | 524 double tzero = out_times (0); |
3990 | 525 |
526 ColumnVector crit_times; | |
527 | |
528 bool crit_times_set = false; | |
529 | |
530 if (argp < nargin) | |
531 { | |
532 crit_times = ColumnVector (args(argp++).vector_value ()); | |
533 | |
534 if (error_state) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
535 DASRT_ABORT2 |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
536 ("expecting critical time vector as argument %d", argp); |
3990 | 537 |
538 crit_times_set = true; | |
539 } | |
540 | |
541 if (dasrt_j) | |
542 func.set_jacobian_function (dasrt_user_j); | |
543 | |
544 DASRT_result output; | |
545 | |
3992 | 546 DASRT dae = DASRT (state, stateprime, tzero, func); |
3990 | 547 |
4122 | 548 dae.set_options (dasrt_opts); |
3990 | 549 |
550 if (crit_times_set) | |
551 output = dae.integrate (out_times, crit_times); | |
552 else | |
553 output = dae.integrate (out_times); | |
554 | |
5729 | 555 if (fcn_name.length()) |
556 clear_function (fcn_name); | |
557 if (jac_name.length()) | |
558 clear_function (jac_name); | |
559 | |
3990 | 560 if (! error_state) |
561 { | |
3997 | 562 std::string msg = dae.error_message (); |
563 | |
564 retval(4) = msg; | |
565 retval(3) = static_cast<double> (dae.integration_state ()); | |
566 | |
567 if (dae.integration_ok ()) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
568 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
569 retval(2) = output.times (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
570 retval(1) = output.deriv (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
571 retval(0) = output.state (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
572 } |
3997 | 573 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
574 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
575 retval(2) = Matrix (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
576 retval(1) = Matrix (); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
577 retval(0) = Matrix (); |
3997 | 578 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
579 if (nargout < 4) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
580 error ("dasrt: %s", msg.c_str ()); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
10066
diff
changeset
|
581 } |
3990 | 582 } |
583 | |
584 return retval; | |
585 } | |
586 | |
587 /* | |
588 ;;; Local Variables: *** | |
589 ;;; mode: C++ *** | |
590 ;;; End: *** | |
591 */ |