Mercurial > hg > octave-nkf
comparison liboctave/LSODE.cc @ 10314:07ebe522dac2
untabify liboctave C++ sources
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 11 Feb 2010 12:23:32 -0500 |
parents | 4c0cdbe0acca |
children | 12884915a8e4 |
comparison
equal
deleted
inserted
replaced
10313:f3b65e1ae355 | 10314:07ebe522dac2 |
---|---|
34 #include "lo-error.h" | 34 #include "lo-error.h" |
35 #include "lo-math.h" | 35 #include "lo-math.h" |
36 #include "quit.h" | 36 #include "quit.h" |
37 | 37 |
38 typedef octave_idx_type (*lsode_fcn_ptr) (const octave_idx_type&, const double&, double*, | 38 typedef octave_idx_type (*lsode_fcn_ptr) (const octave_idx_type&, const double&, double*, |
39 double*, octave_idx_type&); | 39 double*, octave_idx_type&); |
40 | 40 |
41 typedef octave_idx_type (*lsode_jac_ptr) (const octave_idx_type&, const double&, double*, | 41 typedef octave_idx_type (*lsode_jac_ptr) (const octave_idx_type&, const double&, double*, |
42 const octave_idx_type&, const octave_idx_type&, double*, const | 42 const octave_idx_type&, const octave_idx_type&, double*, const |
43 octave_idx_type&); | 43 octave_idx_type&); |
44 | 44 |
45 extern "C" | 45 extern "C" |
46 { | 46 { |
47 F77_RET_T | 47 F77_RET_T |
48 F77_FUNC (dlsode, DLSODE) (lsode_fcn_ptr, octave_idx_type&, double*, double&, | 48 F77_FUNC (dlsode, DLSODE) (lsode_fcn_ptr, octave_idx_type&, double*, double&, |
49 double&, octave_idx_type&, double&, const double*, octave_idx_type&, | 49 double&, octave_idx_type&, double&, const double*, octave_idx_type&, |
50 octave_idx_type&, octave_idx_type&, double*, octave_idx_type&, octave_idx_type*, octave_idx_type&, | 50 octave_idx_type&, octave_idx_type&, double*, octave_idx_type&, octave_idx_type*, octave_idx_type&, |
51 lsode_jac_ptr, octave_idx_type&); | 51 lsode_jac_ptr, octave_idx_type&); |
52 } | 52 } |
53 | 53 |
54 static ODEFunc::ODERHSFunc user_fun; | 54 static ODEFunc::ODERHSFunc user_fun; |
55 static ODEFunc::ODEJacFunc user_jac; | 55 static ODEFunc::ODEJacFunc user_jac; |
56 static ColumnVector *tmp_x; | 56 static ColumnVector *tmp_x; |
57 | 57 |
58 static octave_idx_type | 58 static octave_idx_type |
59 lsode_f (const octave_idx_type& neq, const double& time, double *, | 59 lsode_f (const octave_idx_type& neq, const double& time, double *, |
60 double *deriv, octave_idx_type& ierr) | 60 double *deriv, octave_idx_type& ierr) |
61 { | 61 { |
62 BEGIN_INTERRUPT_WITH_EXCEPTIONS; | 62 BEGIN_INTERRUPT_WITH_EXCEPTIONS; |
63 | 63 |
64 ColumnVector tmp_deriv; | 64 ColumnVector tmp_deriv; |
65 | 65 |
72 if (tmp_deriv.length () == 0) | 72 if (tmp_deriv.length () == 0) |
73 ierr = -1; | 73 ierr = -1; |
74 else | 74 else |
75 { | 75 { |
76 for (octave_idx_type i = 0; i < neq; i++) | 76 for (octave_idx_type i = 0; i < neq; i++) |
77 deriv [i] = tmp_deriv.elem (i); | 77 deriv [i] = tmp_deriv.elem (i); |
78 } | 78 } |
79 | 79 |
80 END_INTERRUPT_WITH_EXCEPTIONS; | 80 END_INTERRUPT_WITH_EXCEPTIONS; |
81 | 81 |
82 return 0; | 82 return 0; |
83 } | 83 } |
84 | 84 |
85 static octave_idx_type | 85 static octave_idx_type |
86 lsode_j (const octave_idx_type& neq, const double& time, double *, | 86 lsode_j (const octave_idx_type& neq, const double& time, double *, |
87 const octave_idx_type&, const octave_idx_type&, double *pd, const octave_idx_type& nrowpd) | 87 const octave_idx_type&, const octave_idx_type&, double *pd, const octave_idx_type& nrowpd) |
88 { | 88 { |
89 BEGIN_INTERRUPT_WITH_EXCEPTIONS; | 89 BEGIN_INTERRUPT_WITH_EXCEPTIONS; |
90 | 90 |
91 Matrix tmp_jac (neq, neq); | 91 Matrix tmp_jac (neq, neq); |
92 | 92 |
125 nn = n; | 125 nn = n; |
126 | 126 |
127 octave_idx_type max_maxord = 0; | 127 octave_idx_type max_maxord = 0; |
128 | 128 |
129 if (integration_method () == "stiff") | 129 if (integration_method () == "stiff") |
130 { | 130 { |
131 max_maxord = 5; | 131 max_maxord = 5; |
132 | 132 |
133 if (jac) | 133 if (jac) |
134 method_flag = 21; | 134 method_flag = 21; |
135 else | 135 else |
136 method_flag = 22; | 136 method_flag = 22; |
137 | 137 |
138 liw = 20 + n; | 138 liw = 20 + n; |
139 lrw = 22 + n * (9 + n); | 139 lrw = 22 + n * (9 + n); |
140 } | 140 } |
141 else | 141 else |
142 { | 142 { |
143 max_maxord = 12; | 143 max_maxord = 12; |
144 | 144 |
145 method_flag = 10; | 145 method_flag = 10; |
146 | 146 |
147 liw = 20; | 147 liw = 20; |
148 lrw = 22 + 16 * n; | 148 lrw = 22 + 16 * n; |
149 } | 149 } |
150 | 150 |
151 maxord = maximum_order (); | 151 maxord = maximum_order (); |
152 | 152 |
153 iwork.resize (liw); | 153 iwork.resize (liw); |
154 | 154 |
155 for (octave_idx_type i = 4; i < 9; i++) | 155 for (octave_idx_type i = 4; i < 9; i++) |
156 iwork(i) = 0; | 156 iwork(i) = 0; |
157 | 157 |
158 rwork.resize (lrw); | 158 rwork.resize (lrw); |
159 | 159 |
160 for (octave_idx_type i = 4; i < 9; i++) | 160 for (octave_idx_type i = 4; i < 9; i++) |
161 rwork(i) = 0; | 161 rwork(i) = 0; |
162 | 162 |
163 if (maxord >= 0) | 163 if (maxord >= 0) |
164 { | 164 { |
165 if (maxord > 0 && maxord <= max_maxord) | 165 if (maxord > 0 && maxord <= max_maxord) |
166 { | 166 { |
167 iwork(4) = maxord; | 167 iwork(4) = maxord; |
168 iopt = 1; | 168 iopt = 1; |
169 } | 169 } |
170 else | 170 else |
171 { | 171 { |
172 (*current_liboctave_error_handler) | 172 (*current_liboctave_error_handler) |
173 ("lsode: invalid value for maximum order"); | 173 ("lsode: invalid value for maximum order"); |
174 integration_error = true; | 174 integration_error = true; |
175 return retval; | 175 return retval; |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 if (stop_time_set) | 179 if (stop_time_set) |
180 { | 180 { |
181 itask = 4; | 181 itask = 4; |
182 rwork(0) = stop_time; | 182 rwork(0) = stop_time; |
183 iopt = 1; | 183 iopt = 1; |
184 } | 184 } |
185 else | 185 else |
186 { | 186 { |
187 itask = 1; | 187 itask = 1; |
188 } | 188 } |
189 | 189 |
190 px = x.fortran_vec (); | 190 px = x.fortran_vec (); |
191 | 191 |
192 piwork = iwork.fortran_vec (); | 192 piwork = iwork.fortran_vec (); |
193 prwork = rwork.fortran_vec (); | 193 prwork = rwork.fortran_vec (); |
206 user_jac = jacobian_function (); | 206 user_jac = jacobian_function (); |
207 | 207 |
208 ColumnVector xdot = (*user_fun) (x, t); | 208 ColumnVector xdot = (*user_fun) (x, t); |
209 | 209 |
210 if (x.length () != xdot.length ()) | 210 if (x.length () != xdot.length ()) |
211 { | 211 { |
212 (*current_liboctave_error_handler) | 212 (*current_liboctave_error_handler) |
213 ("lsode: inconsistent sizes for state and derivative vectors"); | 213 ("lsode: inconsistent sizes for state and derivative vectors"); |
214 | 214 |
215 integration_error = true; | 215 integration_error = true; |
216 return retval; | 216 return retval; |
217 } | 217 } |
218 | 218 |
219 ODEFunc::reset = false; | 219 ODEFunc::reset = false; |
220 | 220 |
221 // LSODE_options | 221 // LSODE_options |
222 | 222 |
224 abs_tol = absolute_tolerance (); | 224 abs_tol = absolute_tolerance (); |
225 | 225 |
226 octave_idx_type abs_tol_len = abs_tol.length (); | 226 octave_idx_type abs_tol_len = abs_tol.length (); |
227 | 227 |
228 if (abs_tol_len == 1) | 228 if (abs_tol_len == 1) |
229 itol = 1; | 229 itol = 1; |
230 else if (abs_tol_len == n) | 230 else if (abs_tol_len == n) |
231 itol = 2; | 231 itol = 2; |
232 else | 232 else |
233 { | 233 { |
234 (*current_liboctave_error_handler) | 234 (*current_liboctave_error_handler) |
235 ("lsode: inconsistent sizes for state and absolute tolerance vectors"); | 235 ("lsode: inconsistent sizes for state and absolute tolerance vectors"); |
236 | 236 |
237 integration_error = true; | 237 integration_error = true; |
238 return retval; | 238 return retval; |
239 } | 239 } |
240 | 240 |
241 double iss = initial_step_size (); | 241 double iss = initial_step_size (); |
242 if (iss >= 0.0) | 242 if (iss >= 0.0) |
243 { | 243 { |
244 rwork(4) = iss; | 244 rwork(4) = iss; |
245 iopt = 1; | 245 iopt = 1; |
246 } | 246 } |
247 | 247 |
248 double maxss = maximum_step_size (); | 248 double maxss = maximum_step_size (); |
249 if (maxss >= 0.0) | 249 if (maxss >= 0.0) |
250 { | 250 { |
251 rwork(5) = maxss; | 251 rwork(5) = maxss; |
252 iopt = 1; | 252 iopt = 1; |
253 } | 253 } |
254 | 254 |
255 double minss = minimum_step_size (); | 255 double minss = minimum_step_size (); |
256 if (minss >= 0.0) | 256 if (minss >= 0.0) |
257 { | 257 { |
258 rwork(6) = minss; | 258 rwork(6) = minss; |
259 iopt = 1; | 259 iopt = 1; |
260 } | 260 } |
261 | 261 |
262 octave_idx_type sl = step_limit (); | 262 octave_idx_type sl = step_limit (); |
263 if (sl > 0) | 263 if (sl > 0) |
264 { | 264 { |
265 iwork(5) = sl; | 265 iwork(5) = sl; |
266 iopt = 1; | 266 iopt = 1; |
267 } | 267 } |
268 | 268 |
269 pabs_tol = abs_tol.fortran_vec (); | 269 pabs_tol = abs_tol.fortran_vec (); |
270 | 270 |
271 LSODE_options::reset = false; | 271 LSODE_options::reset = false; |
272 } | 272 } |
273 | 273 |
274 F77_XFCN (dlsode, DLSODE, (lsode_f, nn, px, t, tout, itol, rel_tol, | 274 F77_XFCN (dlsode, DLSODE, (lsode_f, nn, px, t, tout, itol, rel_tol, |
275 pabs_tol, itask, istate, iopt, prwork, lrw, | 275 pabs_tol, itask, istate, iopt, prwork, lrw, |
276 piwork, liw, lsode_j, method_flag)); | 276 piwork, liw, lsode_j, method_flag)); |
277 | 277 |
278 switch (istate) | 278 switch (istate) |
279 { | 279 { |
280 case 1: // prior to initial integration step. | 280 case 1: // prior to initial integration step. |
281 case 2: // lsode was successful. | 281 case 2: // lsode was successful. |
286 case -1: // excess work done on this call (perhaps wrong mf). | 286 case -1: // excess work done on this call (perhaps wrong mf). |
287 case -2: // excess accuracy requested (tolerances too small). | 287 case -2: // excess accuracy requested (tolerances too small). |
288 case -3: // invalid input detected (see printed message). | 288 case -3: // invalid input detected (see printed message). |
289 case -4: // repeated error test failures (check all inputs). | 289 case -4: // repeated error test failures (check all inputs). |
290 case -5: // repeated convergence failures (perhaps bad jacobian | 290 case -5: // repeated convergence failures (perhaps bad jacobian |
291 // supplied or wrong choice of mf or tolerances). | 291 // supplied or wrong choice of mf or tolerances). |
292 case -6: // error weight became zero during problem. (solution | 292 case -6: // error weight became zero during problem. (solution |
293 // component i vanished, and atol or atol(i) = 0.) | 293 // component i vanished, and atol or atol(i) = 0.) |
294 case -13: // return requested in user-supplied function. | 294 case -13: // return requested in user-supplied function. |
295 integration_error = true; | 295 integration_error = true; |
296 break; | 296 break; |
297 | 297 |
298 default: | 298 default: |
299 integration_error = true; | 299 integration_error = true; |
300 (*current_liboctave_error_handler) | 300 (*current_liboctave_error_handler) |
301 ("unrecognized value of istate (= %d) returned from lsode", | 301 ("unrecognized value of istate (= %d) returned from lsode", |
302 istate); | 302 istate); |
303 break; | 303 break; |
304 } | 304 } |
305 | 305 |
306 return retval; | 306 return retval; |
307 } | 307 } |
322 break; | 322 break; |
323 | 323 |
324 case 2: | 324 case 2: |
325 retval = "successful exit"; | 325 retval = "successful exit"; |
326 break; | 326 break; |
327 | 327 |
328 case 3: | 328 case 3: |
329 retval = "prior to continuation call with modified parameters"; | 329 retval = "prior to continuation call with modified parameters"; |
330 break; | 330 break; |
331 | 331 |
332 case -1: | 332 case -1: |
333 retval = std::string ("excess work on this call (t = ") | 333 retval = std::string ("excess work on this call (t = ") |
334 + t_curr + "; perhaps wrong integration method)"; | 334 + t_curr + "; perhaps wrong integration method)"; |
335 break; | 335 break; |
336 | 336 |
337 case -2: | 337 case -2: |
338 retval = "excess accuracy requested (tolerances too small)"; | 338 retval = "excess accuracy requested (tolerances too small)"; |
339 break; | 339 break; |
342 retval = "invalid input detected (see printed message)"; | 342 retval = "invalid input detected (see printed message)"; |
343 break; | 343 break; |
344 | 344 |
345 case -4: | 345 case -4: |
346 retval = std::string ("repeated error test failures (t = ") | 346 retval = std::string ("repeated error test failures (t = ") |
347 + t_curr + "check all inputs)"; | 347 + t_curr + "check all inputs)"; |
348 break; | 348 break; |
349 | 349 |
350 case -5: | 350 case -5: |
351 retval = std::string ("repeated convergence failures (t = ") | 351 retval = std::string ("repeated convergence failures (t = ") |
352 + t_curr | 352 + t_curr |
353 + "perhaps bad jacobian supplied or wrong choice of integration method or tolerances)"; | 353 + "perhaps bad jacobian supplied or wrong choice of integration method or tolerances)"; |
354 break; | 354 break; |
355 | 355 |
356 case -6: | 356 case -6: |
357 retval = std::string ("error weight became zero during problem. (t = ") | 357 retval = std::string ("error weight became zero during problem. (t = ") |
358 + t_curr | 358 + t_curr |
359 + "; solution component i vanished, and atol or atol(i) == 0)"; | 359 + "; solution component i vanished, and atol or atol(i) == 0)"; |
360 break; | 360 break; |
361 | 361 |
362 case -13: | 362 case -13: |
363 retval = "return requested in user-supplied function (t = " | 363 retval = "return requested in user-supplied function (t = " |
364 + t_curr + ")"; | 364 + t_curr + ")"; |
365 break; | 365 break; |
366 | 366 |
367 default: | 367 default: |
368 retval = "unknown error state"; | 368 retval = "unknown error state"; |
369 break; | 369 break; |
383 if (n_out > 0 && n > 0) | 383 if (n_out > 0 && n > 0) |
384 { | 384 { |
385 retval.resize (n_out, n); | 385 retval.resize (n_out, n); |
386 | 386 |
387 for (octave_idx_type i = 0; i < n; i++) | 387 for (octave_idx_type i = 0; i < n; i++) |
388 retval.elem (0, i) = x.elem (i); | 388 retval.elem (0, i) = x.elem (i); |
389 | 389 |
390 for (octave_idx_type j = 1; j < n_out; j++) | 390 for (octave_idx_type j = 1; j < n_out; j++) |
391 { | 391 { |
392 ColumnVector x_next = do_integrate (tout.elem (j)); | 392 ColumnVector x_next = do_integrate (tout.elem (j)); |
393 | 393 |
394 if (integration_error) | 394 if (integration_error) |
395 return retval; | 395 return retval; |
396 | 396 |
397 for (octave_idx_type i = 0; i < n; i++) | 397 for (octave_idx_type i = 0; i < n; i++) |
398 retval.elem (j, i) = x_next.elem (i); | 398 retval.elem (j, i) = x_next.elem (i); |
399 } | 399 } |
400 } | 400 } |
401 | 401 |
402 return retval; | 402 return retval; |
403 } | 403 } |
404 | 404 |
413 if (n_out > 0 && n > 0) | 413 if (n_out > 0 && n > 0) |
414 { | 414 { |
415 retval.resize (n_out, n); | 415 retval.resize (n_out, n); |
416 | 416 |
417 for (octave_idx_type i = 0; i < n; i++) | 417 for (octave_idx_type i = 0; i < n; i++) |
418 retval.elem (0, i) = x.elem (i); | 418 retval.elem (0, i) = x.elem (i); |
419 | 419 |
420 octave_idx_type n_crit = tcrit.capacity (); | 420 octave_idx_type n_crit = tcrit.capacity (); |
421 | 421 |
422 if (n_crit > 0) | 422 if (n_crit > 0) |
423 { | 423 { |
424 octave_idx_type i_crit = 0; | 424 octave_idx_type i_crit = 0; |
425 octave_idx_type i_out = 1; | 425 octave_idx_type i_out = 1; |
426 double next_crit = tcrit.elem (0); | 426 double next_crit = tcrit.elem (0); |
427 double next_out; | 427 double next_out; |
428 while (i_out < n_out) | 428 while (i_out < n_out) |
429 { | 429 { |
430 bool do_restart = false; | 430 bool do_restart = false; |
431 | 431 |
432 next_out = tout.elem (i_out); | 432 next_out = tout.elem (i_out); |
433 if (i_crit < n_crit) | 433 if (i_crit < n_crit) |
434 next_crit = tcrit.elem (i_crit); | 434 next_crit = tcrit.elem (i_crit); |
435 | 435 |
436 octave_idx_type save_output; | 436 octave_idx_type save_output; |
437 double t_out; | 437 double t_out; |
438 | 438 |
439 if (next_crit == next_out) | 439 if (next_crit == next_out) |
440 { | 440 { |
441 set_stop_time (next_crit); | 441 set_stop_time (next_crit); |
442 t_out = next_out; | 442 t_out = next_out; |
443 save_output = 1; | 443 save_output = 1; |
444 i_out++; | 444 i_out++; |
445 i_crit++; | 445 i_crit++; |
446 do_restart = true; | 446 do_restart = true; |
447 } | 447 } |
448 else if (next_crit < next_out) | 448 else if (next_crit < next_out) |
449 { | 449 { |
450 if (i_crit < n_crit) | 450 if (i_crit < n_crit) |
451 { | 451 { |
452 set_stop_time (next_crit); | 452 set_stop_time (next_crit); |
453 t_out = next_crit; | 453 t_out = next_crit; |
454 save_output = 0; | 454 save_output = 0; |
455 i_crit++; | 455 i_crit++; |
456 do_restart = true; | 456 do_restart = true; |
457 } | 457 } |
458 else | 458 else |
459 { | 459 { |
460 clear_stop_time (); | 460 clear_stop_time (); |
461 t_out = next_out; | 461 t_out = next_out; |
462 save_output = 1; | 462 save_output = 1; |
463 i_out++; | 463 i_out++; |
464 } | 464 } |
465 } | 465 } |
466 else | 466 else |
467 { | 467 { |
468 set_stop_time (next_crit); | 468 set_stop_time (next_crit); |
469 t_out = next_out; | 469 t_out = next_out; |
470 save_output = 1; | 470 save_output = 1; |
471 i_out++; | 471 i_out++; |
472 } | 472 } |
473 | 473 |
474 ColumnVector x_next = do_integrate (t_out); | 474 ColumnVector x_next = do_integrate (t_out); |
475 | 475 |
476 if (integration_error) | 476 if (integration_error) |
477 return retval; | 477 return retval; |
478 | 478 |
479 if (save_output) | 479 if (save_output) |
480 { | 480 { |
481 for (octave_idx_type i = 0; i < n; i++) | 481 for (octave_idx_type i = 0; i < n; i++) |
482 retval.elem (i_out-1, i) = x_next.elem (i); | 482 retval.elem (i_out-1, i) = x_next.elem (i); |
483 } | 483 } |
484 | 484 |
485 if (do_restart) | 485 if (do_restart) |
486 force_restart (); | 486 force_restart (); |
487 } | 487 } |
488 } | 488 } |
489 else | 489 else |
490 { | 490 { |
491 retval = do_integrate (tout); | 491 retval = do_integrate (tout); |
492 | 492 |
493 if (integration_error) | 493 if (integration_error) |
494 return retval; | 494 return retval; |
495 } | 495 } |
496 } | 496 } |
497 | 497 |
498 return retval; | 498 return retval; |
499 } | 499 } |