subroutine aptpfab (idiga, ndiga, nfactm, idigb, idigc,
     &                    nfact, idigd, nerr)

ccbeg.
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c                             SUBROUTINE APTPFAB
c
c     call aptpfab (idiga, ndiga, nfactm, idigb, idigd,
c                   nfact, idigd, nerr)
c
c     Version:  aptpfab  Updated    2006 April 4, 17:30.
c               aptpfab  Originated 2006 April 4, 17:30.
c
c     Authors:  Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123.
c
c
c     Purpose:  For the big integer idiga(i), i = 1, ndiga, find any prime
c               factors idigb(n) > 1, and their exponents idigd(n), for
c               n = 1, nfact, with nfact limited to nfactm.
c               If not all prime factors of idiga are returned, because nfactm
c               is insufficient, then idigd, the remaining unfactored part of
c               idiga, is returned with a value other than 1, with nerr = 3.
c
c               The method is slow, but avoids storing a large number of prime
c               numbers.  Each successive integer, 2, 3, 5, 7, 9, ..., is
c               tested as a factor multiple times, and the result of dividing
c               idiga by each factor used to limit the search to integers no
c               larger than the square root of that result.
c
c               Flag nerr indicates any input error or limited results.
c
c     Input:    idiga, ndiga, nfactm.
c
c     Output:   idigb, idigd, nfact, idigd, nerr.
c
c     Calls: (none) 
c
c     Glossary:
c
c     idiga        Input   Any big integer, for which all prime factors and
c                            their exponents are to be found, up to a maximum of
c                            nfactm prime factors.  Size at least ndiga.
c
c     idigb        Output  Prime factor idigb(n) is the n'th smallest prime
c                            factor of idiga, with an exponent of idigc(n).
c                            If idiga = 1, then idigb(1) = idigc(1) = 0.
c                            Size at least nfactm.  Initially set to -999999999.
c
c     idigb        Input   Any trial factor.
c
c     idigc        Output  Exponent idigc(n) is the largest power of
c                            idigb(n) that divides idiga.
c                            Size at least nfactm.  Initially set to -999999999.
c
c     idigd        Output  Any remaining unfactored part of idiga, when nfact
c                            is prevented from exceeding nfactm.  Normally 1.
c
c     ndiga        Input   The number of digits in idiga.
c
c     nerr         Output  If not zero, indicates an error.
c                            1 if idiga is not 1 or more.
c                            2 if nfactm is not positive.
c                            3 if more than nfactm prime factors exist.
c
c     nfact        Output  The number of prime factors found for big integer
c                            idiga.  If more than nfactm exist, nerr = 3.
c
c     nfactm       Input   The maximum allowed number of prime factors.
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccend.

c.... Declarations for arguments.

      integer idiga(1)                ! A big integer to be factored.
      integer idigb(1)                ! A prime factor of idiga.
      integer idigc(1)                ! Power of idigb(n) dividing idiga.
      integer idigd(1)                ! Result of idiga divided by all factors.
      integer nerr                    ! Indicates an error, if not zero.
      integer nfact                   ! Number of prime factors of idiga found.
      integer nfactm                  ! The maximum allowed value of nfact.

c.... Declarations for local variables.

      integer idigb(ndiga)     ! Any big integer.
      integer idigc(ndiga)     ! Any big integer.
      integer idigd(ndiga)     ! Any big integer.
      integer idige(ndiga)     ! Any big integer.
      integer idigf(ndiga)     ! Any big integer.
      integer idigg(ndiga)     ! Any big integer.
      integer idigh(ndiga)     ! Any big integer.
      integer idigi(ndiga)     ! Any big integer.
      integer idigj(ndiga)     ! Any big integer.
      integer idigk(ndiga)     ! Any big integer.
      integer idigl(ndiga)     ! Any big integer.
      integer idigm(ndiga)     ! Any big integer.
      integer idign(ndiga)     ! Any big integer.
      integer idigo(ndiga)     ! Any big integer.
      integer idigp(ndiga)     ! Any big integer.
      integer idigq(ndiga)     ! Any big integer.
      integer idigr(ndiga)     ! Any big integer.
      integer idigs(ndiga)     ! Any big integer.
      integer idigt(ndiga)     ! Any big integer.
      integer idigu(ndiga)     ! Any big integer.
      integer idigv(ndiga)     ! Any big integer.
      integer idigw(ndiga)     ! Any big integer.
      integer idigx(ndiga)     ! Any big integer.
      integer idigy(ndiga)     ! Any big integer.
      integer idigz(ndiga)     ! Any big integer.

      integer n                    ! Index in arrays idigb, idigc.

c***DEBUG begins.
 9901 format ('' / 'aptpfab finding prime factors of big integer',
     &  ' with length',i6,' digits,' /
     &  '  But no more than',i6,' prime factors.' )
 9902 format ('big  ',11x,i6,' = ',50i1)

          write ( 3, 9901) ndiga, nfactm

          do nin = 1, ndiga, 50
            nlast = min (nin + 49, ndiga)
            write ( 3, 9902) nin, (idiga(n), n = nin, nlast)
          enddo
c***DEBUG ends.

c.... Initialize.

      nerr   = 0
      nfact  = 0
      idigd  = idiga

      if (nfactm .gt. 0) then
        do n = 1, nfactm
          idigb(n) = -999999999
          idigc(n)  = -999999999
        enddo
      endif

c.... Test for input errors.

      if (idiga .lt. 1) then
        nerr = 1
        go to 210
      endif

      if (nfactm .le. 0) then
        nerr = 2
        go to 210
      endif

      if (idiga .eq. 1) then
        nfact    = 1
        idigb(1) = 1
        idigc(1)  = 1
        go to 210
      endif

c.... Find maximum possible factor.

      idigd = sqrt (idigd)
      call aptbrtn (2, 10, idiga, ndiga, idmax, iemax,
     &              idigs, idigt, idigu, idigv,
     &              idigw, idigx, idigy, idigz,
     &              ndigm, idigd, ndigc, isign, nerr)
c***DEBUG begins.
 9700 format ('DEBUG 0.  nfact,           idigd =',i3,21x,   i18)
      write ( 3, 9700) nfact, idigd
c***DEBUG ends.

c.... Test 2.

      idigb = 2
      if (idigb .gt. idigd) then   ! 2 is too high. 
        nfact        = nfact + 1
c***DEBUG begins.
 9801 format ('DEBUG A.  nfact,           idigd =',i3,21x,   i18)
      write ( 3, 9801) nfact, idigd
c***DEBUG ends.
        idigb(nfact) = idigd
        idigc(nfact)  = 1
        idigd        = 1
        go to 210
      endif                         ! 2 is too high.

      if (mod (idigd, idigb) .eq. 0) then  ! Residual idigd is even.
        if (nfact .ge. nfactm) then
          nerr = 3
          go to 210
        endif
        nfact        = nfact + 1
c***DEBUG begins.
 9802 format ('DEBUG B.  nfact,           idigd =',i3,21x,   i18)
      write ( 3, 9802) nfact, idigd
c***DEBUG ends.
        idigb(nfact) = idigb
        idigc(nfact)  = 1
        idigd        = idigd / idigb
        if (idigd .eq. 1) go to 210
        idigd = sqrt (float (idigd))
c***DEBUG begins.
 9701 format ('DEBUG 1.  nfact,idigb,idigc =',i3,i18,'^',i2,i18)
      write ( 3, 9701) nfact, idigb(nfact), idigd(nfact), idigd
c***DEBUG ends.
  120     if (mod (idigd, idigb) .eq. 0) then
          idigc(nfact) = idigc(nfact) + 1
          idigd = idigd / idigb
          if (idigd .eq. 1) go to 210
          idigd = sqrt (float (idigd))
c***DEBUG begins.
 9702 format ('DEBUG 2.  nfact,idigb,idigd =',i3,i18,'^',i2,i18)
      write ( 3, 9702) nfact, idigb(nfact), idigc(nfact), idigc
c***DEBUG ends.
          go to 120
        endif
      endif

      if (nfact .ge. nfactm) then
        nerr = 3
        go to 210
      endif

c.... Test each higher odd integer.

      idigb = 3

  130 if (idigb .gt. idigd) then
        nfact        = nfact + 1
c***DEBUG begins.
 9803 format ('DEBUG C.  nfact,           idigd =',i3,21x,   i18)
      write ( 3, 9803) nfact, idigd
c***DEBUG ends.
        idigb(nfact) = idigd
        idigc(nfact)  = 1
        idigd        = 1
        go to 210
      endif

      if (mod (idigd, idigb) .eq. 0) then  ! Test next odd integer.

        nfact        = nfact + 1
c***DEBUG begins.
 9804 format ('DEBUG C.  nfact,           idigd =',i3,21x,   i18)
      write ( 3, 9804) nfact, idigd
c***DEBUG ends.
        idigb(nfact) = idigb
        idigc(nfact)  = 1
        idigd        = idigd / idigb
        if (idigd .eq. 1) go to 210
        idigd       = sqrt (float (idigd))
c***DEBUG begins.
 9703 format ('DEBUG 3.  nfact,idigb,idigd =',i3,i18,'^',i2,i18)
      write ( 3, 9703) nfact, idigb(nfact), idigc(nfact), idigc
c***DEBUG ends.
  140   if (mod (idigd, idigb) .eq. 0) then
          idigd(nfact) = idigd(nfact) + 1
          idigc       = idigc / idigb
          if (idigd .eq. 1) go to 210
          idigd      = sqrt (float (idigd))
c***DEBUG begins.
 9704 format ('DEBUG 4.  nfact,idigb,idigd =',i3,i18,'^',i2,i18)
      write ( 3, 9704) nfact, idigb(nfact), idigc(nfact), idigc
c***DEBUG ends.
          go to 140
        endif

      endif                           ! Tested next odd integer.

      if (nfact .ge. nfactm) then
        nerr = 3
        go to 210
      endif

      call aptbadd (10, idigb, ndigb, idigb, ndigb,
     &              ndigm, idigb, ndigb, nerr)

      go to 130
   
  210 continue
c***DEBUG begins.
 9902 format (/ 'aptpfab found',i12,' factors.  nerr =',i3,'.' )
 9903 format ('  n =',i3,'  idigb(n) =',i22,'^',i2)
 9905 format ('  Unfactored residue =',i20)
      write ( 3, 9902) nfact, nerr
      if (nfact .gt. 0) then
        write ( 3, 9903) (n, idigb(n), idigc(n), n = 1, nfact)
      endif
      if (nerr .eq. 3) then
        write ( 3, 9905) idigd
      endif
c***DEBUG ends.
      return

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

UCRL-WEB-209832