LILAC
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lsoda.cpp
Go to the documentation of this file.
1 /*
2  This is a C version of the LSODA library. I acquired the original
3  source code from this web page:
4 
5  http://www.ccl.net/cca/software/SOURCES/C/kinetics2/index.shtml
6 
7  I merged several C files into one and added a simpler interface. I
8  also made the array start from zero in functions called by lsoda(),
9  and fixed two minor bugs: a) small memory leak in freevectors(); and
10  b) misuse of lsoda() in the example.
11 
12  The original source code came with no license or copyright
13  information. I now release this file under the MIT/X11 license. All
14  authors' notes are kept in this file.
15 
16  - Heng Li <lh3lh3@gmail.com>
17  */
18 
19 /* The MIT License
20 
21  Copyright (c) 2009 Genome Research Ltd (GRL).
22 
23  Permission is hereby granted, free of charge, to any person obtaining
24  a copy of this software and associated documentation files (the
25  "Software"), to deal in the Software without restriction, including
26  without limitation the rights to use, copy, modify, merge, publish,
27  distribute, sublicense, and/or sell copies of the Software, and to
28  permit persons to whom the Software is furnished to do so, subject to
29  the following conditions:
30 
31  The above copyright notice and this permission notice shall be
32  included in all copies or substantial portions of the Software.
33 
34  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
37  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
38  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
39  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41  SOFTWARE.
42 */
43 
44 /* Contact: Heng Li <lh3@sanger.ac.uk> */
45 
46 typedef void (*_lsoda_f) (double, double *, double *, void *);
47 
48 /************
49  * idamax.c *
50  ************/
51 
52 #include <math.h>
53 #include "../utils/defs.h"
54 static int
55 idamax(size_t n, double* dx, size_t incx)
56 
57 /* Purpose : Find largest component of double vector dx
58 
59 
60  --- Input ---
61 
62  n : number of elements in input vector
63  dx : double vector with n+1 elements, dx[0] is not used
64  incx : storage spacing between elements of dx
65 
66 
67  --- Output ---
68 
69  idamax : smallest index, 0 if n <= 0
70 
71 
72  Find smallest index of maximum magnitude of dx.
73  idamax = first i, i=1 to n, to minimize fabs( dx[1-incx+i*incx] ).
74 
75 */
76 
77 {
78  double dmax, xmag;
79  int i, ii, xindex;
80 
81  xindex = 0;
82  if (n <= 0)
83  return xindex;
84  xindex = 1;
85  if (n <= 1 || incx <= 0)
86  return xindex;
87 
88 /* Code for increments not equal to 1. */
89 
90  if (incx != 1) {
91  dmax = fabs(dx[1]);
92  ii = 2;
93  for (i = 1 + incx; i <= n * incx; i = i + incx) {
94  xmag = fabs(dx[i]);
95  if (xmag > dmax) {
96  xindex = ii;
97  dmax = xmag;
98  }
99  ii++;
100  }
101  return xindex;
102  }
103 /* Code for increments equal to 1. */
104 
105  dmax = fabs(dx[1]);
106  for (i = 2; i <= n; i++) {
107  xmag = fabs(dx[i]);
108  if (xmag > dmax) {
109  xindex = i;
110  dmax = xmag;
111  }
112  }
113  return xindex;
114 
115 }
116 
117 /***********
118  * dscal.c *
119  ***********/
120 
121 void
122 dscal(size_t n, double da, double* dx, size_t incx)
123 
124 /* Purpose : scalar vector multiplication
125 
126  dx = da * dx
127 
128 
129  --- Input ---
130 
131  n : number of elements in input vector
132  da : double scale factor
133  dx : double vector with n+1 elements, dx[0] is not used
134  incx : storage spacing between elements of dx
135 
136 
137  --- Output ---
138 
139  dx = da * dx, unchanged if n <= 0
140 
141 
142  For i = 0 to n-1, replace dx[1+i*incx] with
143  da * dx[1+i*incx].
144 
145 */
146 
147 {
148  int m, i;
149 
150  if (n <= 0)
151  return;
152 
153 /* Code for increments not equal to 1. */
154 
155  if (incx != 1) {
156  for (i = 1; i <= n * incx; i = i + incx)
157  dx[i] = da * dx[i];
158  return;
159  }
160 /* Code for increments equal to 1. */
161 
162 /* Clean-up loop so remaining vector length is a multiple of 5. */
163 
164  m = n % 5;
165  if (m != 0) {
166  for (i = 1; i <= m; i++)
167  dx[i] = da * dx[i];
168  if (n < 5)
169  return;
170  }
171  for (i = m + 1; i <= n; i = i + 5) {
172  dx[i] = da * dx[i];
173  dx[i + 1] = da * dx[i + 1];
174  dx[i + 2] = da * dx[i + 2];
175  dx[i + 3] = da * dx[i + 3];
176  dx[i + 4] = da * dx[i + 4];
177  }
178  return;
179 
180 }
181 
182 /**********
183  * ddot.c *
184  **********/
185 
186 static double
187 ddot(size_t n, double* dx, size_t incx, double* dy, size_t incy)
188 
189 /*
190  Purpose : Inner product dx . dy
191 
192 
193  --- Input ---
194 
195  n : number of elements in input vector(s)
196  dx : double vector with n+1 elements, dx[0] is not used
197  incx : storage spacing between elements of dx
198  dy : double vector with n+1 elements, dy[0] is not used
199  incy : storage spacing between elements of dy
200 
201 
202  --- Output ---
203 
204  ddot : dot product dx . dy, 0 if n <= 0
205 
206 
207  ddot = sum for i = 0 to n-1 of
208  dx[lx+i*incx] * dy[ly+i*incy] where lx = 1 if
209  incx >= 0, else lx = (-incx)*(n-1)+1, and ly
210  is defined in a similar way using incy.
211 
212 */
213 
214 {
215  double dotprod;
216  int ix, iy, i, m;
217 
218  dotprod = 0.;
219  if (n <= 0)
220  return dotprod;
221 
222 /* Code for unequal or nonpositive increments. */
223 
224  if (incx != incy || incx < 1) {
225  ix = 1;
226  iy = 1;
227  if (incx < 0)
228  ix = (-n + 1) * incx + 1;
229  if (incy < 0)
230  iy = (-n + 1) * incy + 1;
231  for (i = 1; i <= n; i++) {
232  dotprod = dotprod + dx[ix] * dy[iy];
233  ix = ix + incx;
234  iy = iy + incy;
235  }
236  return dotprod;
237  }
238 /* Code for both increments equal to 1. */
239 
240 /* Clean-up loop so remaining vector length is a multiple of 5. */
241 
242  if (incx == 1) {
243  m = n % 5;
244  if (m != 0) {
245  for (i = 1; i <= m; i++)
246  dotprod = dotprod + dx[i] * dy[i];
247  if (n < 5)
248  return dotprod;
249  }
250  for (i = m + 1; i <= n; i = i + 5)
251  dotprod = dotprod + dx[i] * dy[i] + dx[i + 1] * dy[i + 1] +
252  dx[i + 2] * dy[i + 2] + dx[i + 3] * dy[i + 3] +
253  dx[i + 4] * dy[i + 4];
254  return dotprod;
255  }
256 /* Code for positive equal nonunit increments. */
257 
258  for (i = 1; i <= n * incx; i = i + incx)
259  dotprod = dotprod + dx[i] * dy[i];
260  return dotprod;
261 
262 }
263 
264 /***********
265  * daxpy.c *
266  ***********/
267 
268 /*
269 From tam@dragonfly.wri.com Wed Apr 24 15:48:31 1991
270 Return-Path: <tam>
271 Date: Wed, 24 Apr 91 17:48:43 CDT
272 From: tam@dragonfly.wri.com
273 To: whitbeck@sanjuan.wrc.unr.edu
274 */
275 
276 static void
277 daxpy(size_t n, double da, double* restr dx, size_t incx, double* restr dy, size_t incy)
278 
279 /*
280  Purpose : To compute
281 
282  dy = da * dx + dy
283 
284 
285  --- Input ---
286 
287  n : number of elements in input vector(s)
288  da : double scalar multiplier
289  dx : double vector with n+1 elements, dx[0] is not used
290  incx : storage spacing between elements of dx
291  dy : double vector with n+1 elements, dy[0] is not used
292  incy : storage spacing between elements of dy
293 
294 
295  --- Output ---
296 
297  dy = da * dx + dy, unchanged if n <= 0
298 
299 
300  For i = 0 to n-1, replace dy[ly+i*incy] with
301  da*dx[lx+i*incx] + dy[ly+i*incy], where lx = 1
302  if incx >= 0, else lx = (-incx)*(n-1)+1 and ly is
303  defined in a similar way using incy.
304 
305 */
306 
307 {
308  int ix, iy, i, m;
309 
310  if (n < 0 || da == 0.)
311  return;
312 
313 /* Code for nonequal or nonpositive increments. */
314 
315  if (incx != incy || incx < 1) {
316  ix = 1;
317  iy = 1;
318  if (incx < 0)
319  ix = (-n + 1) * incx + 1;
320  if (incy < 0)
321  iy = (-n + 1) * incy + 1;
322  for (i = 1; i <= n; i++) {
323  dy[iy] = dy[iy] + da * dx[ix];
324  ix = ix + incx;
325  iy = iy + incy;
326  }
327  return;
328  }
329 /* Code for both increments equal to 1. */
330 
331 /* Clean-up loop so remaining vector length is a multiple of 4. */
332 
333  if (incx == 1) {
334  m = n % 4;
335  if (m != 0) {
336  for (i = 1; i <= m; i++)
337  dy[i] = dy[i] + da * dx[i];
338  if (n < 4)
339  return;
340  }
341  for (i = m + 1; i <= n; i = i + 4) {
342  dy[i] = dy[i] + da * dx[i];
343  dy[i + 1] = dy[i + 1] + da * dx[i + 1];
344  dy[i + 2] = dy[i + 2] + da * dx[i + 2];
345  dy[i + 3] = dy[i + 3] + da * dx[i + 3];
346  }
347  return;
348  }
349 /* Code for equal, positive, nonunit increments. */
350 
351  for (i = 1; i <= n * incx; i = i + incx)
352  dy[i] = da * dx[i] + dy[i];
353  return;
354 
355 }
356 
357 /***********
358  * dgesl.c *
359  ***********/
360 
361 static void
362 dgesl(double *restr * restr a, int n, int* ipvt, double* restr b, int job)
363 
364 /*
365  Purpose : dgesl solves the linear system
366  a * x = b or Transpose(a) * x = b
367  using the factors computed by dgeco or degfa.
368 
369 
370  On Entry :
371 
372  a : double matrix of dimension ( n+1, n+1 ),
373  the output from dgeco or dgefa.
374  The 0-th row and column are not used.
375  n : the row dimension of a.
376  ipvt : the pivot vector from degco or dgefa.
377  b : the right hand side vector.
378  job : = 0 to solve a * x = b,
379  = nonzero to solve Transpose(a) * x = b.
380 
381 
382  On Return :
383 
384  b : the solution vector x.
385 
386 
387  Error Condition :
388 
389  A division by zero will occur if the input factor contains
390  a zero on the diagonal. Technically this indicates
391  singularity but it is often caused by improper argments or
392  improper setting of the pointers of a. It will not occur
393  if the subroutines are called correctly and if dgeco has
394  set rcond > 0 or dgefa has set info = 0.
395 
396 
397  BLAS : daxpy, ddot
398 */
399 
400 {
401  int nm1, k, j;
402  double t;
403 
404  nm1 = n - 1;
405 
406 /*
407  Job = 0, solve a * x = b.
408 */
409  if (job == 0) {
410 /*
411  First solve L * y = b.
412 */
413  for (k = 1; k <= n; k++) {
414  t = ddot(k - 1, a[k], 1, b, 1);
415  b[k] = (b[k] - t) / a[k][k];
416  }
417 /*
418  Now solve U * x = y.
419 */
420  for (k = n - 1; k >= 1; k--) {
421  b[k] = b[k] + ddot(n - k, a[k] + k, 1, b + k, 1);
422  j = ipvt[k];
423  if (j != k) {
424  t = b[j];
425  b[j] = b[k];
426  b[k] = t;
427  }
428  }
429  return;
430  }
431 /*
432  Job = nonzero, solve Transpose(a) * x = b.
433 
434  First solve Transpose(U) * y = b.
435 */
436  for (k = 1; k <= n - 1; k++) {
437  j = ipvt[k];
438  t = b[j];
439  if (j != k) {
440  b[j] = b[k];
441  b[k] = t;
442  }
443  daxpy(n - k, t, a[k] + k, 1, b + k, 1);
444  }
445 /*
446  Now solve Transpose(L) * x = y.
447 */
448  for (k = n; k >= 1; k--) {
449  b[k] = b[k] / a[k][k];
450  t = -b[k];
451  daxpy(k - 1, t, a[k], 1, b, 1);
452  }
453 
454 }
455 
456 /***********
457  * dgefa.c *
458  ***********/
459 
460 void
461 dgefa(double** a, int n, int* ipvt, int* info)
462 
463 /*
464  Purpose : dgefa factors a double matrix by Gaussian elimination.
465 
466  dgefa is usually called by dgeco, but it can be called directly
467  with a saving in time if rcond is not needed.
468  (Time for dgeco) = (1+9/n)*(time for dgefa).
469 
470  This c version uses algorithm kji rather than the kij in dgefa.f.
471  Note that the fortran version input variable lda is not needed.
472 
473 
474  On Entry :
475 
476  a : double matrix of dimension ( n+1, n+1 ),
477  the 0-th row and column are not used.
478  a is created using NewDoubleMatrix, hence
479  lda is unnecessary.
480  n : the row dimension of a.
481 
482  On Return :
483 
484  a : a lower triangular matrix and the multipliers
485  which were used to obtain it. The factorization
486  can be written a = L * U where U is a product of
487  permutation and unit upper triangular matrices
488  and L is lower triangular.
489  ipvt : an n+1 integer vector of pivot indices.
490  *info : = 0 normal value,
491  = k if U[k][k] == 0. This is not an error
492  condition for this subroutine, but it does
493  indicate that dgesl or dgedi will divide by
494  zero if called. Use rcond in dgeco for
495  a reliable indication of singularity.
496 
497  Notice that the calling program must use &info.
498 
499  BLAS : daxpy, dscal, idamax
500 */
501 
502 {
503  int j, k, i;
504  double t;
505 
506 /* Gaussian elimination with partial pivoting. */
507 
508  *info = 0;
509  for (k = 1; k <= n - 1; k++) {
510 /*
511  Find j = pivot index. Note that a[k]+k-1 is the address of
512  the 0-th element of the row vector whose 1st element is a[k][k].
513 */
514  j = idamax(n - k + 1, a[k] + k - 1, 1) + k - 1;
515  ipvt[k] = j;
516 /*
517  Zero pivot implies this row already triangularized.
518 */
519  if (a[k][j] == 0.) {
520  *info = k;
521  continue;
522  }
523 /*
524  Interchange if necessary.
525 */
526  if (j != k) {
527  t = a[k][j];
528  a[k][j] = a[k][k];
529  a[k][k] = t;
530  }
531 /*
532  Compute multipliers.
533 */
534  t = -1. / a[k][k];
535  dscal(n - k, t, a[k] + k, 1);
536 /*
537  Column elimination with row indexing.
538 */
539  for (i = k + 1; i <= n; i++) {
540  t = a[i][j];
541  if (j != k) {
542  a[i][j] = a[i][k];
543  a[i][k] = t;
544  }
545  daxpy(n - k, t, a[k] + k, 1, a[i] + k, 1);
546  }
547  } /* end k-loop */
548 
549  ipvt[n] = n;
550  if (a[n][n] == 0.)
551  *info = n;
552 
553 }
554 
555 /***********
556  * lsoda.c *
557  ***********/
558 
559 /*
560 From tam@dragonfly.wri.com Wed Apr 24 01:35:52 1991
561 Return-Path: <tam>
562 Date: Wed, 24 Apr 91 03:35:24 CDT
563 From: tam@dragonfly.wri.com
564 To: whitbeck@wheeler.wrc.unr.edu
565 Subject: lsoda.c
566 Cc: augenbau@sparc0.brc.uconn.edu
567 
568 
569 I'm told by Steve Nichols at Georgia Tech that you are interested in
570 a stiff integrator. Here's a translation of the fortran code LSODA.
571 
572 Please note
573 that there is no comment. The interface is the same as the FORTRAN
574 code and I believe the documentation in LSODA will suffice.
575 As usual, a free software comes with no guarantee.
576 
577 Hon Wah Tam
578 Wolfram Research, Inc.
579 tam@wri.com
580 */
581 
582 #include <stdio.h>
583 #include <math.h>
584 #include <stdlib.h>
585 
586 #define max( a , b ) ( (a) > (b) ? (a) : (b) )
587 #define min( a , b ) ( (a) < (b) ? (a) : (b) )
588 
589 #define ETA 2.2204460492503131e-16
590 
591 static void stoda(int neq, double *y, _lsoda_f f, void *_data);
592 static void correction(int neq, double *y, _lsoda_f f, int *corflag, double pnorm, double *del, double *delp, double *told,
593  int *ncf, double *rh, int *m, void *_data);
594 static void prja(int neq, double *y, _lsoda_f f, void *_data);
595 static void terminate(int *istate);
596 static void terminate2(double *y, double *t);
597 static void successreturn(double *y, double *t, int itask, int ihit, double tcrit, int *istate);
598 static void freevectors(void); /* this function does nothing */
599 static void _freevectors(void);
600 static void ewset(int itol, double *rtol, double *atol, double *ycur);
601 static void resetcoeff(void);
602 static void solsy(double *y);
603 static void endstoda(void);
604 static void orderswitch(double *rhup, double dsm, double *pdh, double *rh, int *orderflag);
605 static void intdy(double t, int k, double *dky, int *iflag);
606 static void corfailure(double *told, double *rh, int *ncf, int *corflag);
607 static void methodswitch(double dsm, double pnorm, double *pdh, double *rh);
608 static void cfode(int meth);
609 static void scaleh(double *rh, double *pdh);
610 static double fnorm(int n, double **a, double *w);
611 static double vmnorm(int n, double *v, double *w);
612 
613 static int g_nyh = 0, g_lenyh = 0;
614 
615 /* newly added static variables */
616 
617 static int ml, mu, imxer;
618 static int mord[3] = {0, 12, 5};
619 static double sqrteta, *yp1, *yp2;
620 static double sm1[13] = {0., 0.5, 0.575, 0.55, 0.45, 0.35, 0.25, 0.2, 0.15, 0.1, 0.075, 0.05, 0.025};
621 
622 /* static variables for lsoda() */
623 
624 static double ccmax, el0, h, hmin, hmxi, hu, rc, tn;
625 static int illin = 0, init = 0, mxstep, mxhnil, nhnil, ntrep = 0, nslast, nyh, ierpj, iersl,
627  nfe, nje, nqu;
628 static double tsw, pdnorm;
629 static int ixpr = 0, jtyp, mused, mxordn, mxords;
630 
631 /* no static variable for prja(), solsy() */
632 /* static variables for stoda() */
633 
634 static double conit, crate, el[14], elco[13][14], hold, rmax, tesco[13][4];
635 static int ialth, ipup, lmax, nslp;
636 static double pdest, pdlast, ratio, cm1[13], cm2[6];
637 static int icount, irflag;
638 
639 /* static variables for various vectors and the Jacobian. */
640 
641 static double **yh, **wm, *ewt, *savf, *acor;
642 static int *ipvt;
643 
644 /*
645  The following are useful statistics.
646 
647  hu,
648  h,
649  tn,
650  tolsf,
651  tsw,
652  nst,
653  nfe,
654  nje,
655  nqu,
656  nq,
657  imxer,
658  mused,
659  meth
660 */
661 
662 
663 /* Terminate lsoda due to illegal input. */
664 static void terminate(int *istate)
665 {
666  if (illin == 5) {
667  fprintf(stderr, "[lsoda] repeated occurrence of illegal input. run aborted.. apparent infinite loop\n");
668  } else {
669  illin++;
670  *istate = -3;
671  }
672 }
673 
674 
675 /* Terminate lsoda due to various error conditions. */
676 static void terminate2(double *y, double *t)
677 {
678  int i;
679  yp1 = yh[1];
680  for (i = 1; i <= n; i++)
681  y[i] = yp1[i];
682  *t = tn;
683  illin = 0;
684  freevectors();
685  return;
686 
687 }
688 
689 /*
690  The following block handles all successful returns from lsoda.
691  If itask != 1, y is loaded from yh and t is set accordingly.
692  *Istate is set to 2, the illegal input counter is zeroed, and the
693  optional outputs are loaded into the work arrays before returning.
694 */
695 
696 static void successreturn(double *y, double *t, int itask, int ihit, double tcrit, int *istate)
697 {
698  int i;
699  yp1 = yh[1];
700  for (i = 1; i <= n; i++)
701  y[i] = yp1[i];
702  *t = tn;
703  if (itask == 4 || itask == 5)
704  if (ihit)
705  *t = tcrit;
706  *istate = 2;
707  illin = 0;
708  freevectors();
709 }
710 
711 /*
712 c-----------------------------------------------------------------------
713 c this is the march 30, 1987 version of
714 c lsoda.. livermore solver for ordinary differential equations, with
715 c automatic method switching for stiff and nonstiff problems.
716 c
717 c this version is in double precision.
718 c
719 c lsoda solves the initial value problem for stiff or nonstiff
720 c systems of first order ode-s,
721 c dy/dt = f(t,y) , or, in component form,
722 c dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(neq)) (i = 1,...,neq).
723 c
724 c this a variant version of the lsode package.
725 c it switches automatically between stiff and nonstiff methods.
726 c this means that the user does not have to determine whether the
727 c problem is stiff or not, and the solver will automatically choose the
728 c appropriate method. it always starts with the nonstiff method.
729 c
730 c authors..
731 c linda r. petzold and alan c. hindmarsh,
732 c computing and mathematics research division, l-316
733 c lawrence livermore national laboratory
734 c livermore, ca 94550.
735 c
736 c references..
737 c 1. alan c. hindmarsh, odepack, a systematized collection of ode
738 c solvers, in scientific computing, r. s. stepleman et al. (eds.),
739 c north-holland, amsterdam, 1983, pp. 55-64.
740 c 2. linda r. petzold, automatic selection of methods for solving
741 c stiff and nonstiff systems of ordinary differential equations,
742 c siam j. sci. stat. comput. 4 (1983), pp. 136-148.
743 c-----------------------------------------------------------------------
744 c summary of usage.
745 c
746 c communication between the user and the lsoda package, for normal
747 c situations, is summarized here. this summary describes only a subset
748 c of the full set of options available. see the full description for
749 c details, including alternative treatment of the jacobian matrix,
750 c optional inputs and outputs, nonstandard options, and
751 c instructions for special situations. see also the example
752 c problem (with program and output) following this summary.
753 c
754 c a. first provide a subroutine of the form..
755 c subroutine f (neq, t, y, ydot)
756 c dimension y(neq), ydot(neq)
757 c which supplies the vector function f by loading ydot(i) with f(i).
758 c
759 c b. write a main program which calls subroutine lsoda once for
760 c each point at which answers are desired. this should also provide
761 c for possible use of logical unit 6 for output of error messages
762 c by lsoda. on the first call to lsoda, supply arguments as follows..
763 c f = name of subroutine for right-hand side vector f.
764 c this name must be declared external in calling program.
765 c neq = number of first order ode-s.
766 c y = array of initial values, of length neq.
767 c t = the initial value of the independent variable.
768 c tout = first point where output is desired (.ne. t).
769 c itol = 1 or 2 according as atol (below) is a scalar or array.
770 c rtol = relative tolerance parameter (scalar).
771 c atol = absolute tolerance parameter (scalar or array).
772 c the estimated local error in y(i) will be controlled so as
773 c to be less than
774 c ewt(i) = rtol*abs(y(i)) + atol if itol = 1, or
775 c ewt(i) = rtol*abs(y(i)) + atol(i) if itol = 2.
776 c thus the local error test passes if, in each component,
777 c either the absolute error is less than atol (or atol(i)),
778 c or the relative error is less than rtol.
779 c use rtol = 0.0 for pure absolute error control, and
780 c use atol = 0.0 (or atol(i) = 0.0) for pure relative error
781 c control. caution.. actual (global) errors may exceed these
782 c local tolerances, so choose them conservatively.
783 c itask = 1 for normal computation of output values of y at t = tout.
784 c istate = integer flag (input and output). set istate = 1.
785 c iopt = 0 to indicate no optional inputs used.
786 c rwork = real work array of length at least..
787 c 22 + neq * max(16, neq + 9).
788 c see also paragraph e below.
789 c lrw = declared length of rwork (in user-s dimension).
790 c iwork = integer work array of length at least 20 + neq.
791 c liw = declared length of iwork (in user-s dimension).
792 c jac = name of subroutine for jacobian matrix.
793 c use a dummy name. see also paragraph e below.
794 c jt = jacobian type indicator. set jt = 2.
795 c see also paragraph e below.
796 c note that the main program must declare arrays y, rwork, iwork,
797 c and possibly atol.
798 c
799 c c. the output from the first call (or any call) is..
800 c y = array of computed values of y(t) vector.
801 c t = corresponding value of independent variable (normally tout).
802 c istate = 2 if lsoda was successful, negative otherwise.
803 c -1 means excess work done on this call (perhaps wrong jt).
804 c -2 means excess accuracy requested (tolerances too small).
805 c -3 means illegal input detected (see printed message).
806 c -4 means repeated error test failures (check all inputs).
807 c -5 means repeated convergence failures (perhaps bad jacobian
808 c supplied or wrong choice of jt or tolerances).
809 c -6 means error weight became zero during problem. (solution
810 c component i vanished, and atol or atol(i) = 0.)
811 c -7 means work space insufficient to finish (see messages).
812 c
813 c d. to continue the integration after a successful return, simply
814 c reset tout and call lsoda again. no other parameters need be reset.
815 c
816 c e. note.. if and when lsoda regards the problem as stiff, and
817 c switches methods accordingly, it must make use of the neq by neq
818 c jacobian matrix, j = df/dy. for the sake of simplicity, the
819 c inputs to lsoda recommended in paragraph b above cause lsoda to
820 c treat j as a full matrix, and to approximate it internally by
821 c difference quotients. alternatively, j can be treated as a band
822 c matrix (with great potential reduction in the size of the rwork
823 c array). also, in either the full or banded case, the user can supply
824 c j in closed form, with a routine whose name is passed as the jac
825 c argument. these alternatives are described in the paragraphs on
826 c rwork, jac, and jt in the full description of the call sequence below.
827 c
828 c-----------------------------------------------------------------------
829 */
830 
831 void lsoda(_lsoda_f f, int neq, double *y, double *t, double tout, int itol, double *rtol, double *atol,
832  int itask, int *istate, int iopt, int jt,
833  int iwork1, int iwork2, int iwork5, int iwork6, int iwork7, int iwork8, int iwork9,
834  double rwork1, double rwork5, double rwork6, double rwork7, void *_data)
835 /*
836 void
837 lsoda(f, neq, y, t, tout, itol, rtol, atol, itask, istate,
838  iopt, jt, iwork1, iwork2, iwork5, iwork6, iwork7, iwork8,
839  iwork9, rwork1, rwork5, rwork6, rwork7, _data)
840  _lsoda_f f;
841  void *_data;
842 
843  int neq, itol, itask, *istate, iopt, jt;
844  int iwork1, iwork2, iwork5, iwork6, iwork7, iwork8, iwork9;
845  double *y, *t, tout, *rtol, *atol;
846  double rwork1, rwork5, rwork6, rwork7;
847 */
848 /*
849  If the user does not supply any of these values, the calling program
850  should initialize those untouched working variables to zero.
851 
852  ml = iwork1
853  mu = iwork2
854  ixpr = iwork5
855  mxstep = iwork6
856  mxhnil = iwork7
857  mxordn = iwork8
858  mxords = iwork9
859 
860  tcrit = rwork1
861  h0 = rwork5
862  hmax = rwork6
863  hmin = rwork7
864 */
865 
866 
867 {
868  int mxstp0 = 500, mxhnl0 = 10;
869 
870  int i, iflag, lenyh, ihit;
871  double atoli, ayi, big, h0, hmax, hmx, rh, rtoli, tcrit, tdist, tnext, tol,
872  tolsf, tp, size, sum, w0;
873 
874  if (*istate == 1) _freevectors();
875 
876 /*
877  Block a.
878  This code block is executed on every call.
879  It tests *istate and itask for legality and branches appropriately.
880  If *istate > 1 but the flag init shows that initialization has not
881  yet been done, an error return occurs.
882  If *istate = 1 and tout = t, return immediately.
883 */
884 
885  if (*istate < 1 || *istate > 3) {
886  fprintf(stderr, "[lsoda] illegal istate = %d\n", *istate);
887  terminate(istate);
888  return;
889  }
890  if (itask < 1 || itask > 5) {
891  fprintf(stderr, "[lsoda] illegal itask = %d\n", itask);
892  terminate(istate);
893  return;
894  }
895  if (init == 0 && (*istate == 2 || *istate == 3)) {
896  fprintf(stderr, "[lsoda] istate > 1 but lsoda not initialized\n");
897  terminate(istate);
898  return;
899  }
900  if (*istate == 1) {
901  init = 0;
902  if (tout == *t) {
903  ntrep++;
904  if (ntrep < 5) return;
905  fprintf(stderr, "[lsoda] repeated calls with istate = 1 and tout = t. run aborted.. apparent infinite loop\n");
906  return;
907  }
908  }
909 /*
910  Block b.
911  The next code block is executed for the initial call ( *istate = 1 ),
912  or for a continuation call with parameter changes ( *istate = 3 ).
913  It contains checking of all inputs and various initializations.
914 
915  First check legality of the non-optional inputs neq, itol, iopt,
916  jt, ml, and mu.
917 */
918 
919  if (*istate == 1 || *istate == 3) {
920  ntrep = 0;
921  if (neq <= 0) {
922  fprintf(stderr, "[lsoda] neq = %d is less than 1\n", neq);
923  terminate(istate);
924  return;
925  }
926  if (*istate == 3 && neq > n) {
927  fprintf(stderr, "[lsoda] istate = 3 and neq increased\n");
928  terminate(istate);
929  return;
930  }
931  n = neq;
932  if (itol < 1 || itol > 4) {
933  fprintf(stderr, "[lsoda] itol = %d illegal\n", itol);
934  terminate(istate);
935  return;
936  }
937  if (iopt < 0 || iopt > 1) {
938  fprintf(stderr, "[lsoda] iopt = %d illegal\n", iopt);
939  terminate(istate);
940  return;
941  }
942  if (jt == 3 || jt < 1 || jt > 5) {
943  fprintf(stderr, "[lsoda] jt = %d illegal\n", jt);
944  terminate(istate);
945  return;
946  }
947  jtyp = jt;
948  if (jt > 2) {
949  ml = iwork1;
950  mu = iwork2;
951  if (ml < 0 || ml >= n) {
952  fprintf(stderr, "[lsoda] ml = %d not between 1 and neq\n", ml);
953  terminate(istate);
954  return;
955  }
956  if (mu < 0 || mu >= n) {
957  fprintf(stderr, "[lsoda] mu = %d not between 1 and neq\n", mu);
958  terminate(istate);
959  return;
960  }
961  }
962 /* Next process and check the optional inpus. */
963 
964 /* Default options. */
965 
966  if (iopt == 0) {
967  ixpr = 0;
968  mxstep = mxstp0;
969  mxhnil = mxhnl0;
970  hmxi = 0.;
971  hmin = 0.;
972  if (*istate == 1) {
973  h0 = 0.;
974  mxordn = mord[1];
975  mxords = mord[2];
976  }
977  }
978  /* end if ( iopt == 0 ) */
979  /* Optional inputs. */
980  else { /* if ( iopt = 1 ) */
981  ixpr = iwork5;
982  if (ixpr < 0 || ixpr > 1) {
983  fprintf(stderr, "[lsoda] ixpr = %d is illegal\n", ixpr);
984  terminate(istate);
985  return;
986  }
987  mxstep = iwork6;
988  if (mxstep < 0) {
989  fprintf(stderr, "[lsoda] mxstep < 0\n");
990  terminate(istate);
991  return;
992  }
993  if (mxstep == 0) mxstep = mxstp0;
994  mxhnil = iwork7;
995  if (mxhnil < 0) {
996  fprintf(stderr, "[lsoda] mxhnil < 0\n");
997  terminate(istate);
998  return;
999  }
1000  if (*istate == 1) {
1001  h0 = rwork5;
1002  mxordn = iwork8;
1003  if (mxordn < 0) {
1004  fprintf(stderr, "[lsoda] mxordn = %d is less than 0\n", mxordn);
1005  terminate(istate);
1006  return;
1007  }
1008  if (mxordn == 0) mxordn = 100;
1009  mxordn = min(mxordn, mord[1]);
1010  mxords = iwork9;
1011  if (mxords < 0) {
1012  fprintf(stderr, "[lsoda] mxords = %d is less than 0\n", mxords);
1013  terminate(istate);
1014  return;
1015  }
1016  if (mxords == 0) mxords = 100;
1017  mxords = min(mxords, mord[2]);
1018  if ((tout - *t) * h0 < 0.) {
1019  fprintf(stderr, "[lsoda] tout = %g behind t = %g. integration direction is given by %g\n",
1020  tout, *t, h0);
1021  terminate(istate);
1022  return;
1023  }
1024  } /* end if ( *istate == 1 ) */
1025  hmax = rwork6;
1026  if (hmax < 0.) {
1027  fprintf(stderr, "[lsoda] hmax < 0.\n");
1028  terminate(istate);
1029  return;
1030  }
1031  hmxi = 0.;
1032  if (hmax > 0)
1033  hmxi = 1. / hmax;
1034  hmin = rwork7;
1035  if (hmin < 0.) {
1036  fprintf(stderr, "[lsoda] hmin < 0.\n");
1037  terminate(istate);
1038  return;
1039  }
1040  } /* end else *//* end iopt = 1 */
1041  } /* end if ( *istate == 1 || *istate == 3 ) */
1042  /*
1043  If *istate = 1, meth is initialized to 1.
1044 
1045  Also allocate memory for yh, wm, ewt, savf, acor, ipvt.
1046  */
1047  if (*istate == 1) {
1048 /*
1049  If memory were not freed, *istate = 3 need not reallocate memory.
1050  Hence this section is not executed by *istate = 3.
1051 */
1052  sqrteta = sqrt(ETA);
1053  meth = 1;
1054  g_nyh = nyh = n;
1055  g_lenyh = lenyh = 1 + max(mxordn, mxords);
1056 
1057  yh = (double **) calloc(1 + lenyh, sizeof(*yh));
1058  if (yh == NULL) {
1059  printf("lsoda -- insufficient memory for your problem\n");
1060  terminate(istate);
1061  return;
1062  }
1063  for (i = 1; i <= lenyh; i++)
1064  yh[i] = (double *) calloc(1 + nyh, sizeof(double));
1065 
1066  wm = (double **) calloc(1 + nyh, sizeof(*wm));
1067  if (wm == NULL) {
1068  free(yh);
1069  printf("lsoda -- insufficient memory for your problem\n");
1070  terminate(istate);
1071  return;
1072  }
1073  for (i = 1; i <= nyh; i++)
1074  wm[i] = (double *) calloc(1 + nyh, sizeof(double));
1075 
1076  ewt = (double *) calloc(1 + nyh, sizeof(double));
1077  if (ewt == NULL) {
1078  free(yh);
1079  free(wm);
1080  printf("lsoda -- insufficient memory for your problem\n");
1081  terminate(istate);
1082  return;
1083  }
1084  savf = (double *) calloc(1 + nyh, sizeof(double));
1085  if (savf == NULL) {
1086  free(yh);
1087  free(wm);
1088  free(ewt);
1089  printf("lsoda -- insufficient memory for your problem\n");
1090  terminate(istate);
1091  return;
1092  }
1093  acor = (double *) calloc(1 + nyh, sizeof(double));
1094  if (acor == NULL) {
1095  free(yh);
1096  free(wm);
1097  free(ewt);
1098  free(savf);
1099  printf("lsoda -- insufficient memory for your problem\n");
1100  terminate(istate);
1101  return;
1102  }
1103  ipvt = (int *) calloc(1 + nyh, sizeof(int));
1104  if (ipvt == NULL) {
1105  free(yh);
1106  free(wm);
1107  free(ewt);
1108  free(savf);
1109  free(acor);
1110  printf("lsoda -- insufficient memory for your problem\n");
1111  terminate(istate);
1112  return;
1113  }
1114  }
1115 /*
1116  Check rtol and atol for legality.
1117 */
1118  if (*istate == 1 || *istate == 3) {
1119  rtoli = rtol[1];
1120  atoli = atol[1];
1121  for (i = 1; i <= n; i++) {
1122  if (itol >= 3)
1123  rtoli = rtol[i];
1124  if (itol == 2 || itol == 4)
1125  atoli = atol[i];
1126  if (rtoli < 0.) {
1127  fprintf(stderr, "[lsoda] rtol = %g is less than 0.\n", rtoli);
1128  terminate(istate);
1129  freevectors();
1130  return;
1131  }
1132  if (atoli < 0.) {
1133  fprintf(stderr, "[lsoda] atol = %g is less than 0.\n", atoli);
1134  terminate(istate);
1135  freevectors();
1136  return;
1137  }
1138  } /* end for */
1139  } /* end if ( *istate == 1 || *istate == 3 ) */
1140  /*
1141  If *istate = 3, set flag to signal parameter changes to stoda.
1142  */
1143  if (*istate == 3) {
1144  jstart = -1;
1145  }
1146 /*
1147  Block c.
1148  The next block is for the initial call only ( *istate = 1 ).
1149  It contains all remaining initializations, the initial call to f,
1150  and the calculation of the initial step size.
1151  The error weights in ewt are inverted after being loaded.
1152 */
1153  if (*istate == 1) {
1154  tn = *t;
1155  tsw = *t;
1156  maxord = mxordn;
1157  if (itask == 4 || itask == 5) {
1158  tcrit = rwork1;
1159  if ((tcrit - tout) * (tout - *t) < 0.) {
1160  fprintf(stderr, "[lsoda] itask = 4 or 5 and tcrit behind tout\n");
1161  terminate(istate);
1162  freevectors();
1163  return;
1164  }
1165  if (h0 != 0. && (*t + h0 - tcrit) * h0 > 0.)
1166  h0 = tcrit - *t;
1167  }
1168  jstart = 0;
1169  nhnil = 0;
1170  nst = 0;
1171  nje = 0;
1172  nslast = 0;
1173  hu = 0.;
1174  nqu = 0;
1175  mused = 0;
1176  miter = 0;
1177  ccmax = 0.3;
1178  maxcor = 3;
1179  msbp = 20;
1180  mxncf = 10;
1181 /*
1182  Initial call to f.
1183 */
1184  (*f) (*t, y + 1, yh[2] + 1, _data);
1185  nfe = 1;
1186 /*
1187  Load the initial value vector in yh.
1188 */
1189  yp1 = yh[1];
1190  for (i = 1; i <= n; i++)
1191  yp1[i] = y[i];
1192 /*
1193  Load and invert the ewt array. ( h is temporarily set to 1. )
1194 */
1195  nq = 1;
1196  h = 1.;
1197  ewset(itol, rtol, atol, y);
1198  for (i = 1; i <= n; i++) {
1199  if (ewt[i] <= 0.) {
1200  fprintf(stderr, "[lsoda] ewt[%d] = %g <= 0.\n", i, ewt[i]);
1201  terminate2(y, t);
1202  return;
1203  }
1204  ewt[i] = 1. / ewt[i];
1205  }
1206 
1207 /*
1208  The coding below computes the step size, h0, to be attempted on the
1209  first step, unless the user has supplied a value for this.
1210  First check that tout - *t differs significantly from zero.
1211  A scalar tolerance quantity tol is computed, as max(rtol[i])
1212  if this is positive, or max(atol[i]/fabs(y[i])) otherwise, adjusted
1213  so as to be between 100*ETA and 0.001.
1214  Then the computed value h0 is given by
1215 
1216  h0^(-2) = 1. / ( tol * w0^2 ) + tol * ( norm(f) )^2
1217 
1218  where w0 = max( fabs(*t), fabs(tout) ),
1219  f = the initial value of the vector f(t,y), and
1220  norm() = the weighted vector norm used throughout, given by
1221  the vmnorm function routine, and weighted by the
1222  tolerances initially loaded into the ewt array.
1223 
1224  The sign of h0 is inferred from the initial values of tout and *t.
1225  fabs(h0) is made < fabs(tout-*t) in any case.
1226 */
1227  if (h0 == 0.) {
1228  tdist = fabs(tout - *t);
1229  w0 = max(fabs(*t), fabs(tout));
1230  if (tdist < 2. * ETA * w0) {
1231  fprintf(stderr, "[lsoda] tout too close to t to start integration\n ");
1232  terminate(istate);
1233  freevectors();
1234  return;
1235  }
1236  tol = rtol[1];
1237  if (itol > 2) {
1238  for (i = 2; i <= n; i++)
1239  tol = max(tol, rtol[i]);
1240  }
1241  if (tol <= 0.) {
1242  atoli = atol[1];
1243  for (i = 1; i <= n; i++) {
1244  if (itol == 2 || itol == 4)
1245  atoli = atol[i];
1246  ayi = fabs(y[i]);
1247  if (ayi != 0.)
1248  tol = max(tol, atoli / ayi);
1249  }
1250  }
1251  tol = max(tol, 100. * ETA);
1252  tol = min(tol, 0.001);
1253  sum = vmnorm(n, yh[2], ewt);
1254  sum = 1. / (tol * w0 * w0) + tol * sum * sum;
1255  h0 = 1. / sqrt(sum);
1256  h0 = min(h0, tdist);
1257  h0 = h0 * ((tout - *t >= 0.) ? 1. : -1.);
1258  } /* end if ( h0 == 0. ) */
1259  /*
1260  Adjust h0 if necessary to meet hmax bound.
1261  */
1262  rh = fabs(h0) * hmxi;
1263  if (rh > 1.)
1264  h0 /= rh;
1265 /*
1266  Load h with h0 and scale yh[2] by h0.
1267 */
1268  h = h0;
1269  yp1 = yh[2];
1270  for (i = 1; i <= n; i++)
1271  yp1[i] *= h0;
1272  } /* if ( *istate == 1 ) */
1273  /*
1274  Block d.
1275  The next code block is for continuation calls only ( *istate = 2 or 3 )
1276  and is to check stop conditions before taking a step.
1277  */
1278  if (*istate == 2 || *istate == 3) {
1279  nslast = nst;
1280  switch (itask) {
1281  case 1:
1282  if ((tn - tout) * h >= 0.) {
1283  intdy(tout, 0, y, &iflag);
1284  if (iflag != 0) {
1285  fprintf(stderr, "[lsoda] trouble from intdy, itask = %d, tout = %g\n", itask, tout);
1286  terminate(istate);
1287  freevectors();
1288  return;
1289  }
1290  *t = tout;
1291  *istate = 2;
1292  illin = 0;
1293  freevectors();
1294  return;
1295  }
1296  break;
1297  case 2:
1298  break;
1299  case 3:
1300  tp = tn - hu * (1. + 100. * ETA);
1301  if ((tp - tout) * h > 0.) {
1302  fprintf(stderr, "[lsoda] itask = %d and tout behind tcur - hu\n", itask);
1303  terminate(istate);
1304  freevectors();
1305  return;
1306  }
1307  if ((tn - tout) * h < 0.) break;
1308  successreturn(y, t, itask, ihit, tcrit, istate);
1309  return;
1310  case 4:
1311  tcrit = rwork1;
1312  if ((tn - tcrit) * h > 0.) {
1313  fprintf(stderr, "[lsoda] itask = 4 or 5 and tcrit behind tcur\n");
1314  terminate(istate);
1315  freevectors();
1316  return;
1317  }
1318  if ((tcrit - tout) * h < 0.) {
1319  fprintf(stderr, "[lsoda] itask = 4 or 5 and tcrit behind tout\n");
1320  terminate(istate);
1321  freevectors();
1322  return;
1323  }
1324  if ((tn - tout) * h >= 0.) {
1325  intdy(tout, 0, y, &iflag);
1326  if (iflag != 0) {
1327  fprintf(stderr, "[lsoda] trouble from intdy, itask = %d, tout = %g\n", itask, tout);
1328  terminate(istate);
1329  freevectors();
1330  return;
1331  }
1332  *t = tout;
1333  *istate = 2;
1334  illin = 0;
1335  freevectors();
1336  return;
1337  }
1338  case 5:
1339  if (itask == 5) {
1340  tcrit = rwork1;
1341  if ((tn - tcrit) * h > 0.) {
1342  fprintf(stderr, "[lsoda] itask = 4 or 5 and tcrit behind tcur\n");
1343  terminate(istate);
1344  freevectors();
1345  return;
1346  }
1347  }
1348  hmx = fabs(tn) + fabs(h);
1349  ihit = fabs(tn - tcrit) <= (100. * ETA * hmx);
1350  if (ihit) {
1351  *t = tcrit;
1352  successreturn(y, t, itask, ihit, tcrit, istate);
1353  return;
1354  }
1355  tnext = tn + h * (1. + 4. * ETA);
1356  if ((tnext - tcrit) * h <= 0.)
1357  break;
1358  h = (tcrit - tn) * (1. - 4. * ETA);
1359  if (*istate == 2)
1360  jstart = -2;
1361  break;
1362  } /* end switch */
1363  } /* end if ( *istate == 2 || *istate == 3 ) */
1364  /*
1365  Block e.
1366  The next block is normally executed for all calls and contains
1367  the call to the one-step core integrator stoda.
1368 
1369  This is a looping point for the integration steps.
1370 
1371  First check for too many steps being taken, update ewt ( if not at
1372  start of problem). Check for too much accuracy being requested, and
1373  check for h below the roundoff level in *t.
1374  */
1375  while (1) {
1376  if (*istate != 1 || nst != 0) {
1377  if ((nst - nslast) >= mxstep) {
1378  fprintf(stderr, "[lsoda] %d steps taken before reaching tout\n", mxstep);
1379  *istate = -1;
1380  terminate2(y, t);
1381  return;
1382  }
1383  ewset(itol, rtol, atol, yh[1]);
1384  for (i = 1; i <= n; i++) {
1385  if (ewt[i] <= 0.) {
1386  fprintf(stderr, "[lsoda] ewt[%d] = %g <= 0.\n", i, ewt[i]);
1387  *istate = -6;
1388  terminate2(y, t);
1389  return;
1390  }
1391  ewt[i] = 1. / ewt[i];
1392  }
1393  }
1394  tolsf = ETA * vmnorm(n, yh[1], ewt);
1395  if (tolsf > 0.01) {
1396  tolsf = tolsf * 200.;
1397  if (nst == 0) {
1398  fprintf(stderr, "lsoda -- at start of problem, too much accuracy\n");
1399  fprintf(stderr, " requested for precision of machine,\n");
1400  fprintf(stderr, " suggested scaling factor = %g\n", tolsf);
1401  terminate(istate);
1402  freevectors();
1403  return;
1404  }
1405  fprintf(stderr, "lsoda -- at t = %g, too much accuracy requested\n", *t);
1406  fprintf(stderr, " for precision of machine, suggested\n");
1407  fprintf(stderr, " scaling factor = %g\n", tolsf);
1408  *istate = -2;
1409  terminate2(y, t);
1410  return;
1411  }
1412  if ((tn + h) == tn) {
1413  nhnil++;
1414  if (nhnil <= mxhnil) {
1415  fprintf(stderr, "lsoda -- warning..internal t = %g and h = %g are\n", tn, h);
1416  fprintf(stderr, " such that in the machine, t + h = t on the next step\n");
1417  fprintf(stderr, " solver will continue anyway.\n");
1418  if (nhnil == mxhnil) {
1419  fprintf(stderr, "lsoda -- above warning has been issued %d times,\n", nhnil);
1420  fprintf(stderr, " it will not be issued again for this problem\n");
1421  }
1422  }
1423  }
1424 /*
1425  Call stoda
1426 */
1427  stoda(neq, y, f, _data);
1428 
1429 /*
1430  printf( "meth= %d, order= %d, nfe= %d, nje= %d\n",
1431  meth, nq, nfe, nje );
1432  printf( "t= %20.15e, h= %20.15e, nst=%d\n", tn, h, nst );
1433  printf( "y= %20.15e, %20.15e, %20.15e\n\n\n",
1434  yh[1][1], yh[1][2], yh[1][3] );
1435 */
1436 
1437  if (kflag == 0) {
1438 /*
1439  Block f.
1440  The following block handles the case of a successful return from the
1441  core integrator ( kflag = 0 ).
1442  If a method switch was just made, record tsw, reset maxord,
1443  set jstart to -1 to signal stoda to complete the switch,
1444  and do extra printing of data if ixpr = 1.
1445  Then, in any case, check for stop conditions.
1446 */
1447  init = 1;
1448  if (meth != mused) {
1449  tsw = tn;
1450  maxord = mxordn;
1451  if (meth == 2)
1452  maxord = mxords;
1453  jstart = -1;
1454  if (ixpr) {
1455  if (meth == 2)
1456  fprintf(stderr, "[lsoda] a switch to the stiff method has occurred ");
1457  if (meth == 1)
1458  fprintf(stderr, "[lsoda] a switch to the nonstiff method has occurred");
1459  fprintf(stderr, "at t = %g, tentative step size h = %g, step nst = %d\n", tn, h, nst);
1460  }
1461  } /* end if ( meth != mused ) */
1462  /*
1463  itask = 1.
1464  If tout has been reached, interpolate.
1465  */
1466  if (itask == 1) {
1467  if ((tn - tout) * h < 0.)
1468  continue;
1469  intdy(tout, 0, y, &iflag);
1470  *t = tout;
1471  *istate = 2;
1472  illin = 0;
1473  freevectors();
1474  return;
1475  }
1476 /*
1477  itask = 2.
1478 */
1479  if (itask == 2) {
1480  successreturn(y, t, itask, ihit, tcrit, istate);
1481  return;
1482  }
1483 /*
1484  itask = 3.
1485  Jump to exit if tout was reached.
1486 */
1487  if (itask == 3) {
1488  if ((tn - tout) * h >= 0.) {
1489  successreturn(y, t, itask, ihit, tcrit, istate);
1490  return;
1491  }
1492  continue;
1493  }
1494 /*
1495  itask = 4.
1496  See if tout or tcrit was reached. Adjust h if necessary.
1497 */
1498  if (itask == 4) {
1499  if ((tn - tout) * h >= 0.) {
1500  intdy(tout, 0, y, &iflag);
1501  *t = tout;
1502  *istate = 2;
1503  illin = 0;
1504  freevectors();
1505  return;
1506  } else {
1507  hmx = fabs(tn) + fabs(h);
1508  ihit = fabs(tn - tcrit) <= (100. * ETA * hmx);
1509  if (ihit) {
1510  successreturn(y, t, itask, ihit, tcrit, istate);
1511  return;
1512  }
1513  tnext = tn + h * (1. + 4. * ETA);
1514  if ((tnext - tcrit) * h <= 0.)
1515  continue;
1516  h = (tcrit - tn) * (1. - 4. * ETA);
1517  jstart = -2;
1518  continue;
1519  }
1520  } /* end if ( itask == 4 ) */
1521  /*
1522  itask = 5.
1523  See if tcrit was reached and jump to exit.
1524  */
1525  if (itask == 5) {
1526  hmx = fabs(tn) + fabs(h);
1527  ihit = fabs(tn - tcrit) <= (100. * ETA * hmx);
1528  successreturn(y, t, itask, ihit, tcrit, istate);
1529  return;
1530  }
1531  } /* end if ( kflag == 0 ) */
1532  /*
1533  kflag = -1, error test failed repeatedly or with fabs(h) = hmin.
1534  kflag = -2, convergence failed repeatedly or with fabs(h) = hmin.
1535  */
1536  if (kflag == -1 || kflag == -2) {
1537  fprintf(stderr, "lsoda -- at t = %g and step size h = %g, the\n", tn, h);
1538  if (kflag == -1) {
1539  fprintf(stderr, " error test failed repeatedly or\n");
1540  fprintf(stderr, " with fabs(h) = hmin\n");
1541  *istate = -4;
1542  }
1543  if (kflag == -2) {
1544  fprintf(stderr, " corrector convergence failed repeatedly or\n");
1545  fprintf(stderr, " with fabs(h) = hmin\n");
1546  *istate = -5;
1547  }
1548  big = 0.;
1549  imxer = 1;
1550  for (i = 1; i <= n; i++) {
1551  size = fabs(acor[i]) * ewt[i];
1552  if (big < size) {
1553  big = size;
1554  imxer = i;
1555  }
1556  }
1557  terminate2(y, t);
1558  return;
1559  } /* end if ( kflag == -1 || kflag == -2 ) */
1560  } /* end while */
1561 
1562 } /* end lsoda */
1563 
1564 
1565 static void stoda(int neq, double *y, _lsoda_f f, void *_data)
1566 {
1567  int corflag, orderflag;
1568  int i, i1, j, m, ncf;
1569  double del, delp, dsm, dup, exup, r, rh, rhup, told;
1570  double pdh, pnorm;
1571 
1572 /*
1573  stoda performs one step of the integration of an initial value
1574  problem for a system of ordinary differential equations.
1575  Note.. stoda is independent of the value of the iteration method
1576  indicator miter, when this is != 0, and hence is independent
1577  of the type of chord method used, or the Jacobian structure.
1578  Communication with stoda is done with the following variables:
1579 
1580  jstart = an integer used for input only, with the following
1581  values and meanings:
1582 
1583  0 perform the first step,
1584  > 0 take a new step continuing from the last,
1585  -1 take the next step with a new value of h,
1586  n, meth, miter, and/or matrix parameters.
1587  -2 take the next step with a new value of h,
1588  but with other inputs unchanged.
1589 
1590  kflag = a completion code with the following meanings:
1591 
1592  0 the step was successful,
1593  -1 the requested error could not be achieved,
1594  -2 corrector convergence could not be achieved,
1595  -3 fatal error in prja or solsy.
1596 
1597  miter = corrector iteration method:
1598 
1599  0 functional iteration,
1600  >0 a chord method corresponding to jacobian type jt.
1601 
1602 */
1603  kflag = 0;
1604  told = tn;
1605  ncf = 0;
1606  ierpj = 0;
1607  iersl = 0;
1608  jcur = 0;
1609  delp = 0.;
1610 
1611 /*
1612  On the first call, the order is set to 1, and other variables are
1613  initialized. rmax is the maximum ratio by which h can be increased
1614  in a single step. It is initially 1.e4 to compensate for the small
1615  initial h, but then is normally equal to 10. If a filure occurs
1616  (in corrector convergence or error test), rmax is set at 2 for
1617  the next increase.
1618  cfode is called to get the needed coefficients for both methods.
1619 */
1620  if (jstart == 0) {
1621  lmax = maxord + 1;
1622  nq = 1;
1623  l = 2;
1624  ialth = 2;
1625  rmax = 10000.;
1626  rc = 0.;
1627  el0 = 1.;
1628  crate = 0.7;
1629  hold = h;
1630  nslp = 0;
1631  ipup = miter;
1632 /*
1633  Initialize switching parameters. meth = 1 is assumed initially.
1634 */
1635  icount = 20;
1636  irflag = 0;
1637  pdest = 0.;
1638  pdlast = 0.;
1639  ratio = 5.;
1640  cfode(2);
1641  for (i = 1; i <= 5; i++)
1642  cm2[i] = tesco[i][2] * elco[i][i + 1];
1643  cfode(1);
1644  for (i = 1; i <= 12; i++)
1645  cm1[i] = tesco[i][2] * elco[i][i + 1];
1646  resetcoeff();
1647  } /* end if ( jstart == 0 ) */
1648  /*
1649  The following block handles preliminaries needed when jstart = -1.
1650  ipup is set to miter to force a matrix update.
1651  If an order increase is about to be considered ( ialth = 1 ),
1652  ialth is reset to 2 to postpone consideration one more step.
1653  If the caller has changed meth, cfode is called to reset
1654  the coefficients of the method.
1655  If h is to be changed, yh must be rescaled.
1656  If h or meth is being changed, ialth is reset to l = nq + 1
1657  to prevent further changes in h for that many steps.
1658  */
1659  if (jstart == -1) {
1660  ipup = miter;
1661  lmax = maxord + 1;
1662  if (ialth == 1)
1663  ialth = 2;
1664  if (meth != mused) {
1665  cfode(meth);
1666  ialth = l;
1667  resetcoeff();
1668  }
1669  if (h != hold) {
1670  rh = h / hold;
1671  h = hold;
1672  scaleh(&rh, &pdh);
1673  }
1674  } /* if ( jstart == -1 ) */
1675  if (jstart == -2) {
1676  if (h != hold) {
1677  rh = h / hold;
1678  h = hold;
1679  scaleh(&rh, &pdh);
1680  }
1681  } /* if ( jstart == -2 ) */
1682  /*
1683  Prediction.
1684  This section computes the predicted values by effectively
1685  multiplying the yh array by the pascal triangle matrix.
1686  rc is the ratio of new to old values of the coefficient h * el[1].
1687  When rc differs from 1 by more than ccmax, ipup is set to miter
1688  to force pjac to be called, if a jacobian is involved.
1689  In any case, prja is called at least every msbp steps.
1690  */
1691  while (1) {
1692  while (1) {
1693  if (fabs(rc - 1.) > ccmax)
1694  ipup = miter;
1695  if (nst >= nslp + msbp)
1696  ipup = miter;
1697  tn += h;
1698  for (j = nq; j >= 1; j--)
1699  for (i1 = j; i1 <= nq; i1++) {
1700  yp1 = yh[i1];
1701  yp2 = yh[i1 + 1];
1702  for (i = 1; i <= n; i++)
1703  yp1[i] += yp2[i];
1704  }
1705  pnorm = vmnorm(n, yh[1], ewt);
1706 
1707  correction(neq, y, f, &corflag, pnorm, &del, &delp, &told, &ncf, &rh, &m, _data);
1708  if (corflag == 0)
1709  break;
1710  if (corflag == 1) {
1711  rh = max(rh, hmin / fabs(h));
1712  scaleh(&rh, &pdh);
1713  continue;
1714  }
1715  if (corflag == 2) {
1716  kflag = -2;
1717  hold = h;
1718  jstart = 1;
1719  return;
1720  }
1721  } /* end inner while ( corrector loop ) */
1722 /*
1723  The corrector has converged. jcur is set to 0
1724  to signal that the Jacobian involved may need updating later.
1725  The local error test is done now.
1726 */
1727  jcur = 0;
1728  if (m == 0)
1729  dsm = del / tesco[nq][2];
1730  if (m > 0)
1731  dsm = vmnorm(n, acor, ewt) / tesco[nq][2];
1732  if (dsm <= 1.) {
1733 /*
1734  After a successful step, update the yh array.
1735  Decrease icount by 1, and if it is -1, consider switching methods.
1736  If a method switch is made, reset various parameters,
1737  rescale the yh array, and exit. If there is no switch,
1738  consider changing h if ialth = 1. Otherwise decrease ialth by 1.
1739  If ialth is then 1 and nq < maxord, then acor is saved for
1740  use in a possible order increase on the next step.
1741  If a change in h is considered, an increase or decrease in order
1742  by one is considered also. A change in h is made only if it is by
1743  a factor of at least 1.1. If not, ialth is set to 3 to prevent
1744  testing for that many steps.
1745 */
1746  kflag = 0;
1747  nst++;
1748  hu = h;
1749  nqu = nq;
1750  mused = meth;
1751  for (j = 1; j <= l; j++) {
1752  yp1 = yh[j];
1753  r = el[j];
1754  for (i = 1; i <= n; i++)
1755  yp1[i] += r * acor[i];
1756  }
1757  icount--;
1758  if (icount < 0) {
1759  methodswitch(dsm, pnorm, &pdh, &rh);
1760  if (meth != mused) {
1761  rh = max(rh, hmin / fabs(h));
1762  scaleh(&rh, &pdh);
1763  rmax = 10.;
1764  endstoda();
1765  break;
1766  }
1767  }
1768 /*
1769  No method switch is being made. Do the usual step/order selection.
1770 */
1771  ialth--;
1772  if (ialth == 0) {
1773  rhup = 0.;
1774  if (l != lmax) {
1775  yp1 = yh[lmax];
1776  for (i = 1; i <= n; i++)
1777  savf[i] = acor[i] - yp1[i];
1778  dup = vmnorm(n, savf, ewt) / tesco[nq][3];
1779  exup = 1. / (double) (l + 1);
1780  rhup = 1. / (1.4 * pow(dup, exup) + 0.0000014);
1781  }
1782  orderswitch(&rhup, dsm, &pdh, &rh, &orderflag);
1783 /*
1784  No change in h or nq.
1785 */
1786  if (orderflag == 0) {
1787  endstoda();
1788  break;
1789  }
1790 /*
1791  h is changed, but not nq.
1792 */
1793  if (orderflag == 1) {
1794  rh = max(rh, hmin / fabs(h));
1795  scaleh(&rh, &pdh);
1796  rmax = 10.;
1797  endstoda();
1798  break;
1799  }
1800 /*
1801  both nq and h are changed.
1802 */
1803  if (orderflag == 2) {
1804  resetcoeff();
1805  rh = max(rh, hmin / fabs(h));
1806  scaleh(&rh, &pdh);
1807  rmax = 10.;
1808  endstoda();
1809  break;
1810  }
1811  } /* end if ( ialth == 0 ) */
1812  if (ialth > 1 || l == lmax) {
1813  endstoda();
1814  break;
1815  }
1816  yp1 = yh[lmax];
1817  for (i = 1; i <= n; i++)
1818  yp1[i] = acor[i];
1819  endstoda();
1820  break;
1821  }
1822  /* end if ( dsm <= 1. ) */
1823  /*
1824  The error test failed. kflag keeps track of multiple failures.
1825  Restore tn and the yh array to their previous values, and prepare
1826  to try the step again. Compute the optimum step size for this or
1827  one lower. After 2 or more failures, h is forced to decrease
1828  by a factor of 0.2 or less.
1829  */
1830  else {
1831  kflag--;
1832  tn = told;
1833  for (j = nq; j >= 1; j--)
1834  for (i1 = j; i1 <= nq; i1++) {
1835  yp1 = yh[i1];
1836  yp2 = yh[i1 + 1];
1837  for (i = 1; i <= n; i++)
1838  yp1[i] -= yp2[i];
1839  }
1840  rmax = 2.;
1841  if (fabs(h) <= hmin * 1.00001) {
1842  kflag = -1;
1843  hold = h;
1844  jstart = 1;
1845  break;
1846  }
1847  if (kflag > -3) {
1848  rhup = 0.;
1849  orderswitch(&rhup, dsm, &pdh, &rh, &orderflag);
1850  if (orderflag == 1 || orderflag == 0) {
1851  if (orderflag == 0)
1852  rh = min(rh, 0.2);
1853  rh = max(rh, hmin / fabs(h));
1854  scaleh(&rh, &pdh);
1855  }
1856  if (orderflag == 2) {
1857  resetcoeff();
1858  rh = max(rh, hmin / fabs(h));
1859  scaleh(&rh, &pdh);
1860  }
1861  continue;
1862  }
1863  /* if ( kflag > -3 ) */
1864  /*
1865  Control reaches this section if 3 or more failures have occurred.
1866  If 10 failures have occurred, exit with kflag = -1.
1867  It is assumed that the derivatives that have accumulated in the
1868  yh array have errors of the wrong order. Hence the first
1869  derivative is recomputed, and the order is set to 1. Then
1870  h is reduced by a factor of 10, and the step is retried,
1871  until it succeeds or h reaches hmin.
1872  */
1873  else {
1874  if (kflag == -10) {
1875  kflag = -1;
1876  hold = h;
1877  jstart = 1;
1878  break;
1879  } else {
1880  rh = 0.1;
1881  rh = max(hmin / fabs(h), rh);
1882  h *= rh;
1883  yp1 = yh[1];
1884  for (i = 1; i <= n; i++)
1885  y[i] = yp1[i];
1886  (*f) (tn, y + 1, savf + 1, _data);
1887  nfe++;
1888  yp1 = yh[2];
1889  for (i = 1; i <= n; i++)
1890  yp1[i] = h * savf[i];
1891  ipup = miter;
1892  ialth = 5;
1893  if (nq == 1)
1894  continue;
1895  nq = 1;
1896  l = 2;
1897  resetcoeff();
1898  continue;
1899  }
1900  } /* end else -- kflag <= -3 */
1901  } /* end error failure handling */
1902  } /* end outer while */
1903 
1904 } /* end stoda */
1905 
1906 static void ewset(int itol, double *rtol, double *atol, double *ycur)
1907 {
1908  int i;
1909 
1910  switch (itol) {
1911  case 1:
1912  for (i = 1; i <= n; i++)
1913  ewt[i] = rtol[1] * fabs(ycur[i]) + atol[1];
1914  break;
1915  case 2:
1916  for (i = 1; i <= n; i++)
1917  ewt[i] = rtol[1] * fabs(ycur[i]) + atol[i];
1918  break;
1919  case 3:
1920  for (i = 1; i <= n; i++)
1921  ewt[i] = rtol[i] * fabs(ycur[i]) + atol[1];
1922  break;
1923  case 4:
1924  for (i = 1; i <= n; i++)
1925  ewt[i] = rtol[i] * fabs(ycur[i]) + atol[i];
1926  break;
1927  }
1928 
1929 } /* end ewset */
1930 
1931 static void intdy(double t, int k, double *dky, int *iflag)
1932 
1933 /*
1934  Intdy computes interpolated values of the k-th derivative of the
1935  dependent variable vector y, and stores it in dky. This routine
1936  is called within the package with k = 0 and *t = tout, but may
1937  also be called by the user for any k up to the current order.
1938  ( See detailed instructions in the usage documentation. )
1939 
1940  The computed values in dky are gotten by interpolation using the
1941  Nordsieck history array yh. This array corresponds uniquely to a
1942  vector-valued polynomial of degree nqcur or less, and dky is set
1943  to the k-th derivative of this polynomial at t.
1944  The formula for dky is
1945 
1946  q
1947  dky[i] = sum c[k][j] * ( t - tn )^(j-k) * h^(-j) * yh[j+1][i]
1948  j=k
1949 
1950  where c[k][j] = j*(j-1)*...*(j-k+1), q = nqcur, tn = tcur, h = hcur.
1951  The quantities nq = nqcur, l = nq+1, n = neq, tn, and h are declared
1952  static globally. The above sum is done in reverse order.
1953  *iflag is returned negative if either k or t is out of bounds.
1954 */
1955 
1956 {
1957  int i, ic, j, jj, jp1;
1958  double c, r, s, tp;
1959 
1960  *iflag = 0;
1961  if (k < 0 || k > nq) {
1962  fprintf(stderr, "[intdy] k = %d illegal\n", k);
1963  *iflag = -1;
1964  return;
1965  }
1966  tp = tn - hu - 100. * ETA * (tn + hu);
1967  if ((t - tp) * (t - tn) > 0.) {
1968  fprintf(stderr, "intdy -- t = %g illegal. t not in interval tcur - hu to tcur\n", t);
1969  *iflag = -2;
1970  return;
1971  }
1972  s = (t - tn) / h;
1973  ic = 1;
1974  for (jj = l - k; jj <= nq; jj++)
1975  ic *= jj;
1976  c = (double) ic;
1977  yp1 = yh[l];
1978  for (i = 1; i <= n; i++)
1979  dky[i] = c * yp1[i];
1980  for (j = nq - 1; j >= k; j--) {
1981  jp1 = j + 1;
1982  ic = 1;
1983  for (jj = jp1 - k; jj <= j; jj++)
1984  ic *= jj;
1985  c = (double) ic;
1986  yp1 = yh[jp1];
1987  for (i = 1; i <= n; i++)
1988  dky[i] = c * yp1[i] + s * dky[i];
1989  }
1990  if (k == 0)
1991  return;
1992  r = pow(h, (double) (-k));
1993  for (i = 1; i <= n; i++)
1994  dky[i] *= r;
1995 
1996 } /* end intdy */
1997 
1998 static void cfode(int meth)
1999 {
2000  int i, nq, nqm1, nqp1;
2001  double agamq, fnq, fnqm1, pc[13], pint, ragq, rqfac, rq1fac, tsign, xpin;
2002 /*
2003  cfode is called by the integrator routine to set coefficients
2004  needed there. The coefficients for the current method, as
2005  given by the value of meth, are set for all orders and saved.
2006  The maximum order assumed here is 12 if meth = 1 and 5 if meth = 2.
2007  ( A smaller value of the maximum order is also allowed. )
2008  cfode is called once at the beginning of the problem, and
2009  is not called again unless and until meth is changed.
2010 
2011  The elco array contains the basic method coefficients.
2012  The coefficients el[i], 1 < i < nq+1, for the method of
2013  order nq are stored in elco[nq][i]. They are given by a generating
2014  polynomial, i.e.,
2015 
2016  l(x) = el[1] + el[2]*x + ... + el[nq+1]*x^nq.
2017 
2018  For the implicit Adams method, l(x) is given by
2019 
2020  dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1), l(-1) = 0.
2021 
2022  For the bdf methods, l(x) is given by
2023 
2024  l(x) = (x+1)*(x+2)*...*(x+nq)/k,
2025 
2026  where k = factorial(nq)*(1+1/2+...+1/nq).
2027 
2028  The tesco array contains test constants used for the
2029  local error test and the selection of step size and/or order.
2030  At order nq, tesco[nq][k] is used for the selection of step
2031  size at order nq-1 if k = 1, at order nq if k = 2, and at order
2032  nq+1 if k = 3.
2033 */
2034  if (meth == 1) {
2035  elco[1][1] = 1.;
2036  elco[1][2] = 1.;
2037  tesco[1][1] = 0.;
2038  tesco[1][2] = 2.;
2039  tesco[2][1] = 1.;
2040  tesco[12][3] = 0.;
2041  pc[1] = 1.;
2042  rqfac = 1.;
2043  for (nq = 2; nq <= 12; nq++) {
2044 /*
2045  The pc array will contain the coefficients of the polynomial
2046 
2047  p(x) = (x+1)*(x+2)*...*(x+nq-1).
2048 
2049  Initially, p(x) = 1.
2050 */
2051  rq1fac = rqfac;
2052  rqfac = rqfac / (double) nq;
2053  nqm1 = nq - 1;
2054  fnqm1 = (double) nqm1;
2055  nqp1 = nq + 1;
2056 /*
2057  Form coefficients of p(x)*(x+nq-1).
2058 */
2059  pc[nq] = 0.;
2060  for (i = nq; i >= 2; i--)
2061  pc[i] = pc[i - 1] + fnqm1 * pc[i];
2062  pc[1] = fnqm1 * pc[1];
2063 /*
2064  Compute integral, -1 to 0, of p(x) and x*p(x).
2065 */
2066  pint = pc[1];
2067  xpin = pc[1] / 2.;
2068  tsign = 1.;
2069  for (i = 2; i <= nq; i++) {
2070  tsign = -tsign;
2071  pint += tsign * pc[i] / (double) i;
2072  xpin += tsign * pc[i] / (double) (i + 1);
2073  }
2074 /*
2075  Store coefficients in elco and tesco.
2076 */
2077  elco[nq][1] = pint * rq1fac;
2078  elco[nq][2] = 1.;
2079  for (i = 2; i <= nq; i++)
2080  elco[nq][i + 1] = rq1fac * pc[i] / (double) i;
2081  agamq = rqfac * xpin;
2082  ragq = 1. / agamq;
2083  tesco[nq][2] = ragq;
2084  if (nq < 12)
2085  tesco[nqp1][1] = ragq * rqfac / (double) nqp1;
2086  tesco[nqm1][3] = ragq;
2087  } /* end for */
2088  return;
2089  } /* end if ( meth == 1 ) */
2090  /*
2091  meth = 2.
2092  */
2093  pc[1] = 1.;
2094  rq1fac = 1.;
2095 /*
2096  The pc array will contain the coefficients of the polynomial
2097 
2098  p(x) = (x+1)*(x+2)*...*(x+nq).
2099 
2100  Initially, p(x) = 1.
2101 */
2102  for (nq = 1; nq <= 5; nq++) {
2103  fnq = (double) nq;
2104  nqp1 = nq + 1;
2105 /*
2106  Form coefficients of p(x)*(x+nq).
2107 */
2108  pc[nqp1] = 0.;
2109  for (i = nq + 1; i >= 2; i--)
2110  pc[i] = pc[i - 1] + fnq * pc[i];
2111  pc[1] *= fnq;
2112 /*
2113  Store coefficients in elco and tesco.
2114 */
2115  for (i = 1; i <= nqp1; i++)
2116  elco[nq][i] = pc[i] / pc[2];
2117  elco[nq][2] = 1.;
2118  tesco[nq][1] = rq1fac;
2119  tesco[nq][2] = ((double) nqp1) / elco[nq][1];
2120  tesco[nq][3] = ((double) (nq + 2)) / elco[nq][1];
2121  rq1fac /= fnq;
2122  }
2123  return;
2124 
2125 } /* end cfode */
2126 
2127 static void scaleh(double *rh, double *pdh)
2128 {
2129  double r;
2130  int j, i;
2131 /*
2132  If h is being changed, the h ratio rh is checked against rmax, hmin,
2133  and hmxi, and the yh array is rescaled. ialth is set to l = nq + 1
2134  to prevent a change of h for that many steps, unless forced by a
2135  convergence or error test failure.
2136 */
2137  *rh = min(*rh, rmax);
2138  *rh = *rh / max(1., fabs(h) * hmxi * *rh);
2139 /*
2140  If meth = 1, also restrict the new step size by the stability region.
2141  If this reduces h, set irflag to 1 so that if there are roundoff
2142  problems later, we can assume that is the cause of the trouble.
2143 */
2144  if (meth == 1) {
2145  irflag = 0;
2146  *pdh = max(fabs(h) * pdlast, 0.000001);
2147  if ((*rh * *pdh * 1.00001) >= sm1[nq]) {
2148  *rh = sm1[nq] / *pdh;
2149  irflag = 1;
2150  }
2151  }
2152  r = 1.;
2153  for (j = 2; j <= l; j++) {
2154  r *= *rh;
2155  yp1 = yh[j];
2156  for (i = 1; i <= n; i++)
2157  yp1[i] *= r;
2158  }
2159  h *= *rh;
2160  rc *= *rh;
2161  ialth = l;
2162 
2163 } /* end scaleh */
2164 
2165 
2166 static void prja(int neq, double *y, _lsoda_f f, void *_data)
2167 {
2168  int i, ier, j;
2169  double fac, hl0, r, r0, yj;
2170 /*
2171  prja is called by stoda to compute and process the matrix
2172  P = I - h * el[1] * J, where J is an approximation to the Jacobian.
2173  Here J is computed by finite differencing.
2174  J, scaled by -h * el[1], is stored in wm. Then the norm of J ( the
2175  matrix norm consistent with the weighted max-norm on vectors given
2176  by vmnorm ) is computed, and J is overwritten by P. P is then
2177  subjected to LU decomposition in preparation for later solution
2178  of linear systems with p as coefficient matrix. This is done
2179  by dgefa if miter = 2, and by dgbfa if miter = 5.
2180 */
2181  nje++;
2182  ierpj = 0;
2183  jcur = 1;
2184  hl0 = h * el0;
2185 /*
2186  If miter = 2, make n calls to f to approximate J.
2187 */
2188  if (miter != 2) {
2189  fprintf(stderr, "[prja] miter != 2\n");
2190  return;
2191  }
2192  if (miter == 2) {
2193  fac = vmnorm(n, savf, ewt);
2194  r0 = 1000. * fabs(h) * ETA * ((double) n) * fac;
2195  if (r0 == 0.)
2196  r0 = 1.;
2197  for (j = 1; j <= n; j++) {
2198  yj = y[j];
2199  r = max(sqrteta * fabs(yj), r0 / ewt[j]);
2200  y[j] += r;
2201  fac = -hl0 / r;
2202  (*f) (tn, y + 1, acor + 1, _data);
2203  for (i = 1; i <= n; i++)
2204  wm[i][j] = (acor[i] - savf[i]) * fac;
2205  y[j] = yj;
2206  }
2207  nfe += n;
2208 /*
2209  Compute norm of Jacobian.
2210 */
2211  pdnorm = fnorm(n, wm, ewt) / fabs(hl0);
2212 /*
2213  Add identity matrix.
2214 */
2215  for (i = 1; i <= n; i++)
2216  wm[i][i] += 1.;
2217 /*
2218  Do LU decomposition on P.
2219 */
2220  dgefa(wm, n, ipvt, &ier);
2221  if (ier != 0)
2222  ierpj = 1;
2223  return;
2224  }
2225 } /* end prja */
2226 
2227 static double vmnorm(int n, double *v, double *w)
2228 
2229 /*
2230  This function routine computes the weighted max-norm
2231  of the vector of length n contained in the array v, with weights
2232  contained in the array w of length n.
2233 
2234  vmnorm = max( i = 1, ..., n ) fabs( v[i] ) * w[i].
2235 */
2236 
2237 {
2238  int i;
2239  double vm;
2240 
2241  vm = 0.;
2242  for (i = 1; i <= n; i++)
2243  vm = max(vm, fabs(v[i]) * w[i]);
2244  return vm;
2245 
2246 }
2247 
2248 static double fnorm(int n, double **a, double *w)
2249 
2250 /*
2251  This subroutine computes the norm of a full n by n matrix,
2252  stored in the array a, that is consistent with the weighted max-norm
2253  on vectors, with weights stored in the array w.
2254 
2255  fnorm = max(i=1,...,n) ( w[i] * sum(j=1,...,n) fabs( a[i][j] ) / w[j] )
2256 */
2257 
2258 {
2259  int i, j;
2260  double an, sum, *ap1;
2261 
2262  an = 0.;
2263  for (i = 1; i <= n; i++) {
2264  sum = 0.;
2265  ap1 = a[i];
2266  for (j = 1; j <= n; j++)
2267  sum += fabs(ap1[j]) / w[j];
2268  an = max(an, sum * w[i]);
2269  }
2270  return an;
2271 
2272 }
2273 
2274 static void correction(int neq, double *y, _lsoda_f f, int *corflag, double pnorm, double *del, double *delp, double *told,
2275  int *ncf, double *rh, int *m, void *_data)
2276 /*
2277  *corflag = 0 : corrector converged,
2278  1 : step size to be reduced, redo prediction,
2279  2 : corrector cannot converge, failure flag.
2280 */
2281 
2282 {
2283  int i;
2284  double rm, rate, dcon;
2285 
2286 /*
2287  Up to maxcor corrector iterations are taken. A convergence test is
2288  made on the r.m.s. norm of each correction, weighted by the error
2289  weight vector ewt. The sum of the corrections is accumulated in the
2290  vector acor[i]. The yh array is not altered in the corrector loop.
2291 */
2292 
2293  *m = 0;
2294  *corflag = 0;
2295  rate = 0.;
2296  *del = 0.;
2297  yp1 = yh[1];
2298  for (i = 1; i <= n; i++)
2299  y[i] = yp1[i];
2300  (*f) (tn, y + 1, savf + 1, _data);
2301  nfe++;
2302 /*
2303  If indicated, the matrix P = I - h * el[1] * J is reevaluated and
2304  preprocessed before starting the corrector iteration. ipup is set
2305  to 0 as an indicator that this has been done.
2306 */
2307  while (1) {
2308  if (*m == 0) {
2309  if (ipup > 0) {
2310  prja(neq, y, f, _data);
2311  ipup = 0;
2312  rc = 1.;
2313  nslp = nst;
2314  crate = 0.7;
2315  if (ierpj != 0) {
2316  corfailure(told, rh, ncf, corflag);
2317  return;
2318  }
2319  }
2320  for (i = 1; i <= n; i++)
2321  acor[i] = 0.;
2322  } /* end if ( *m == 0 ) */
2323  if (miter == 0) {
2324 /*
2325  In case of functional iteration, update y directly from
2326  the result of the last function evaluation.
2327 */
2328  yp1 = yh[2];
2329  for (i = 1; i <= n; i++) {
2330  savf[i] = h * savf[i] - yp1[i];
2331  y[i] = savf[i] - acor[i];
2332  }
2333  *del = vmnorm(n, y, ewt);
2334  yp1 = yh[1];
2335  for (i = 1; i <= n; i++) {
2336  y[i] = yp1[i] + el[1] * savf[i];
2337  acor[i] = savf[i];
2338  }
2339  }
2340  /* end functional iteration */
2341  /*
2342  In the case of the chord method, compute the corrector error,
2343  and solve the linear system with that as right-hand side and
2344  P as coefficient matrix.
2345  */
2346  else {
2347  yp1 = yh[2];
2348  for (i = 1; i <= n; i++)
2349  y[i] = h * savf[i] - (yp1[i] + acor[i]);
2350  solsy(y);
2351  *del = vmnorm(n, y, ewt);
2352  yp1 = yh[1];
2353  for (i = 1; i <= n; i++) {
2354  acor[i] += y[i];
2355  y[i] = yp1[i] + el[1] * acor[i];
2356  }
2357  } /* end chord method */
2358 /*
2359  Test for convergence. If *m > 0, an estimate of the convergence
2360  rate constant is stored in crate, and this is used in the test.
2361 
2362  We first check for a change of iterates that is the size of
2363  roundoff error. If this occurs, the iteration has converged, and a
2364  new rate estimate is not formed.
2365  In all other cases, force at least two iterations to estimate a
2366  local Lipschitz constant estimate for Adams method.
2367  On convergence, form pdest = local maximum Lipschitz constant
2368  estimate. pdlast is the most recent nonzero estimate.
2369 */
2370  if (*del <= 100. * pnorm * ETA)
2371  break;
2372  if (*m != 0 || meth != 1) {
2373  if (*m != 0) {
2374  rm = 1024.0;
2375  if (*del <= (1024. * *delp))
2376  rm = *del / *delp;
2377  rate = max(rate, rm);
2378  crate = max(0.2 * crate, rm);
2379  }
2380  dcon = *del * min(1., 1.5 * crate) / (tesco[nq][2] * conit);
2381  if (dcon <= 1.) {
2382  pdest = max(pdest, rate / fabs(h * el[1]));
2383  if (pdest != 0.)
2384  pdlast = pdest;
2385  break;
2386  }
2387  }
2388 /*
2389  The corrector iteration failed to converge.
2390  If miter != 0 and the Jacobian is out of date, prja is called for
2391  the next try. Otherwise the yh array is retracted to its values
2392  before prediction, and h is reduced, if possible. If h cannot be
2393  reduced or mxncf failures have occured, exit with corflag = 2.
2394 */
2395  (*m)++;
2396  if (*m == maxcor || (*m >= 2 && *del > 2. * *delp)) {
2397  if (miter == 0 || jcur == 1) {
2398  corfailure(told, rh, ncf, corflag);
2399  return;
2400  }
2401  ipup = miter;
2402 /*
2403  Restart corrector if Jacobian is recomputed.
2404 */
2405  *m = 0;
2406  rate = 0.;
2407  *del = 0.;
2408  yp1 = yh[1];
2409  for (i = 1; i <= n; i++)
2410  y[i] = yp1[i];
2411  (*f) (tn, y + 1, savf + 1, _data);
2412  nfe++;
2413  }
2414 /*
2415  Iterate corrector.
2416 */
2417  else {
2418  *delp = *del;
2419  (*f) (tn, y + 1, savf + 1, _data);
2420  nfe++;
2421  }
2422  } /* end while */
2423 } /* end correction */
2424 
2425 static void corfailure(double *told, double *rh, int *ncf, int *corflag)
2426 {
2427  int j, i1, i;
2428 
2429  ncf++;
2430  rmax = 2.;
2431  tn = *told;
2432  for (j = nq; j >= 1; j--)
2433  for (i1 = j; i1 <= nq; i1++) {
2434  yp1 = yh[i1];
2435  yp2 = yh[i1 + 1];
2436  for (i = 1; i <= n; i++)
2437  yp1[i] -= yp2[i];
2438  }
2439  if (fabs(h) <= hmin * 1.00001 || *ncf == mxncf) {
2440  *corflag = 2;
2441  return;
2442  }
2443  *corflag = 1;
2444  *rh = 0.25;
2445  ipup = miter;
2446 
2447 }
2448 
2449 static void solsy(double *y)
2450 
2451 /*
2452  This routine manages the solution of the linear system arising from
2453  a chord iteration. It is called if miter != 0.
2454  If miter is 2, it calls dgesl to accomplish this.
2455  If miter is 5, it calls dgbsl.
2456 
2457  y = the right-hand side vector on input, and the solution vector
2458  on output.
2459 */
2460 
2461 {
2462  iersl = 0;
2463  if (miter != 2) {
2464  printf("solsy -- miter != 2\n");
2465  return;
2466  }
2467  if (miter == 2)
2468  dgesl(wm, n, ipvt, y, 0);
2469  return;
2470 
2471 }
2472 
2473 static void methodswitch(double dsm, double pnorm, double *pdh, double *rh)
2474 {
2475  int lm1, lm1p1, lm2, lm2p1, nqm1, nqm2;
2476  double rh1, rh2, rh1it, exm2, dm2, exm1, dm1, alpha, exsm;
2477 
2478 /*
2479  We are current using an Adams method. Consider switching to bdf.
2480  If the current order is greater than 5, assume the problem is
2481  not stiff, and skip this section.
2482  If the Lipschitz constant and error estimate are not polluted
2483  by roundoff, perform the usual test.
2484  Otherwise, switch to the bdf methods if the last step was
2485  restricted to insure stability ( irflag = 1 ), and stay with Adams
2486  method if not. When switching to bdf with polluted error estimates,
2487  in the absence of other information, double the step size.
2488 
2489  When the estimates are ok, we make the usual test by computing
2490  the step size we could have (ideally) used on this step,
2491  with the current (Adams) method, and also that for the bdf.
2492  If nq > mxords, we consider changing to order mxords on switching.
2493  Compare the two step sizes to decide whether to switch.
2494  The step size advantage must be at least ratio = 5 to switch.
2495 */
2496  if (meth == 1) {
2497  if (nq > 5)
2498  return;
2499  if (dsm <= (100. * pnorm * ETA) || pdest == 0.) {
2500  if (irflag == 0)
2501  return;
2502  rh2 = 2.;
2503  nqm2 = min(nq, mxords);
2504  } else {
2505  exsm = 1. / (double) l;
2506  rh1 = 1. / (1.2 * pow(dsm, exsm) + 0.0000012);
2507  rh1it = 2. * rh1;
2508  *pdh = pdlast * fabs(h);
2509  if ((*pdh * rh1) > 0.00001)
2510  rh1it = sm1[nq] / *pdh;
2511  rh1 = min(rh1, rh1it);
2512  if (nq > mxords) {
2513  nqm2 = mxords;
2514  lm2 = mxords + 1;
2515  exm2 = 1. / (double) lm2;
2516  lm2p1 = lm2 + 1;
2517  dm2 = vmnorm(n, yh[lm2p1], ewt) / cm2[mxords];
2518  rh2 = 1. / (1.2 * pow(dm2, exm2) + 0.0000012);
2519  } else {
2520  dm2 = dsm * (cm1[nq] / cm2[nq]);
2521  rh2 = 1. / (1.2 * pow(dm2, exsm) + 0.0000012);
2522  nqm2 = nq;
2523  }
2524  if (rh2 < ratio * rh1)
2525  return;
2526  }
2527 /*
2528  The method switch test passed. Reset relevant quantities for bdf.
2529 */
2530  *rh = rh2;
2531  icount = 20;
2532  meth = 2;
2533  miter = jtyp;
2534  pdlast = 0.;
2535  nq = nqm2;
2536  l = nq + 1;
2537  return;
2538  } /* end if ( meth == 1 ) */
2539  /*
2540  We are currently using a bdf method, considering switching to Adams.
2541  Compute the step size we could have (ideally) used on this step,
2542  with the current (bdf) method, and also that for the Adams.
2543  If nq > mxordn, we consider changing to order mxordn on switching.
2544  Compare the two step sizes to decide whether to switch.
2545  The step size advantage must be at least 5/ratio = 1 to switch.
2546  If the step size for Adams would be so small as to cause
2547  roundoff pollution, we stay with bdf.
2548  */
2549  exsm = 1. / (double) l;
2550  if (mxordn < nq) {
2551  nqm1 = mxordn;
2552  lm1 = mxordn + 1;
2553  exm1 = 1. / (double) lm1;
2554  lm1p1 = lm1 + 1;
2555  dm1 = vmnorm(n, yh[lm1p1], ewt) / cm1[mxordn];
2556  rh1 = 1. / (1.2 * pow(dm1, exm1) + 0.0000012);
2557  } else {
2558  dm1 = dsm * (cm2[nq] / cm1[nq]);
2559  rh1 = 1. / (1.2 * pow(dm1, exsm) + 0.0000012);
2560  nqm1 = nq;
2561  exm1 = exsm;
2562  }
2563  rh1it = 2. * rh1;
2564  *pdh = pdnorm * fabs(h);
2565  if ((*pdh * rh1) > 0.00001)
2566  rh1it = sm1[nqm1] / *pdh;
2567  rh1 = min(rh1, rh1it);
2568  rh2 = 1. / (1.2 * pow(dsm, exsm) + 0.0000012);
2569  if ((rh1 * ratio) < (5. * rh2))
2570  return;
2571  alpha = max(0.001, rh1);
2572  dm1 *= pow(alpha, exm1);
2573  if (dm1 <= 1000. * ETA * pnorm)
2574  return;
2575 /*
2576  The switch test passed. Reset relevant quantities for Adams.
2577 */
2578  *rh = rh1;
2579  icount = 20;
2580  meth = 1;
2581  miter = 0;
2582  pdlast = 0.;
2583  nq = nqm1;
2584  l = nq + 1;
2585 
2586 } /* end methodswitch */
2587 
2588 
2589 /*
2590  This routine returns from stoda to lsoda. Hence freevectors() is
2591  not executed.
2592 */
2593 static void endstoda()
2594 {
2595  double r;
2596  int i;
2597 
2598  r = 1. / tesco[nqu][2];
2599  for (i = 1; i <= n; i++)
2600  acor[i] *= r;
2601  hold = h;
2602  jstart = 1;
2603 
2604 }
2605 
2606 static void orderswitch(double *rhup, double dsm, double *pdh, double *rh, int *orderflag)
2607 
2608 /*
2609  Regardless of the success or failure of the step, factors
2610  rhdn, rhsm, and rhup are computed, by which h could be multiplied
2611  at order nq - 1, order nq, or order nq + 1, respectively.
2612  In the case of a failure, rhup = 0. to avoid an order increase.
2613  The largest of these is determined and the new order chosen
2614  accordingly. If the order is to be increased, we compute one
2615  additional scaled derivative.
2616 
2617  orderflag = 0 : no change in h or nq,
2618  1 : change in h but not nq,
2619  2 : change in both h and nq.
2620 */
2621 
2622 {
2623  int newq, i;
2624  double exsm, rhdn, rhsm, ddn, exdn, r;
2625 
2626  *orderflag = 0;
2627 
2628  exsm = 1. / (double) l;
2629  rhsm = 1. / (1.2 * pow(dsm, exsm) + 0.0000012);
2630 
2631  rhdn = 0.;
2632  if (nq != 1) {
2633  ddn = vmnorm(n, yh[l], ewt) / tesco[nq][1];
2634  exdn = 1. / (double) nq;
2635  rhdn = 1. / (1.3 * pow(ddn, exdn) + 0.0000013);
2636  }
2637 /*
2638  If meth = 1, limit rh accordinfg to the stability region also.
2639 */
2640  if (meth == 1) {
2641  *pdh = max(fabs(h) * pdlast, 0.000001);
2642  if (l < lmax)
2643  *rhup = min(*rhup, sm1[l] / *pdh);
2644  rhsm = min(rhsm, sm1[nq] / *pdh);
2645  if (nq > 1)
2646  rhdn = min(rhdn, sm1[nq - 1] / *pdh);
2647  pdest = 0.;
2648  }
2649  if (rhsm >= *rhup) {
2650  if (rhsm >= rhdn) {
2651  newq = nq;
2652  *rh = rhsm;
2653  } else {
2654  newq = nq - 1;
2655  *rh = rhdn;
2656  if (kflag < 0 && *rh > 1.)
2657  *rh = 1.;
2658  }
2659  } else {
2660  if (*rhup <= rhdn) {
2661  newq = nq - 1;
2662  *rh = rhdn;
2663  if (kflag < 0 && *rh > 1.)
2664  *rh = 1.;
2665  } else {
2666  *rh = *rhup;
2667  if (*rh >= 1.1) {
2668  r = el[l] / (double) l;
2669  nq = l;
2670  l = nq + 1;
2671  yp1 = yh[l];
2672  for (i = 1; i <= n; i++)
2673  yp1[i] = acor[i] * r;
2674  *orderflag = 2;
2675  return;
2676  } else {
2677  ialth = 3;
2678  return;
2679  }
2680  }
2681  }
2682 /*
2683  If meth = 1 and h is restricted by stability, bypass 10 percent test.
2684 */
2685  if (meth == 1) {
2686  if ((*rh * *pdh * 1.00001) < sm1[newq])
2687  if (kflag == 0 && *rh < 1.1) {
2688  ialth = 3;
2689  return;
2690  }
2691  } else {
2692  if (kflag == 0 && *rh < 1.1) {
2693  ialth = 3;
2694  return;
2695  }
2696  }
2697  if (kflag <= -2)
2698  *rh = min(*rh, 0.2);
2699 /*
2700  If there is a change of order, reset nq, l, and the coefficients.
2701  In any case h is reset according to rh and the yh array is rescaled.
2702  Then exit or redo the step.
2703 */
2704  if (newq == nq) {
2705  *orderflag = 1;
2706  return;
2707  }
2708  nq = newq;
2709  l = nq + 1;
2710  *orderflag = 2;
2711 
2712 } /* end orderswitch */
2713 
2714 
2715 static void resetcoeff()
2716 /*
2717  The el vector and related constants are reset
2718  whenever the order nq is changed, or at the start of the problem.
2719 */
2720 {
2721  int i;
2722  double *ep1;
2723 
2724  ep1 = elco[nq];
2725  for (i = 1; i <= l; i++)
2726  el[i] = ep1[i];
2727  rc = rc * el[1] / el0;
2728  el0 = el[1];
2729  conit = 0.5 / (double) (nq + 2);
2730 
2731 }
2732 
2733 /* this function does nothing. */
2734 static void freevectors(void)
2735 {
2736 }
2737 
2738 static void _freevectors(void)
2739 {
2740  int i;
2741  if (wm) for (i = 1; i <= g_nyh; ++i) free(wm[i]);
2742  if (yh) for (i = 1; i <= g_lenyh; ++i) free(yh[i]);
2743  free(yh); free(wm); free(ewt); free(savf); free(acor); free(ipvt);
2744  g_nyh = g_lenyh = 0;
2745  yh = 0; wm = 0;
2746  ewt = 0; savf = 0; acor = 0; ipvt = 0;
2747 }
2748 
2749 /*****************************
2750  * more convenient interface *
2751  *****************************/
2752 
2753 int n_lsoda(double y[], int n, double *x, double xout, double eps, const double yscal[], _lsoda_f devis, void *data)
2754 {
2755  int i, istate, itask;
2756  double *_y, *atol, *rtol;
2757  _y = (double *) calloc(3 * (n + 1), sizeof(double));
2758  atol = _y + n + 1;
2759  rtol = atol + n + 1;
2760  for (i = 1; i <= n; ++i) {
2761  _y[i] = y[i - 1];
2762  atol[i] = eps * yscal[i - 1];
2763  }
2764  istate = init? 2 : 1;
2765  itask = 2;
2766  lsoda(devis, n, _y, x, xout, 2, rtol, atol, itask, &istate, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0., 0., 0., 0., data);
2767  for (i = 1; i <= n; ++i) y[i - 1] = _y[i];
2768  free(_y);
2769  return istate < 0 ? istate : 0;
2770 }
2771 
2773 {
2774  if (init) _freevectors();
2775  init = 0;
2776 }
2777 
2778 /*************
2779  * example.c *
2780  *************/
2781 
2782 #ifdef _LSODA_MAIN
2783 static void fex(double t, double *y, double *ydot, void *data)
2784 {
2785  ydot[0] = 1.0E4 * y[1] * y[2] - .04E0 * y[0];
2786  ydot[2] = 3.0E7 * y[1] * y[1];
2787  ydot[1] = -1.0 * (ydot[0] + ydot[2]);
2788 }
2789 
2790 int main(void)
2791 {
2792  double rwork1, rwork5, rwork6, rwork7;
2793  double atol[4], rtol[4], t, tout, y[4];
2794  int iwork1, iwork2, iwork5, iwork6, iwork7, iwork8, iwork9;
2795  int neq = 3;
2796  int itol, itask, istate, iopt, jt, iout;
2797 
2798  iwork1 = iwork2 = iwork5 = iwork6 = iwork7 = iwork8 = iwork9 = 0;
2799  rwork1 = rwork5 = rwork6 = rwork7 = 0.0;
2800  y[1] = 1.0E0;
2801  y[2] = 0.0E0;
2802  y[3] = 0.0E0;
2803  t = 0.0E0;
2804  tout = 0.4E0;
2805  itol = 2;
2806  rtol[0] = 0.0;
2807  atol[0] = 0.0;
2808  rtol[1] = rtol[3] = 1.0E-4;
2809  rtol[2] = 1.0E-8;
2810  atol[1] = 1.0E-6;
2811  atol[2] = 1.0E-10;
2812  atol[3] = 1.0E-6;
2813  itask = 1;
2814  istate = 1;
2815  iopt = 0;
2816  jt = 2;
2817 
2818  for (iout = 1; iout <= 12; iout++) {
2819  lsoda(fex, neq, y, &t, tout, itol, rtol, atol, itask, &istate, iopt, jt,
2820  iwork1, iwork2, iwork5, iwork6, iwork7, iwork8, iwork9,
2821  rwork1, rwork5, rwork6, rwork7, 0);
2822  printf(" at t= %12.4e y= %14.6e %14.6e %14.6e\n", t, y[1], y[2], y[3]);
2823  if (istate <= 0) {
2824  printf("error istate = %d\n", istate);
2825  exit(0);
2826  }
2827  tout = tout * 10.0E0;
2828  }
2830 
2831  return 0;
2832 }
2833 /*
2834  The correct answer (up to certain precision):
2835 
2836  at t= 4.0000e-01 y= 9.851712e-01 3.386380e-05 1.479493e-02
2837  at t= 4.0000e+00 y= 9.055333e-01 2.240655e-05 9.444430e-02
2838  at t= 4.0000e+01 y= 7.158403e-01 9.186334e-06 2.841505e-01
2839  at t= 4.0000e+02 y= 4.505250e-01 3.222964e-06 5.494717e-01
2840  at t= 4.0000e+03 y= 1.831976e-01 8.941773e-07 8.168015e-01
2841  at t= 4.0000e+04 y= 3.898729e-02 1.621940e-07 9.610125e-01
2842  at t= 4.0000e+05 y= 4.936362e-03 1.984221e-08 9.950636e-01
2843  at t= 4.0000e+06 y= 5.161833e-04 2.065787e-09 9.994838e-01
2844  at t= 4.0000e+07 y= 5.179804e-05 2.072027e-10 9.999482e-01
2845  at t= 4.0000e+08 y= 5.283675e-06 2.113481e-11 9.999947e-01
2846  at t= 4.0000e+09 y= 4.658667e-07 1.863468e-12 9.999995e-01
2847  at t= 4.0000e+10 y= 1.431100e-08 5.724404e-14 1.000000e+00
2848  */
2849 #endif