    PROGRAM g01anfe

!      G01ANF Example Program Text
!      Mark 23 Release. NAG Copyright 2011.

!      .. Use Statements ..
       USE nag_library, ONLY : g01anf, nag_wp
!      .. Implicit None Statement ..
       IMPLICIT NONE
!      .. Parameters ..
       INTEGER, PARAMETER              :: nin = 5, nout = 6
!      .. Local Scalars ..
       REAL (KIND=nag_wp)              :: eps
       INTEGER                         :: i, ifail, ind, licomm, lrcomm, n,    &
                                          nb, np, nq, nrv, onb
!      .. Local Arrays ..
       REAL (KIND=nag_wp), ALLOCATABLE :: q(:), qv(:), rcomm(:), rv(:)
       INTEGER, ALLOCATABLE            :: icomm(:)
!      .. Executable Statements ..
       WRITE (nout,*) 'G01ANF Example Program Results'
       WRITE (nout,*)

!      Skip heading in data file
       READ (nin,*)

!      Read in stream size and approximation factor
       READ (nin,*) n, eps

!      Read in number of elements in the output vector qv
       READ (nin,*) nq
       ALLOCATE (qv(nq),q(nq))

!      Read in vector q
       READ (nin,*) q(1:nq)

!      Dummy allocation for the communication arrays
       lrcomm = 1
       licomm = 2
       nb = 1
       ALLOCATE (rv(nb),rcomm(lrcomm),icomm(licomm))

!      Call NAG routine for the first time to obtain lrcomm and licomm
       ind = 0
       ifail = 0
       CALL g01anf(ind,n,rv,nb,eps,np,q,qv,nq,rcomm,lrcomm,icomm,licomm,ifail)

!      Reallocate the communication arrays to the required size
       lrcomm = icomm(1)
       licomm = icomm(2)
       DEALLOCATE (rcomm,icomm)
       ALLOCATE (rcomm(lrcomm),icomm(licomm))

!      Read in number of vectors with dataset blocks
       READ (nin,*) nrv

       onb = 0
D_LP:  DO i = 1, nrv
!         Read in number of elements in the first/next vector rv
          READ (nin,*) nb

          IF (onb/=nb) THEN
!            Reallocate RV if required
             DEALLOCATE (rv)
             ALLOCATE (rv(nb))
          END IF
          onb = nb

!         Read in vector rv
          READ (nin,*) rv(1:nb)

!         Repeat calls to NAG routine for every dataset block rv 
!         until n observations have been passed
          ifail = 1
          CALL g01anf(ind,n,rv,nb,eps,np,q,qv,nq,rcomm,lrcomm,icomm,licomm, &
             ifail)
          IF (ifail/=0) THEN
!            This routine is most likely to be used to process large datasets, 
!            certain parameter checks will only be done once all the data has 
!            been processed. Calling the routine with a hard failure (IFAIL=0)
!            would cause any processing to be lost as the program terminates.
!            It is likely that a soft failure would be more appropriate. This 
!            would allow any issues with the input parameters to be resolved 
!            without losing any processing already carried out. 

!            In this small example we are just calling the routine again with
!            a hard failure so that the error messages are displayed.
             ifail = 0
             CALL g01anf(ind,n,rv,nb,eps,np,q,qv,nq,rcomm,lrcomm,icomm,licomm, &
                ifail)
          END IF
          IF (ind==4) EXIT D_LP
       END DO D_LP

!      Call NAG routine again to calculate quantiles specified in vector q
       ind = 3
       ifail = 0
       CALL g01anf(ind,n,rv,nb,eps,np,q,qv,nq,rcomm,lrcomm,icomm,licomm,ifail)

!      Print the results
       WRITE (nout,*) 'Input data:'
       WRITE (nout,99999) n, ' observations'
       WRITE (nout,99998) 'eps = ', eps
       WRITE (nout,*)
       WRITE (nout,*) 'Quantile     Result'
       WRITE (nout,99997) (q(i),qv(i),i=1,nq)

99999  FORMAT (1X,I2,A)
99998  FORMAT (1X,A,F5.2)
99997  FORMAT (1X,F7.2,4X,F7.2)
    END PROGRAM g01anfe
