C      ALGORITHM 648, COLLECTED ALGORITHMS FROM ACM.
C      THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE,
C      VOL. 13, NO. 1, P. 28
 
 
 
 
 
 
 
 
 
Brief  information  for  DETEST 1986 version (sufficient  for  preliminary
tests of the code without the timing facility).
 
 
Implementation Steps
--------------------
 
1.  In routine CONST in CONCLK.F insert a data statement suitable for your
    machine.  (See  implementation  notes  in  STDOC.T or NSDOC.T.  Sample
    settings are included in CONST in comments.)
 
2.  Insert system calls to suppress underflow  exceptions,  and  any other
    needed  initialization,  in  the  I=0 section of CONST.  Again, sample
    code is included.
 
3.  The program consisting of NSTTRU.F,  NSDTST.F,  NSTRUE.F, NSPROB.F and
    CONCLK.F  should  now  compile  and  run,  giving  output  similar  to
    NSTTRU.O.
 
4.  Similarly with STTTRU.F, STDTST.F, STTRUE.F, STPROB.F and CONCLK.F.
 
 
 
1. Purpose
   -------
 
Two packages are provided for assessing  the  performance  of  initial
value  solvers.  The  first  package, whose main routine is NSDTST, is
designed  for  assessing  the  performance  of  solvers  suitable  for
non-stiff systems, while the second  package,  whose  main  routine is
STDTST,  is designed for assessing the performance of solvers suitable
for stiff  systems.  Each package consists of a number of routines but
the user need only  be  aware of the main routine and the routines FCN
(and for the stiff package, PDERV), and STATS, whose role is explained
below.   In  this  document  we  will   describe  the  use  of  STDTST
(double precision version).  The requirements and  calling sequence of
NSDTST  are almost identical.  In [4] the  design   of   the   testing
package is  discussed  and  guidance is given on the interpretation of
the results it produces.
 
A set of test problems, described in detail in [2,3], is  incorporated
in  the stiff package.  The code being tested is run on a selection of
these problems at various tolerances.  The user  selects  the problems
and  the  tolerances,    and    also    organizes  the  problems  into
groups  for statistical reporting purposes, at his discretion.
 
To test a code a user must write an interface routine  called  METHOD,
described  below, and then call STDTST with the desired options.  Note
that  STDTST  comes in a 'single' and a 'double' precision version. It
is best if the version used  matches the precision of the SOLVER under
test. If this is not possible then  great  care must be exercised when
constructing  METHOD.  The   arguments  of  STDTST  are, in any event,
always  single  precision  but those of METHOD are of single or double
precision according to the version used.
 
The package divides naturally into five parts:
 
STDTST,CNTROL and various service routines
        organize  the  assembling,  computation   and   reporting   of
        statistics.
 
STATS
        is the routine which 'instruments' the code being  tested  and
        passes statistics via COMMON to CNTROL and STDTST.
 
FCN, PDERV, IVALU, EVALU
        describe the set of test problems.  FCN gives the r.h.s.  f(y)
        of  the  ODE system and PDERV gives the Jacobian matrix df/dy.
        (At present all the problems are posed  in  autonomous  form).
        IVALU  gives the initial conditions, scaling weights and other
        data about each  problem.   EVALU  gives  accurately  computed
        values at the endpoint.
 
DDCOMP and DSOLVE
        are standard (double precision) LU decomposition and backsolve
        routines  for full matrices, compatible with the layout of the
        Jacobian produced by PDERV.  They are used  by  TRUE  but  are
        available for use by the code being tested if desired.
 
TRUE and its subordinate routines
        (alias the Addison-Enright code SECDER) form a reliable  stiff
        solver  for  computing  the  'true' global and local solutions
        when required.
 
There is also a 'dummy' STDTST and STATS to help the  user  debug  his
METHOD routine (described below);  a  utility GENTIM which can be used
on each new machine to generate  timing  data  embedded  in  the code;
and  a  utility  GENWT which can be used if ever a  user wishes to add
further test problems to the set.
 
 
 
Main Lines of Calling Hierarchy (user-supplied routines are in boxes)
 
+--------+
| User's |---STDTST---CNTROL-----IVALU
|Program |                  |               +--------+
+--------+                  |   +------+    |'SOLVER'|
                            |---|METHOD|----|(Code   |->-+
                            |   +------+    | being  |   |
                            |          |    | tested)|   |
                            |          |    +--------+   |---FCN,PDERV
                            |          |                 |
                            |          STATS---TRUE--->--+
                            |
                            +----EVALU
 
We acknowledge valuable recommendations in Shampine's paper  [5].   In
particular  the  package  will,  by  default, integrate each system in
scaled form, scaling each solution component by its  maximum  observed
value  over the range of integration.  That is, the change of variable
     -1
z = D  y is done where
                       D = diag(w(1), .., w(n))
 
and w(i) =max |i-th component of  y|  over  the  range.   The  problem
                       -1
solved  is  then z' = D  f(x,Dz).  The  weights  w(i) were found by an
accurate  integration  of  each  problem and  are  embedded  in IVALU.
Note   that   this  scaling  affects  the  norms  which  are  used  in
measuring all errors, and thus can have a considerable effect  on  the
accuracy in some of the problems.
 
If the problem code in IDLIST (see below) is given a negative sign the
system  is  solved  in  its 'natural' scaling, as was done in the 1975
version of DETEST.
 
 
 
 
 
 
2. Arguments to STDTST:
   --------- -- -------
 
TITLE   (input) Character of length 80,  holds  name  of  method being
        tested.
 
OPTION  (input)  Integer  array of length 10, only elements 1 to 3 are
        used and are referred to henceforth as OPT, NORMEF and NRMTYP.
        (OPTION(4) is also used when OPT=4)
 
OPT     one of 1, 2, 3 or 4. OPT selects level  of analysis required:
     1  gives a report of the following at each tolerance used:
      - Total time per integration
      - Overhead time excluding function and Jacobian calls and matrix
        factorizations.
      - Number   of   function   calls,   Jacobian    calls,    matrix
        factorizations and successful steps over range
      - Global error at endpoint XEND, divided by TOL, ie.
                  ||(computed y) - (true y)||/TOL  at x=XEND
        The norm used throughout the package is that chosen by NRMTYP.
 
    2   reports (in addition to the above statistics):
      - Maximum global error  over  range.  The 'true'  solution  over
        the  range  is  obtained  by  a  reliable integrator at a more
        stringent tolerance.
 
    3   reports (in addition to the above):
      - Maximum local error over range, ie.  max over  all  meshpoints
        of
               LENRM = ||(computed y) -  yloc||/ERRBND
        where yloc is the true local  solution  through  the  previous
        meshpoint,  and  ERRBND, the assumed error bound, is explained
        below.
      - Fraction of steps where LENRM exceeded 1.
      - Fraction of steps where LENRM exceeded 5.
 
    4   reports (in addition to the above):
     -  An analysis of the local error estimates used by SOLVER as the
        basis for its error control.
        Under development and described more fully in the actual code.
 
NORMEF  one  of  0   1   or   2   ,   selects   normalized  efficiency
        statistics.    These  try  to  compensate  for  the  fact that
        achieved  accuracy  may  be much higher or lower   than   that
        requested  by  TOL, and this relationship is very problem- and
        method- dependent.  For each problem, a least-squares  fit  is
        made of log10(actual error) vs log10(TOL) and used to estimate
        what the various cost statistics would be for an actual  error
        of 10**n.  This is achieved by interpolation, for those n such
        that 10**n lies within the range of accuracies  achieved  with
        the user-specified tolerances.
    0   No normalized statistics
    1   Normalized statistics are produced taking the  'actual  error'
        used in the least squares fit to be the endpoint global error.
    2   Normalized statistics are produced taking  'actual  error'  as
        the  maximum  global error over the range.  N.B.  In this case
        OPT must be at least 2.
 
 
 
NRMTYP  one of 1, 2  or 3, selects the norm used in assessing the size
        of local and global errors. It should be chosen by the user to
        agree with the norm used in SOLVER. We offer:
    1   Max-norm.
    2   2-norm (Euclidean norm).
    3   r.m.s. norm, that is (2-norm of x)/sqrt(n) for an n-vector x.
 
TOL     (input) Real array, holds list of up to 10  tolerances  to  be
        used,  in  strictly  decreasing  order,  with 0 as terminator.
        Each Problem is integrated at each tolerance in turn.
        Example:  in calling program
                  REAL TOL(11)
                  DATA TOL/1E-1,1E-3,1E-5,1E-7,7*0E0/
        requests the four tolerances .1, .001, .00001, .0000001.
 
IDLIST  (input) Integer array, holds list of groups of  problems,  and
        specifies  for  each  one  whether  it  is to be integrated in
        scaled or unscaled  form  (see  General  Notes  above).   Each
        problem  is specified by a numeric code, 11 to 14 for problems
        A1 to A4, 21 to 25 for B1 to B5  etc.   A  zero  terminates  a
        group and two zeros terminate the list of groups.
        If the problem code is given a negative sign,  the  system  is
        integrated  in  unscaled  form;  if a positive sign, in scaled
        form.
        Example:  in calling program
                  INTEGER IDLIST(7)
                  DATA IDLIST/11,22,0,-31,-51,0,0/
        specifies Group 1 consisting of Problems A1,B2 and Group 2  of
        Problems  C1,E1.  The first two are to be solved in the scaled
        form and the last two  in  unscaled  form.
 
        The total length of the list including zeros must be  at  most
        60 items.
 
FLAG
        (output) Real.  A nonzero value indicates  that  the  call  to
        STDTST  was  aborted because of argument errors, in which case
        the values of the decimal digits of FLAG indicate the error(s)
        that have occurred, as follows:
          1:  OPT invalid.
          2:  NORMEF invalid.
          3:  NORMEF = 2 was requested with OPT = 1.
          4:  A negative  tolerance  was  supplied,  or the  list  of
              tolerances was not in decreasing order.
          5:  The list of tolerances was empty or not terminated by a
              zero.
          6:  An invalid Problem-Id was found in IDLIST.
          7:  The list  of  groups  in  IDLIST  is  empty  or  is not
              terminated  by  two  zeros or has more than the maximum
              allowed number (6) of groups.
          8:  NRMTYP invalid.
        Eg.  a value FLAG = 0.245E 03 indicates that errors 2, 4 and 5
        in  the  above  list  have  occurred.  Its value if nonzero is
        printed by STDTST anyway, but FLAG is meant to be inspected if
        further  action  of  the  main program depends on a successful
        call to STDTST.
 
 
3. Interface routine METHOD
   --------- ------- ------
 
This invokes the code being tested, call it SOLVER.  The specification
is
 
 
        SUBROUTINE METHOD(N,X,Y,XEND,TOL,HMAX,HSTART)
        INTEGER N
        DOUBLE PRECISION X,Y(N),XEND,TOL,HMAX,HSTART
        EXTERNAL FCN, PDERV
 
METHOD is to be written by the user as a simple integrator to  advance
the  solution of N differential equations from the initial values held
in X,Y up to XEND, with an unweighted absolute error control  of  TOL.
HMAX  is  a  recommended  maximum stepsize and HSTART is a recommended
initial stepsize.  If SOLVER can make use of these two parameters, the
statistics will probably be more favorable and reliable, but their use
is not crucial.
 
The derivatives, and the analytical Jacobian matrix,  of  the  problem
are  computed  by  package  routines FCN and PDERV respectively.  Thus
certainly FCN, and in most cases PDERV, must be arguments  to  SOLVER,
and they must be declared EXTERNAL in METHOD.
 
METHOD should call SOLVER in one-step mode  so  that  a  call  to  the
package  routine  STATS  can  be  made after each successful step.  If
SOLVER does not have this facility, SOLVER must have a call  to  STATS
inserted at the appropriate point in the code.
 
Some  calls  to  METHOD  are  intended  to  be  aborted  after  a  few
integration  steps  by  the  STATS call setting X = XEND.  Thus a test
should be made after each call to STATS, of the form
        if STATS has set X = XEND then EXIT.
 
NB:  If the actual X  argument  to  STATS  is  different  from  the  X
argument  of METHOD (which may be necessary with some SOLVERs), ensure
that the X argument of METHOD is set to XEND  before  exit,  else  the
package will report 'METHOD failed to start'.
 
The algorithm for METHOD should thus be of the form:
- Declare all arguments and workspace expected by SOLVER
- Set appropriate options  including  absolute  error  control  and
   one-step mode
- Initialize extra arguments if required
- FOR each successful step DO
   - Call SOLVER( ...  ,FCN,PDERV, ...  )
     EXIT if SOLVER is in trouble.
   - Set X,Y to the just computed meshpoint x and solution vector y
   - Set ERRBND to the bound that is  satisfied  by ||ERREST||, and
     hence is intended to be satisfied by ||LE||, at this step.
   - Set ERREST  to the  local error estimate  vector (OPT=4 only)
 
     (See   [4]   for   discussion  and  note  that X,Y are ignored
     unless  OPT.GE.2,  ERRBND   is  ignored  unless  OPT.GE.3, and
     ERREST is ignored unless OPT.GE.4.)
 
   - Call STATS(X,Y,ERRBND,ERREST)
   - EXIT if X .ge.  XEND.
- ENDLOOP
 
 
On normal exit X,Y must hold XEND and the solution at XEND.   On  exit
because  SOLVER  was  in trouble, X must hold the final point reached.
On an exit forced by STATS, X must hold XEND.
 
 
 
 
4. Controlling the destination of output
   ----------- --- ----------- -- ------
 
 
 
The unit number on which the package writes its output  is  set  by  a
call  to one of the package routines, and you can find out what it is,
by putting the statement
 
      IOUT = CONST(3)
 
in your main program.  Probably output will default to your  terminal,
which  is  good  for debugging.  For more serious work you may want to
send output to a file.  The statements
 
      IOUT = CONST(3)
      OPEN(IOUT, FILE=filename, other options..  )
 
will do this for you, assuming your  Fortran   I/O  is consistent with
the  1977 standard.
 
5. The routines FCN, PDERV
   --- -------- ---- -----
 
The specification of FCN is
        SUBROUTINE FCN(X,Y,YP)
        DOUBLE PRECISION X,Y(20),YP(20)
 
On entry X holds the independent variable and Y holds  the  vector  of
dependent  variables.   On exit YP holds the vector of derivatives for
the problem being solved (selected by a switch in COMMON).
 
The specification for PDERV is
        SUBROUTINE PDERV(X,Y,DY)
        DOUBLE PRECISION X,Y(20),DY(400)
 
where X and Y are as for FCN.  The entries of the Jacobian matrix  are
stored  in the first N**2 elements of DY with df(i)/dy(j) being stored
in element i+(j-1)*N.  Thus DY may be treated as if it were declared
        DIMENSION DY(N,N)
 
6. Function, Jacobian and LU Decomposition counts
   --------- -------- --- -- ------------- ------
 
These are maintained in three COMMON variables:
        COMMON/STCOM6/NFCN,NJAC,NLUD
 
Each call to FCN, PDERV and DDCOMP increments NFCN, NJAC and NLUD by 1
respectively.   If  SOLVER  uses its own linear algebra routines it is
the user's responsibility to insert the above COMMON at an appropriate
place  in  his  code  and  set  NLUD  correctly.   This may be done by
incrementing it at each LU decomposition call, or by setting it  equal
to an independently maintained count before exit from METHOD.  Similar
comments apply to NJAC if SOLVER does its own Jacobian evaluation (eg.
by  numerical differencing).  If a method does not use Jacobians, NJAC
and NLUD may be used for gathering some other statistics.
 
 
 
7. Sample Program
   ------ -------
 
The following driver is the program used  to  generate  the results of
Fig. 4 of [4].
 
 
C   SAMPLE DRIVER FOR STDTST, WITH ONE GROUP CONSISTING  ONLY
C   OF PROBLEM E3 SOLVED IN SCALED FORM, AT FOUR TOLERANCES.
C   IN THIS CASE THE ARRAYS IDLIST, TOL NEED NOT BE SO LONG.
C
      CHARACTER TITLE*80
      INTEGER OPTION(10),IDLIST(60)
      REAL TOL(11)
      DATA TITLE/'SECDER, ADDISON-ENRIGHT SECOND DERIVATIVE METHOD'/
     *    , OPTION/2, 2, 1, 0, 6*0/
     *    , TOL/1E-2, 1E-4, 1E-6, 1E-8, 7*0E0/
     *    , IDLIST/53, 0, 58*0/
      CALL STDTST(TITLE, OPTION, TOL, IDLIST, FLAG)
      STOP
      END
C
C
      SUBROUTINE METHOD(N,X,Y,XEND,TOL,HMAX,HSTART)
C
C     DRIVER FOR THE SECDER CODE WHICH IS PART OF THE PACKAGE.
C     IT IS SOMEWHAT LENGTHY BECAUSE ITS INTERRUPT MECHANISM DOES
C     NOT ALLOW INTERRUPT IMMEDIATELY AFTER ACCEPTING A STEP.
C
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
      DOUBLE PRECISION X,Y(N),XEND,TOL,HMAX,HSTART
      EXTERNAL FCN,PDERV
      DOUBLE PRECISION C(20),YP(20,11),W(400),PD(400),WK(20,12)
      INTEGER INF(40)
C
      COMMON/STCOM6/NFCN,NJAC,NLUD
C
      DATA NDIM/20/
C
      IND=2
      DO 20 I=1,5
         INF(I)=0
         C(I)=0.D0
20    CONTINUE
C
C   SET ABS ERROR CONTROL: INF(1); INTERRUPT NO. 2: INF(5);
C   MIN,MAX & STARTING STEPSIZE: C(2),C(4),C(5).
      INF(1)=1
      INF(5)=1
      C(2)=1D-12
      C(4)=HMAX
      C(5)=HSTART
C
50    CALL TRUE(FCN,PDERV,NDIM,N,X,Y,XEND,TOL,IND,C,INF,YP,W,PD,WK)
      IF(IND.EQ.6)GOTO 50
C     WRITE(5,999)X,Y,C(13),(WK(I,1),I=1,N)
C999  FORMAT(20X,10F10.6)
      IF(IND.NE.5) GOTO 60
         TEMP=C(13)
C  C(13),WK(*,1) ARE THE ABOUT-TO-BE-ACCEPTED X,Y.
C  WK(*,12) IS THE ERROR-ESTIMATE VECTOR, DELIVERED
C  BY A SMALL CHANGE IN 'TRUE'.
         CALL STATS(C(13),WK(1,1),TOL,WK(1,12))
         IF(C(13).NE.TEMP) GOTO 70
      GOTO 50
C
60    IF(IND.NE.3) GOTO 70
         X = XEND
      GOTO 80
C
C   FAILURE EXIT OF SOME KIND:
70    X=C(13)
C      WRITE(IOUT,110)IND,(INF(I),I=9,15)
C110   FORMAT(1H ,'IND,INF(9)..INF(15)=',8I10)
80    CONTINUE
      NLUD=INF(15)
      RETURN
      END
*
*
*
*
*
References
-----------
*
[1]  W  H  Enright,  'Using  a  testing  package  for  the   automatic
     assessment   of  numerical  methods  for  ODEs',  in  Performance
     Evaluation of Numerical  Software,  (Fosdick,  ed),  IFIP,  North
     Holland Publ Co (1979) 199-213.
*
*
[2]  W H Enright and T E Hull, 'Comparing numerical  methods  for  the
     solution  of  stiff  systems  of  ODEs  arising in chemistry', in
     Numerical  Methods  for   Differential   Systems   (Lapidus   and
     Schiesser, eds), Academic Press, New York (1976) 45-65.
*
[3]  W H Enright, T  E  Hull  and  B  Lindberg,  'Comparing  numerical
     methods  for  stiff  systems of ordinary differential equations',
     BIT 15(1975) 10-48.
*
[4]  W H Enright and J D Pryce, 'A  pair  of  packages  for  assessing
     initial  value  methods',  University of Toronto Technical Report
     no.  167/83.
*
[5]  L F Shampine 'Evaluation of a test set for  stiff  ODE  solvers',
     TOMS 7(1981)409-420.
*
*
*
      REAL FUNCTION CONST(I)
C
C********+*********+*********+*********+*********+*********+*********+**
C     .. Scalar Arguments ..
      INTEGER             I
C     .. Local Scalars ..
      CHARACTER*32        MCNAME
C     .. Local Arrays ..
      REAL                C(4)
C     .. Intrinsic Functions ..
      INTRINSIC           ICHAR
C     .. Data statements ..
C
C  CONST AND CLOCK ENCLOSE (WE HOPE) ALL THE MACHINE-DEPENDENT PARTS
C  OF THE STIFF AND NONSTIFF DETEST PACKAGES, EXCEPT THE TIMING
C  DATA IN THE IVALU ROUTINE OF EACH PACKAGE.
C
C  CALLS WITH VALUES I=1 TO 4 RETURN THE FOLLOWING VALUES IN 'CONST':
C     I=1 UNIT ROUNDOFF APPROXIMATELY, IN THE PRECISION USED BY THE
C         ODE-SOLVING PART OF THE PACKAGE.
C     I=2 NUMBER NEAR UNDERFLOW THRESHOLD
C     I=3 STANDARD OUTPUT UNIT NUMBER
C     I=4 VALUE OF TSTTIM (USED IN CNTROL)
C
C  CALLS WITH VALUES -1 TO -32 RETURN THE 'ICHAR' VALUE OF SUCCESSIVE
C  CHARACTERS OF THE NAME OF THE COMPUTER WE ARE RUNNING ON. (CLUMSY BUT
C  INTENDED TO ISOLATE MACHINE-DEPENDENCIES HERE)
C
C  A CALL WITH I OUTSIDE THESE RANGES (DONE WITH I=0 NEAR THE HEAD OF TH
C  MAIN NSDTST & STDTST ROUTINES) RETURNS CONST=0 AND
C  1.  IS TO BE USED FOR MACHINE-DEPENDENT INITIALIZATIONS SUCH AS THE
C      SUPPRESSION OF UNDERFLOW MESSAGES.
C
C****** VALUES FOR IBM3033 MODEL N12 ******
CIBM      DATA C/2.25E-16,1E-50,6.0,0.5/
C****** VALUES FOR DEC10 MODEL KL10 ******
CDEC      DATA C /2.17E-19,1E-38,5.0,0.5/
      DATA                C/4*0.0/, MCNAME/
     *                    '..PUT NAME OF COMPUTER HERE..'/
C     .. Executable Statements ..
C
      IF (I.GE.1 .AND. I.LE.4) THEN
         CONST = C(I)
      ELSE IF (I.LT.0) THEN
         CONST = ICHAR(MCNAME(-I:-I))
      ELSE
C     SUPPRESS UNDERFLOW REPORTING (DEC):
CDEC      CALL ERRSET(0,6)
C     SUPPRESS UNDERFLOW REPORTING (IBM):
CIBM      CALL ERRSET(208,256,-1,0,0,208)
C
         CONST = 0
      END IF
      RETURN
      END
C
C********+*********+*********+*********+*********+*********+*********+**
C
      REAL FUNCTION CLOCK(S)
C     .. Scalar Arguments ..
      REAL                S
C     .. Executable Statements ..
C
C********+*********+*********+*********+*********+*********+*********+**
C  CLOCK IS 'RESET' TO 0 BY A CALL
C            S = CLOCK(0.0)
C  AND THEN (WITH S SET AS ABOVE) DELIVERS THE ELAPSED CPU SECONDS
C  SINCE LAST RESET, BY CALLS OF FORM
C            TIME = CLOCK(S)
C
C  THIS WORKS ON AN IBM:
CIBM      CLOCK = UTTIMR(1) - S
C  THIS WORKS ON A DEC10 UNDER TOPS10 IN CONJUNCTION WITH THE
C  COMMAND "SET TIME LLL" AT MONITOR LEVEL WHERE LLL IS A
C  SUITABLE TIME LIMIT.
CDEC      CLOCK = -TIM2GO(S) -S
C  WHEN FIRST MOUNTING THE PACKAGE, LET IT RETURN ZERO AS BELOW:
      CLOCK = 0.0
      RETURN
      END
      REAL FUNCTION CONST(I)
C
C********+*********+*********+*********+*********+*********+*********+**
C     .. Scalar Arguments ..
      INTEGER             I
C     .. Local Scalars ..
      CHARACTER*32        MCNAME
C     .. Local Arrays ..
      REAL                C(4)
C     .. Intrinsic Functions ..
      INTRINSIC           ICHAR
C     .. Data statements ..
C
C  CONST AND CLOCK ENCLOSE (WE HOPE) ALL THE MACHINE-DEPENDENT PARTS
C  OF THE STIFF AND NONSTIFF DETEST PACKAGES, EXCEPT THE TIMING
C  DATA IN THE IVALU ROUTINE OF EACH PACKAGE.
C
C  CALLS WITH VALUES I=1 TO 4 RETURN THE FOLLOWING VALUES IN 'CONST':
C     I=1 UNIT ROUNDOFF APPROXIMATELY, IN THE PRECISION USED BY THE
C         ODE-SOLVING PART OF THE PACKAGE.
C     I=2 NUMBER NEAR UNDERFLOW THRESHOLD
C     I=3 STANDARD OUTPUT UNIT NUMBER
C     I=4 VALUE OF TSTTIM (USED IN CNTROL)
C
C  CALLS WITH VALUES -1 TO -32 RETURN THE 'ICHAR' VALUE OF SUCCESSIVE
C  CHARACTERS OF THE NAME OF THE COMPUTER WE ARE RUNNING ON. (CLUMSY BUT
C  INTENDED TO ISOLATE MACHINE-DEPENDENCIES HERE)
C
C  A CALL WITH I OUTSIDE THESE RANGES (DONE WITH I=0 NEAR THE HEAD OF TH
C  MAIN NSDTST & STDTST ROUTINES) RETURNS CONST=0 AND
C  1.  IS TO BE USED FOR MACHINE-DEPENDENT INITIALIZATIONS SUCH AS THE
C      SUPPRESSION OF UNDERFLOW MESSAGES.
C
C****** VALUES FOR IBM3033 MODEL N12 ******
CIBM      DATA C/2.25E-16,1E-50,6.0,0.5/
C****** VALUES FOR DEC10 MODEL KL10 ******
CDEC      DATA C /2.17E-19,1E-38,5.0,0.5/
      DATA                C/4*0.0/, MCNAME/
     *                    '..PUT NAME OF COMPUTER HERE..'/
C     .. Executable Statements ..
C
      IF (I.GE.1 .AND. I.LE.4) THEN
         CONST = C(I)
      ELSE IF (I.LT.0) THEN
         CONST = ICHAR(MCNAME(-I:-I))
      ELSE
C     SUPPRESS UNDERFLOW REPORTING (DEC):
CDEC      CALL ERRSET(0,6)
C     SUPPRESS UNDERFLOW REPORTING (IBM):
CIBM      CALL ERRSET(208,256,-1,0,0,208)
C
         CONST = 0
      END IF
      RETURN
      END
C
C********+*********+*********+*********+*********+*********+*********+**
C
      REAL FUNCTION CLOCK(S)
C     .. Scalar Arguments ..
      REAL                S
C     .. Executable Statements ..
C
C********+*********+*********+*********+*********+*********+*********+**
C  CLOCK IS 'RESET' TO 0 BY A CALL
C            S = CLOCK(0.0)
C  AND THEN (WITH S SET AS ABOVE) DELIVERS THE ELAPSED CPU SECONDS
C  SINCE LAST RESET, BY CALLS OF FORM
C            TIME = CLOCK(S)
C
C  THIS WORKS ON AN IBM:
CIBM      CLOCK = UTTIMR(1) - S
C  THIS WORKS ON A DEC10 UNDER TOPS10 IN CONJUNCTION WITH THE
C  COMMAND "SET TIME LLL" AT MONITOR LEVEL WHERE LLL IS A
C  SUITABLE TIME LIMIT.
CDEC      CLOCK = -TIM2GO(S) -S
C  WHEN FIRST MOUNTING THE PACKAGE, LET IT RETURN ZERO AS BELOW:
      CLOCK = 0.0
      RETURN
      END
*
*
*
Nonstiff DETEST 1986 version
----- ------ ---- -------
          by  W H Enright,                 and J D Pryce,
              Dept of Computer Science,        School of Mathematics
              University of Toronto,           University Walk
              Toronto M5S 1A4                  Bristol BS8 1TW
              Canada                           England
              Tel (416) 978-6025               Tel (272) 303335
*
          Please inform the authors of any errors in code or
          documentation.
*
1. General Notes
   ------- -----
*
Nonstiff DETEST is a package to test the performance of  initial-value
codes  for nonstiff differential  systems.  This code is a revision of
the 1971 version, used to produce the results reported on in [2,4].
*
A set of test problems,  described  in detail in [2], is  incorporated
in  the package.  The code being tested is run on a selection of these
problems  at  various tolerances.  The user  selects  the problems and
the  tolerances,  and  also  organizes  the  problems into groups  for
statistical reporting purposes, at his discretion.
*
To test a code a user must write an interface routine  called  METHOD,
described  below, and then call NSDTST with the desired options.  Note
that  NSDTST  comes in a 'single' and a 'double' precision version for
use according as the  software  under  test  is  written  in single or
double  precision.   The  arguments of NSDTST are single precision but
METHOD must be implemented in the appropriate precision.
*
The package divides naturally into four parts:
*
NSDTST,CNTROL and various service routines
        organize  the  assembling,  computation   and   reporting   of
        statistics.
*
STATS
        is the routine which 'instruments' the code being  tested  and
        passes statistics via COMMON to CNTROL and NSDTST.
*
FCN, IVALU, EVALU
        describe  the  set of test problems.   FCN  gives  the  r.h.s.
        f(x,y) of the ODE system. IVALU  gives the initial conditions,
        scaling weights  and  other  data  about  each  problem. EVALU
        gives  accurately  computed values at the endpoint.
*
TRUE and its subordinate routines
        (alias   the Hull-Enright-Jackson code DVERK based on Verner's
        Runge-Kutta formulas)  form  a  reliable  nonstiff solver  for
        computing the 'true' global and local solutions when required.
*
There is also a 'dummy' NSDTST and STATS to help the  user  debug  his
METHOD routine (described below);  a  utility NSGTIM which can be used
on each new machine to generate timing data embedded in the code;  and
a utility NSGWT can be used if ever a user  wishes to add further test
problems to the set.
*
Main Lines of Calling Hierarchy (user-supplied routines are in boxes)
*
*
*
+--------+
| User's |---NSDTST---CNTROL-----IVALU
|Program |                  |               +--------+
+--------+                  |   +------+    |'SOLVER'|
                            |---|METHOD|----|(Code   |->-+
                            |   +------+    | being  |   |
                            |          |    | tested)|   |
                            |          |    +--------+   |---FCN
                            |          |                 |
                            |          STATS---TRUE--->--+
                            |
                            +----EVALU
*
We acknowledge valuable recommendations in Shampine's paper  [5].   In
particular  the  package  will,  by  default, integrate each system in
scaled form, scaling each solution component by its  maximum  observed
value  over the range of integration.  That is, the change of variable
     -1
z = D  y is done where
                       D = diag(w(1), .., w(n))
*
and w(i) =max |i-th component of  y|  over  the  range.   The  problem
                       -1
solved  is  then z' = D  f(x,Dz).  The  weights  w(i) were found by an
accurate  integration  of  each  problem and  are  embedded  in IVALU.
Note   that   this  scaling  affects  the  norms  which  are  used  in
measuring all errors, and thus can have a considerable effect  on  the
accuracy in some of the problems.
*
If the problem code in IDLIST (see below) is given a negative sign the
system  is  solved  in  its 'natural' scaling, as was done in the 1975
version of DETEST.
*
*
References
-----------
*
[1]  W  H  Enright,   'Using  a  testing  package  for  the   automatic
      assessment   of  numerical  methods  for  ODEs',  in  Performance
      Evaluation of Numerical  Software,  (Fosdick,  ed),  IFIP,  North
     Holland Publ Co (1979) 199-213.
*
[2]  T E Hull, W H Enright, B M Fellen and A  E  Sedgwick,  'Comparing
     numerical  methods  for ordinary differential equations', SIAM J.
     Numer.  Anal.  9(1972)603-637.
*
[3]  W H Enright and J D Pryce, 'A  pair  of  packages  for  assessing
     initial  value  methods',  University of Toronto Technical Report
     no.  167/83.
*
[4]  W H Enright and T E Hull, 'Test results on initial value  methods
     for  nonstiff  ordinary  differential equations', SIAM J.  Numer.
     Anal.  13(1976)944-961.
*
[5]  L F Shampine 'Evaluation of a test set for  stiff  ODE  solvers',
     TOMS 7(1981)409-420.
*
*
*
*
*
*
*
*
2. Arguments to NSDTST:
   --------- -- -------
*
TITLE   (input) Character of length 80,  holds  name  of  method being
        tested.
*
OPTION  (input)  Integer  array of length 10, only elements 1 to 3 are
        used and are referred to henceforth as OPT, NORMEF and NRMTYP.
        (OPTION(4) is also used when OPT=4)
*
OPT     one of 1, 2, 3 or 4. OPT selects level  of analysis required:
     1  gives a report of the following at each tolerance used:
      - Total time per integration
      - Overhead time excluding function calls.
      - Number of function calls and successful steps over range.
      - Global error at endpoint XEND, divided by TOL, ie.
                  ||(computed y) - (true y)||/TOL  at x=XEND
        The norm used throughout the package is that chosen by NRMTYP.
*
    2   reports (in addition to the above statistics):
      - Maximum global error  over  range.  The 'true'  solution  over
        the  range  is  obtained  by  a  reliable integrator at a more
        stringent tolerance.
*
    3   reports (in addition to the above):
      - Maximum local error over range, ie.  max over  all  meshpoints
        of
               LENRM = ||(computed y) -  yloc||/ERRBND
        where yloc is the true local  solution  through  the  previous
        meshpoint,  and  ERRBND, the assumed error bound, is explained
        below.
      - Fraction of steps where LENRM exceeded 1.
      - Fraction of steps where LENRM exceeded 5.
*
    4   reports (in addition to the above):
     -  An analysis of the local error estimates used by SOLVER as the
        basis  for  its error control. At this level three assumptions
        are   made.   First,  that  at  each  step  SOLVER  forms  two
        approximations, y  and  y*,  to the local solution yloc at the
        new meshpoint, such that asymptotically as TOL->0, y* is 'more
        accurate'  than  y.  Second, that the approximation  which  is
        taken as the computed  solution at the new meshpoint is either
        always y* (in which case one says local extrapolation is used)
        or always y (in which case it is not used). The vector
                       LE = y - yloc
        is the true local error  in  the  'less  accurate' solution y,
        and
                       ERREST = y - y*
        is  an estimate of LE. It is assumed finally  that  the  error
        control  consists  in  keeping  ||ERREST||,  in an appropriate
        norm, below ERRBND at each step.
*
        Note  that  some  methods,  such as Merson's method, cannot be
        regarded in this way.
*
        At   this   level   DETEST   analyses  how  accurately  ERREST
        approximates to LE, by forming a scatter plot of the values of
        r1  =  ||ERREST  -  LE||/ERRBND (vertical axis) against  r2  =
        ||ERREST||/ERRBND (horizontal)  at each  step.   Note ERREST -
        LE = -(y* - yloc) = -LE*,  say, so that LENRM defined above is
        r1 if local extrapolation is being done.  For an 'ideal' error
        control strategy, we expect the plotted points to cluster near
        (1,0) on the graph,  whether  or  not  local  extrapolation is
        used.
*
        To use this level of analysis the user must:
     a) Ensure  that  the  STATS call  in METHOD  delivers  ERREST  as
        defined above (with the correct sign!).
     b) Set OPTION(4) as follows.
        =0   Argument Y to STATS is y above (no local extrapolation).
        =1   Y is y* above (local extrapolation).
*
        For each integration, a scatter plot is produced.  Each of the
        ratios r1, r2 is put into one of 12 class-intervals
                 -7   -7     -6        2     3   3
           0<=r<2  , 2  <=r<2  , ..., 2 <=r<2 , 2 <=r<infinity
        thus   forming  12x12  pigeonholes.  Each   integration   step
        contributes  a data point (r1,r2)  which  is  entered  in  one
        pigeonhole. The  counts  of  the  number  of  entries  in each
        pigeonhole are expressed as integer percentages of  the  total
        number  of integration steps and printed out in a 12x12 array,
        zero entries being left blank,  and  positive  values  below 1
        being shown by a dot '.'.
*
        Step-lumping (see [4]) is deemed to make this analysis useless
        so  statistics are only gathered on unlumped steps. It  is  at
        present also  not  considered useful to produce summary tables
        over several problems (and would be costly in array space).
*
*
NORMEF  one  of  0   1   or   2   ,   selects   normalized  efficiency
        statistics.    These  try  to  compensate  for  the  fact that
        achieved  accuracy  may  be much higher or lower   than   that
        requested  by  TOL, and this relationship is very problem- and
        method- dependent.  For each problem, a least-squares  fit  is
        made of log10(actual error) vs log10(TOL) and used to estimate
        what the various cost statistics would be for an actual  error
        of 10**n.  This is achieved by interpolation, for those n such
        that 10**n lies within the range of accuracies  achieved  with
        the user-specified tolerances.
    0   No normalized statistics
    1   Normalized statistics are produced taking the  'actual  error'
        used in the least squares fit to be the endpoint global error.
    2   Normalized statistics are produced taking  'actual  error'  as
        the  maximum  global error over the range.  N.B.  In this case
        OPT must be at least 2.
*
NRMTYP  one of 1, 2  or 3, selects the norm used in assessing the size
        of local and global errors. It should be chosen by the user to
        agree with the norm used in SOLVER. We offer:
    1   Max-norm.
    2   2-norm (Euclidean norm).
    3   r.m.s. norm, that is (2-norm of x)/sqrt(n) for an n-vector x.
*
TOL     (input) Real array, holds list of up to 10  tolerances  to  be
        used,  in  strictly  decreasing  order,  with 0 as terminator.
        Each Problem is integrated at each tolerance in turn.
        Example:  in calling program
                  REAL TOL(11)
                  DATA TOL/1E-1,1E-3,1E-5,1E-7,7*0E0/
        requests the four tolerances .1, .001, .00001, .0000001.
*
IDLIST  (input) Integer array, holds list of groups of  problems,  and
        specifies  for  each  one  whether  it  is to be integrated in
        scaled or unscaled  form  (see  General  Notes  above).   Each
        problem  is specified by a numeric code, 11 to 14 for problems
        A1 to A4, 21 to 25 for B1 to B5  etc.   A  zero  terminates  a
        group and two zeros terminate the list of groups.
        If the problem code is given a negative sign,  the  system  is
        integrated  in  unscaled  form;  if a positive sign, in scaled
        form.
        Example:  in calling program
                  INTEGER IDLIST(7)
                  DATA IDLIST/11,22,0,-31,-51,0,0/
        specifies Group 1 consisting of Problems A1,B2 and Group 2  of
        Problems  C1,E1.  The first two are to be solved in the scaled
        form and the last two  in  unscaled  form.
*
        The total length of the list including zeros must be  at  most
        60 items.
*
FLAG
        (output) Real.  A nonzero value indicates  that  the  call  to
        NSDTST  was  aborted because of argument errors, in which case
        the values of the decimal digits of FLAG indicate the error(s)
        that have occurred, as follows:
          1:  OPT invalid.
          2:  NORMEF invalid.
          3:  NORMEF = 2 was requested with OPT = 1.
          4:  A negative  tolerance  was  supplied,  or the  list  of
              tolerances was not in decreasing order.
          5:  The list of tolerances was empty or not terminated by a
              zero.
          6:  An invalid Problem-Id was found in IDLIST.
          7:  The list  of  groups  in  IDLIST  is  empty  or  is not
              terminated  by  two  zeros or has more than the maximum
              allowed number (6) of groups.
          8:  NRMTYP invalid.
        Eg.  a value FLAG = 0.245E 03 indicates that errors 2, 4 and 5
        in  the  above  list  have  occurred.  Its value if nonzero is
        printed by NSDTST anyway, but FLAG is meant to be inspected if
        further  action  of  the  main program depends on a successful
        call to NSDTST.
*
*
3. Interface routine METHOD
   --------- ------- ------
*
This invokes the code being tested, call it SOLVER.  The specification
is
        SUBROUTINE METHOD(N,X,Y,XEND,TOL,HMAX,HSTART)
        INTEGER N
        DOUBLE PRECISION X,Y(N),XEND,TOL,HMAX,HSTART
        EXTERNAL FCN
*
METHOD is to be written by the user as a simple integrator to  advance
the  solution of N differential equations from the initial values held
in X,Y up to XEND, with an unweighted absolute error control  of  TOL.
HMAX  is  a  recommended  maximum stepsize and HSTART is a recommended
initial stepsize.  If SOLVER can make use of these two parameters, the
statistics will probably be more favorable and reliable, but their use
is not crucial.
*
The derivatives of the problem are  computed  by  package routine FCN.
Thus FCN will be an argument to  SOLVER, and must be declared EXTERNAL
in METHOD.
*
METHOD should call SOLVER in one-step mode  so  that  a  call  to  the
package  routine  STATS  can  be  made after each successful step.  If
SOLVER does not have this facility, SOLVER must have a call  to  STATS
inserted at the appropriate point in the code.
*
Some  calls  to  METHOD  are  intended  to  be  aborted  after  a  few
integration  steps  by  the  STATS call setting X = XEND.  Thus a test
should be made after each call to STATS, of the form
        if STATS has set X = XEND then EXIT.
*
NB:  If the actual X  argument  to  STATS  is  different  from  the  X
argument  of METHOD (which may be necessary with some SOLVERs), ensure
that the X argument of METHOD is set to XEND  before  exit,  else  the
package will report 'METHOD failed to start'.
*
The algorithm for METHOD should thus be of the form:
- Declare all arguments and workspace expected by SOLVER
- Set appropriate options  including  absolute  error  control  and
   one-step mode
- Initialize extra arguments if required
- FOR each successful step DO
   - Call SOLVER( ...  ,FCN, ...  )
     EXIT if SOLVER is in trouble.
   - Set X,Y to the just computed meshpoint x and solution vector y
   - Set ERRBND to the bound that is  satisfied  by ||ERREST||, and
     hence is intended to be satisfied by ||LE||, at this step.
   - Set ERREST  to the  local error estimate  vector y-y*  defined
     above
*
     (See   [3]   for   discussion  and  note  that X,Y are ignored
     unless  OPT.GE.2,  ERRBND   is  ignored  unless  OPT.GE.3, and
     ERREST is ignored unless OPT.GE.4.)
*
   - Call STATS(X,Y,ERRBND,ERREST)
   - EXIT if X .ge.  XEND.
- ENDLOOP
*
*
On normal exit X,Y must hold XEND and the solution at XEND.   On  exit
because  SOLVER  was  in trouble, X must hold the final point reached.
On an exit forced by STATS, X must hold XEND.
*
*
*
*
*
*
4. Controlling the destination of output
   ----------- --- ----------- -- ------
*
The unit number on which the package writes its output  is  set  by  a
call  to one of the package routines, and you can find out what it is,
by putting the statement
*
      IOUT = CONST(3)
*
in your main program.  Probably output will default to your  terminal,
which  is  good  for debugging.  For more serious work you may want to
send output to a file.  The statements
*
      IOUT = CONST(3)
      OPEN(IOUT, FILE=filename, other options..  )
*
will do this for you, assuming your  Fortran   I/O  is consistent with
the  1977 standard.
*
*
*
5. The routine FCN
   --- ------- ---
*
The specification of FCN is
        SUBROUTINE FCN(X,Y,YP)
        DOUBLE PRECISION X,Y(51),YP(51)
*
On entry X holds the independent variable and Y holds  the  vector  of
dependent  variables.   On exit YP holds the vector of derivatives for
the problem being solved (selected by a switch in COMMON).
*
*
6. The Dummy NSDTST for Debugging
   --- ----- ------ --- ---------
*
To the user:
*
This will probably be implemented  at  your  site  as  a  source  file
containing  cut-down  versions  of NSDTST and STATS (and other package
routines of no concern to the  user).   This  file  makes  a  complete
program when combined with the NSPROB file and the user's Main Program
and METHOD (and of course SOLVER).  The  cut-down  routines  have  the
same calling sequence as the proper ones.
*
The resulting program uses METHOD to solve the first problem specified
in IDLIST, at the first tolerance specified in TOL.  It will print out
the values of the arguments passed by METHOD to STATS and also the  LU
Decomp  counter  NLUD,  for  5 steps, and then set X = XEND.  The user
should check that the values of X, Y, ERREST, ERRBND look right;  that
X = XEND  forces  termination  as  it  should;  and that NLUD is being
counted up correctly.
*
Feel free to modify these routines to work interactively.
*
To the person implementing the package:
*
Please modify these routines to match the user environment.
*
*
*
7. Implementation Notes
   -------------- -----
*
 7.1.  Machine-dependent constants
*
    These  are   isolated  in  the  routine   CONST   which   has  the
    specification   REAL  FUNCTION CONST(I).  You must set the array C
    and the string MCNAME in the DATA statement:
*
    C(1)   Approximately  the  double  precision  unit  roundoff, used
           in STATS and TRUE.
    C(2)   A number near the underflow threshold, used in TRUE.
    C(3)   The  standard  output  unit number IOUT, used in NSDTST and
           TRUE.   We suggest output be to the terminal by default.
    C(4)   TSTTIM, used in CNTROL (see Clock Routine).
    MCNAME Titling  information  for printout, giving the  name of the
           computer and operating system.
*
    In addition, a call of CONST(0) (executed near the top of  NSDTST)
    is  intended  to  invoke  calls  to  system  routines  to suppress
    underflow  reporting  (which  may  spoil  the  appearance  of  the
    output), etc.
*
    It may be convenient  to  allow  IOUT  (C(3)  above)  to be set by
    interaction with the user at this point.
*
 7.2.  Clock Routine
*
    If   it  is  decided  to  implement  the  timing  facilities,  the
    implementer  should  provide  a  timing routine  which  calls  the
    system clock and has the specification
         REAL FUNCTION CLOCK(S)
         REAL(S)
    It should be such that it is 'reset to zero' by the statement
         S = CLOCK(0.0)
    and (as long as S is left alone) can then be 'read'  as  often  as
    desired by statements like
         TIME = CLOCK(S)
    which sets TIME to the number of seconds of processor  time  since
    CLOCK was 'reset'.
*
    The larger is  the  value  of  TSTTIM  (ie.   CONST(4))  the  more
    accurate,  and expensive, is the timing process.  It should be set
    to a value reflecting the speed of the hardware and the resolution
    of  the  system clock.  We cannot give much guidance here, and our
    experience is that timings inevitably vary significantly from  run
    to run on a time-shared computing system.
*
    If timing is left unimplemented, give  TSTTIM  the  value zero and
    leave the timing data in IVALU as all zero  to cause all values of
    timing statistics to be printed out as zero.
*
 7.3.  The Timing Data in IVALU
*
    Routine IVALU contains values of the  quantity  FCNTIM  for   each
    problem:  these are the cost of one call to  FCN  as  measured  by
    CLOCK, and are used in computing the "overhead"   statistics. They
    should be  recomputed  for  another  machine.  The utility program
    NSGTIM  provided  with  the package, when supplied  with  a  CLOCK
    routine, can either produce  a complete revised IVALU file, or for
    selected problems will produce blocks of output of the form
*
    C PROBLEM xx
          FCNTIM = ...
*
    suitable for inclusion in the text of IVALU.
*
*
 7.4.  Adding extra problems
*
    Say you wish to add three extra problems to class B  of  the  set.
    They  will  then  be  called  B6,  B7  and B8 (for the sake of the
    checking routine PARCHK they  must  follow  consecutively  on  the
    existing  problem-ids).   Their numeric codes which you specify in
    the IDLIST argument of NSDTST will then be 26, 27, 27.   You  need
    to be aware that the internal code, put in variable ID and used in
    FCN, IVALU and EVALU to select the correct section  of  subroutine
    to execute, is 10 less than this, ie.  16, 17 or 17.
*
    The  steps  involved  are:
    a)  Code the  definition  of   the   differential   equations   at
        the appropriate place in FCN.  Change the computed GOTO at the
        head  of  FCN so that the value ID = 16, 17 or 18 gives a jump
        to  the correct place.
    b)  Code the  initial  values,  "true"  final   values  and  other
        data into  the  appropriate  places  in IVALU  and  EVALU in a
        similar  way.   The  true  final  values  should  probably  be
        computed   by   an  integrator   using   higher   than  double
        precision, but the only consequence of slight  inaccuracies is
        to  affect  the  END  PT   GLB ERR  statistic   at   stringent
        tolerances.  At this stage ignore the  weights  W(i)  and  the
        timing data FCNTIM.
    c)  In the argument-checking  routine   PARCHK  change  the   DATA
        statement  which defines array NSYSTM,  to indicate that class
        B now has 8 members.  (Ie.   change its second element from  5
        to 7.)
    d)  Run  the utility  program  NSGWT.F on the tape to compute  the
        values  of  the  weights  W(i).   Similarly  run  NSGTIM.F  to
        determine FCNTIM for your problems.
*
Adding  an  entire  new  problem class is  no  more  difficult.   Note
that  it  involves  increasing  the   value   of   NCLASS  in the DATA
statement and the length of NSYSTM in the  dimensioning   statement in
PARCHK; also check the string IDCLAS  in  NSDTST has enough letters in
it.
*
 7.5.  Other statistics to print
*
Statistics  which are gathered but do  not  appear   in   the   output
tables  include   NSTART,  NSTL  and  TRUTIM.  They are defined in the
description   of   COMMON  /NSCOM3/  below.   NSTART   assesses    the
efficiency  of  the  starting  phase  of  a code and may be of general
interest.  TRUTIM is of use  if  you  are  troubled  by  the overheads
of calls to TRUE with OPT  >=  2,  and  have a possibly more efficient
code   to   put   in   its  place.   NSTL  is relevant  if   you   are
interested  in  the algorithms used  by  the package, specifically the
step-lumping  process  which   takes   place  in  STATS  at  stringent
tolerances.
*
*
*
*
8. Subroutines in the Package
   ----------- -- --- -------
*
In order of appearance in the files.  The list also  shows,  for  each
routine, the other package routines and COMMON areas which it uses.  A
name in parentheses, like (FCN) denotes a routine which is  called  at
one  remove (eg.  METHOD calls SOLVER which must call FCN) or which is
passed as an argument rather than being  an  external  reference  (eg.
FCN in TRUE).
*
In CONCLK file
   CONST  calls:  none
   CLOCK  calls:  none
*
In NSDTST file
   NSDTST calls:  PARCHK LSQFIT RATIO  EFSTAT CNTROL CONST  ;   NSCOM1
                  NSCOM3
   PARCHK calls:  none
   LSQFIT calls:  none
   RATIO  calls:  none
   EFSTAT calls:  none
   CNTROL calls:  DIFNRM STATS  CONST  CLOCK IVALU EVALU METHOD PLOT ;
                  NSCOM1 NSCOM2 NSCOM3 NSCOM5 NSCOM6
   DIFNRM calls:  none
   STATS  calls:  DIFNRM CONST TRUE  FCN PLOT ;  NSCOM1 NSCOM2 NSCOM3
                  NSCOM4 NSCOM6
   PLOT   calls:  none
*
In NSTRUE file
   TRUE   calls:  CONST  (FCN2   )
   FCN2   calls:  FCN
*
In NSPROB file
   IVALU  calls:  none
   EVALU  calls:  none
   FCN    calls:  ;  NSCOM5 NSCOM6
*
User-supplied
   METHOD calls:  STATS  (FCN    )
*
*
9. Definition of Common Areas and Dictionary of Data-flow
    ---------- -- ------ ----- --- ---------- -- ---------
*
The flow of information between those routines  which  use  COMMON  is
indicated for each variable by the codes
   S: the variable is assigned a value (Set) in this routine, possibly
      by  a call to another routine to which the variable is passed as
      an argument.
   A: the value is used (Accessed) in this routine.
*
For counters and similar variables, these codes are  used  instead  of
code S:
   I: the variable is Initialized in this routine.
   U: the variable is Updated in this routine.
*
*
COMMON /NSCOM1/ passes information from NSDTST to CNTROL and STATS.
*
NSDTST
| CNTROL
| | STATS
| | | DIFNRM
| | | |
S A A -  ERRTOL  DOUBLE.  Copy of current error tolerance.
S A A -  OPT     INTEGER.  Copy of OPTION(1) argument of NSDTST.
S - - A  NRMTYP  INTEGER.  Copy of OPTION(3) argument of NSDTST.
S - A -  XTRAP   INTEGER.  Copy of OPTION(4) argument of NSDTST.
S A - -  ID      INTEGER.  Internal code of current problem, 1  for  A1,
                 ..., 13 for B3, etc.
S A - -  IWT     INTEGER.   Flag  for   scaling   (+1:    Scaled.    -1:
                 Unscaled)
S - - -  IOUT    INTEGER.  Standard output unit number.
*
*
*
*
COMMON /NSCOM2/ communicates between CNTROL and STATS.
*
  CNTROL
  | STATS
  | |
  S A  XEND    DOUBLE.  End of integration range of current problem.
  A S  HSTART  DOUBLE.   Initial  stepsize  passed   to   METHOD   for
               integration proper.
  S A  N       INTEGER.  No.  of equations in current problem.
  S A  IFLAG   INTEGER.  Set by CNTROL to inform STATS what it  is  to
               do:
           =0  METHOD is being timed.
           =1  Initializing call  of  STATS  from  CNTROL  to  set  up
               NSCOM4.
           =2  Preliminary integration to  determine  HSTART,  aborted
              after 2 steps.
          =3  Integration proper, compiling statistics.
*
*
 A SA  INDL,INDG
               Error flags for the local and global  'true  solutions'
               obtained by calls to routine TRUE.
*
*
*
*
*
COMMON /NSCOM3/ outputs statistics from CNTROL and STATS.
*
NSDTST
| CNTROL
| | STATS
| | |
A S -  XFIN    DOUBLE.  Point of failure of METHOD if it doesn't reach
               XEND.
A - S  XTRUE   DOUBLE.  Point of failure of  TRUE  if  any.   If  both
               local  and  global  fail,  point  of  global failure is
               returned.
A S -  TIME    REAL.  CPU time for  one  integration  as  measured  by
               CLOCK function.
A S -  OVHD    REAL.  Equals TIME less estimated cost of FCN calls.
A I U  TRUTIM  REAL.  The time spent in calls to TRUE.   Not  relevant
               to  performance  of  METHOD  but  measures the overhead
               incurred by the  testing package when  OPT = 2, 3 or 4.
               Not printed but available.
A S -  GEND    REAL.  Norm of global error of METHOD at XEND.
*
*
A I U  GEMX    REAL.  Maximum of global error  over  all  lumped  step
               meshpoints, ie.  usually over all meshpoints of METHOD,
               except when ERRTOL is very small.
A I U  LEMXSC  REAL.  Maximum local error in units of ERRBND, over all
               lumped step meshpoints.
A S -  NFCN    INTEGER.  Copy of NFCN1, see /NSCOM6/.
               /NSCOM6/
A I U  NSTP    INTEGER.  Counts (unlumped) steps taken  by  METHOD  in
               current integration.
- I U  NSTL    INTEGER.   Counts  lumped  steps  formed   in   current
               integration (see STATS).  Not printed but available.
A I U  NDCV,NBAD
               INTEGER.  Count lumped steps on  which  SOLVER's  local
               error control was deceived, resp.  badly deceived.
A I U  NTRU    INTEGER.  Counts  lumped  steps  on  which  true  local
               solution  was  successfully computed, hence valid local
               error statistics obtained.  Used in computing 'fraction
               deceived'  information.   Reported  if  different  from
               NSTP.  Note NTRU <= NSTL <= NSTP.
- S -  NSTART  INTEGER.  No.  of FCN calls needed by METHOD to  start,
               ie.   to  do  preliminary  integration  (2 steps).  Not
               printed out but available.
*
*
COMMON /NSCOM4/ is used only by STATS, to  preserve  information  from
one call of STATS to another.  All variables are set and/or updated in
STATS.
*
       XOLD1   DOUBLE.   Similar  to  XOLD  but  used  in  preliminary
               integration.
       XOLD,YOLD
               DOUBLE and DOUBLE array.   Copy  of  METHOD's  computed
               solution  at  end  of  previous  lumped  step.  Used as
               actual arguments of TRUE local solution call.
       XOLDG,YOLDG
               DOUBLE and DOUBLE array.  Hold 'true'  global  solution
               updated to end of previous lumped step.  Used as actual
               arguments of TRUE global solution call.
       CG,PDG,WKG,WG,YPG,INFG
               Workspace for 'true' global solution.
       XT      DOUBLE.  Holds last METHOD meshpoint between  calls  to
               STATS.
       PRECIS  DOUBLE.  Holds 1000 * (unit roundoff) approx.
       ERLUMP  DOUBLE.  Accumulates METHOD's local error estimates  to
               form an estimate over a lumped step.
*
*
COMMON /NSCOM5/  passes information  between CNTROL  and FCN,  (or any
replacement a user may provide for FCN).
*
CNTROL
| FCN
| |
*
S A    WT      DOUBLE.   Array  of  weights  used  to  implement   the
               'scaled' integration option.
S A    IWT1,N1,ID1
               INTEGER.  Copies of IWT,N,ID in /NSCOM1/  or  /NSCOM2/.
*
*
COMMON  /NSCOM6/  holds  a  counter.  It  is  initialized  in  CNTROL,
saved-and-restored  in  STATS,  and eventually copied by CNTROL to the
corresponding variable in /NSCOM3/.
*
CNTROL
|   STATS
|   |   FCN
|   |   |
*
IA  AS  U - -  NFCN1  INTEGER.  Counts calls to FCN.
*
*
There is also a COMMON/NSCOM7/ used by the dummy (debugging)  versions
of NSDTST and STATS for communication.
*
