subroutine aptalin (noptx, xl, xr, pl, pr, nbins, pbin, fbin,
     &                    nalb, nerr)


ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTALIN
c
c     call aptalin (noptx, xl, xr, pl, pr, nbins, pbin, fbin,
c    &              nalb, nerr)
c
c     Version:  aptalin  Updated    1990 July 19 10:20.
c               aptalin  Originated 1990 June 28 10:00.
c
c     Author:   Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  To convert a piecewise linear tabulated probability distribution
c               function (PFD) to the form required for random sampling by the
c               aliasing method.  The PDF is defined by either of two methods:
c
c               For noptx = 0, the PDF is a histogram with nbins bins.
c               In each bin, pl(n) = pr(n), and xl and xr are not used.
c               The random variable to be sampled is the bin index n.
c
c               For noptx = 1, the PDF is a piecewise linear tabulated function
c               of p(x) vs x, with nbins x intervals, where x is the random
c               variable to be sampled.  In the n'th interval, the relative
c               probability varies linearly from pl(n) at xl(n) on the left,
c               to pr(n) at xr(n) on the right.  For a histogram PDF,
c               pl(n) = pr(n).  For a continuous PDF, pl(n+1) = pr(n) and
c               xl(n+1) = xr(n).  There may be gaps in x, but no overlaps.
c
c               After the conversion, each bin will have a probability fbin(n)
c               of its own index n, and a probability 1.0 - fbin(n) of the
c               aliased index, nalb(n), and a total relative probability pbin(n)
c               of sampling either bin n or bin nalb(n).
c
c               After aliasing, values of n and x may be randomly sampled as
c               follows:
c
c               (1)  Select a random number u1 uniformly between 0.0 and 1.0.
c               (2)  Randomly sample the initial bin index n:
c                      xn = 1 + u1 * nbins
c                      n  = xn
c               (3)  Choose either bin index n or the alias bin index, nalb(n):
c                      u2 = xn - n  (an independent random number)
c                      if (u2 .gt. fbin(n)) n = nalb(n)
c               (4)  Randomly sample a value of x in the range from xl(n) to
c                    xr(n), based on the linear probability distribution from
c                    pl(n) to pr(n) (uniform if pl(n) = pr(n)).
c
c               Flag nerr indicates any input error, if not zero.
c
c     Note:     Use subroutine aptalsb to sample bin indices from the aliased
c               bins.  Sample x values from the resulting set of bin indices
c               with aptalsh (uniform bins) or aptalsl (linear bins).
c
c     History:  1990 July 17 10:40.  Changed argument list, added option noptx.
c
c     Input:    noptx, xl, xr, pl, pr, nbins.
c
c     Output:   pbin, fbin, nalb, nerr.
c
c     Glossary:
c
c     fbin      Output   The probability of selecting bin n instead of the alias
c                          bin nalb(n).  Size nbins.
c
c     nalb      Output   The index of the aliased bin associated with bin n.
c                          Size nbins.
c
c     nbins     Input    Number of PDF bins or intervals.  Size of arrays xl,
c                          xr, pl, pr, pbin, fbin, nalb.
c
c     nerr      Output   Indicates an input error, if not 0.
c                          1 if nbins is not positive.
c                          2 if noptx is not 0 or 1.
c                          3 if any pl(n) or pr(n) is negative.
c                          4 if any xr(n) is less than xl(n).
c                          5 if any xr(n) is greater than xl(n+1).
c
c     noptx     Input    Indicates the type of PDF:
c                          0 if the bin index is the random variable, xl and xr
c                            are not used, and pl(n) = pr(n) (a histogram).
c                          1 if xl(n) and xr(n) are the values of the random
c                            variable with relative probabilities pl(n) and
c                            pr(n), respectively, in the n'th interval.
c
c     pbin      In/Out   The unnormalized relative probability of the n'th bin.
c                          Initially 0.5 * (pl(n) + pr(n)) (noptx = 0) or
c                          0.5 * (pl(n) + pr(n)) * (xr(n) - xl(n)) (noptx = 1).
c                          After aliasing, the output values of pbin will each
c                          be equal to the mean of all of the initial values.
c                          Size nbins.
c
c     pl        Input    For bin n, the unnormalized relative probability of the
c                          bin (noptx = 0) or of xl(n), per unit x interval
c                          (noptx = 1).  Size nbins.
c                          May not be negative for any n.
c                          If the PDF is a histogram, pl(n) = pr(n).
c                          If the PDF is continuous, pl(n) = pr(n-1), for
c                          n = 2, nbins.
c
c     pr        Input    For bin n, the unnormalized relative probability of the
c                          bin (noptx = 0) or of xr(n), per unit x interval
c                          (noptx = 1).  Size nbins.
c                          May not be negative for any n.
c                          If the PDF is a histogram, pr(n) = pl(n).
c                          If the PDF is continuous, pr(n) = pl(n+1), for
c                          n = 1, nbins - 1.
c
c     xl        Input    For bin n, the value of the random variable x at the
c                          left boundary of the bin (noptx = 1).
c                          For any n, xl(n) must not be greater than xr(n),
c                          and must be equal or greater than xr(n-1).
c                          If the PDF includes a continuous range of x values,
c                          in monotonically increasing order, with no gaps, then
c                          xl(n) = xr(n-1), for n = 2, nbins.
c                          Size nbins, if noptx = 1.  Otherwise, not used.
c
c     xr        Input    For bin n, the value of the random variable x at the
c                          right boundary of the bin (noptx = 1).
c                          For any n, xr(n) must not be less than xl(n),
c                          and must be equal or less than xl(n+1).
c                          If the PDF includes a continuous range of x values,
c                          in monotonically increasing order, with no gaps, then
c                          xr(n) = xl(n+1), for n = 1, nbins - 1.
c                          Size nbins, if noptx = 1.  Otherwise, not used.
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccend.

c.... Dimensioned arguments.

c---- Probability of n in aliased bin n.
      dimension fbin    (1)
c---- Aliased bin index for bin n.
      dimension nalb    (1)
c---- Relative prob of n and nalb in bin n.
      dimension pbin    (1)
c---- Left-hand probability in bin.
      dimension pl      (1)
c---- Right-hand probability in bin.
      dimension pr      (1)
c---- Left-hand value of x in bin.
      dimension xl      (1)
c---- Right-hand value of x in bin.
      dimension xr      (1)

c.... Local variables.

c---- Bin width, 1.0 or xr(n) - xl(n).
      common /laptalin/ dx
c---- Index in fbin, nalb or pbin.
      common /laptalin/ n
c---- Index of bin with max pbin value.
      common /laptalin/ nmax
c---- Index of bin with min pbin value.
      common /laptalin/ nmin
c---- Number of bins aliased.
      common /laptalin/ nn
c---- Maximum value of pbin.
      common /laptalin/ pmax
c---- Mean value of pbin.
      common /laptalin/ pmean
c---- Minimum value of pbin.
      common /laptalin/ pmin
c---- Sum of pbin values.
      common /laptalin/ psum
cbugc***DEBUG begins.
cbugc---- Number of occurrences of a bin index.
cbug      common /laptalin/ nbin
cbug 9901 format (/ 'aptalin converting a PDF for aliasing.  noptx=',i3)
cbug 9902 format (i3,'  pl,pr=',1p2e22.14)
cbug 9903 format (i3,'  xl,xr=',1p2e22.14 / '     pl,pr=',1p2e22.14)
cbug      write ( 3, 9901) noptx
cbug      if (noptx .eq. 0) then
cbug        write (3, 9902) (n, pl(n), pr(n), n = 1, nbins)
cbug      elseif (noptx .eq. 1) then
cbug        write (3, 9903) (n, xl(n), xr(n), pl(n), pr(n), n = 1, nbins)
cbug      endif
cbugc***DEBUG ends.

c.... initialize.

      nerr = 0

c.... Test for errors in scalar input.

      if (nbins .le. 0) then
        nerr = 1
        go to 210
      endif

      if ((noptx .ne. 0) .and. (noptx .ne. 1)) then
        nerr = 2
        go to 210
      endif

c.... Test for errors in input arrays, and find the relative
c....   probability of each bin, and the average for all the bins.

      psum = 0.0

c---- Loop over pbin.
      do 120 n = 1, nbins

        if (noptx .eq. 0) then
          dx = 1.0
        else
          dx = (xr(n) - xl(n))
          if (dx .lt. 0.0) then
            nerr = 4
            go to 210
          endif
          if ((n .lt. nbins) .and. (xr(n) .gt. xl(n+1))) then
            nerr = 5
            go to 210
          endif
        endif

        if ((pl(n) .lt. 0.0) .or. (pr(n) .lt. 0.0)) then
          nerr = 3
          go to 210
        endif
        pbin(n) = 0.5 * (pl(n) + pr(n)) * dx

        psum    = psum + pbin(n)

c---- End of loop over pbin.
  120 continue

      pmean = psum / nbins

c.... Initialize.

c---- Loop over bins.
      do 130 n = 1, nbins

        fbin(n) = 1.0
        nalb(n) = n

c---- End of loop over bins.
  130 continue

      if (nbins .gt. 1) then

c....   Alias the least probable bin to the most probable, until done.

c---- Loop over min and max pbin.
        do 140 nn = 1, nbins - 1

c....     Find the min and max pbin values, and their indices.

          call aminmx (pbin, 1, nbins, 1, pmin, pmax, nmin, nmax)

c++++ Alias min bin to max bin.
          if (nalb(nmin) .eq. nmin) then

            fbin(nmin) = pmin / pmean
            nalb(nmin) = nmax
            pbin(nmin) = pmean
            pbin(nmax) = pmin + pmax - pmean

          endif

c---- End of loop over min and max pbin.
  140   continue

c---- Tested nbins.
      endif
cbugc***DEBUG begins.
cbug 9904 format (/ 'aptalin results.  pmean=',1pe22.14 /
cbug     &  (i3,' nalb=',i3,' fbin=',1pe22.14, ' pbin=',1pe22.14))
cbug      write ( 3, 9904) pmean,  (n, nalb(n), fbin(n), pbin(n),
cbug     &  n = 1, nbins)
cbug
cbug 9905 format (/ '  check total probabilities.')
cbug 9906 format ('  nn=',i3,' nbin=',i3,' psum=',1pe22.14)
cbug      write ( 3, 9905)
cbug      do 160 nn = 1, nbins
cbug        nbin = 1
cbug        psum = fbin(nn) * pbin(nn)
cbug        do 150 n = 1, nbins
cbug          if (nalb(n) .eq. nn) then
cbug            psum = psum + (1.0 - fbin(n)) * pbin(n)
cbug            if (n .ne. nn) then
cbug              nbin = nbin + 1
cbug            endif
cbug          endif
cbug  150   continue
cbug        write ( 3, 9906) nn, nbin, psum
cbug  160 continue
cbugc***DEBUG ends.

  210 return

c.... End of subroutine aptalin.      (+1 line.)
      end

UCRL-WEB-209832