subroutine  miev0 ( xx, crefin, perfct, mimcut, anyang, 1
     $                    numang, xmu, nmom, ipolzn, momdim, prnt,
     $                    qext, qsca, gqsc, pmom, sforw, sback, s1,
     $                    s2, tforw, tback )
c
c    computes mie scattering and extinction efficiencies; asymmetry
c    factor;  forward- and backscatter amplitude;  scattering
c    amplitudes for incident polarization parallel and perpendicular
c    to the plane of scattering, as functions of scattering angle;
c    coefficients in the legendre polynomial expansions of either the
c    unpolarized phase function or the polarized phase matrix;
c    and some quantities needed in polarized radiative transfer.
c
c      calls :  biga, ckinmi, small1, small2, testmi, miprnt,
c               lpcoef, errmsg
c
c      i n t e r n a l   v a r i a b l e s
c      -----------------------------------
c
c  an,bn           mie coefficients  little-a-sub-n, little-b-sub-n
c                     ( ref. 1, eq. 16 )
c  anm1,bnm1       mie coefficients  little-a-sub-(n-1),
c                     little-b-sub-(n-1);  used in -gqsc- sum
c  anp             coeffs. in s+ expansion ( ref. 2, p. 1507 )
c  bnp             coeffs. in s- expansion ( ref. 2, p. 1507 )
c  anpm            coeffs. in s+ expansion ( ref. 2, p. 1507 )
c                     when  mu  is replaced by  - mu
c  bnpm            coeffs. in s- expansion ( ref. 2, p. 1507 )
c                     when  mu  is replaced by  - mu
c  calcmo(k)       true, calculate moments for k-th phase quantity
c                     (derived from -ipolzn-; used only in 'lpcoef')
c  cbiga(n)        bessel function ratio capital-a-sub-n (ref. 2, eq. 2)
c                     ( complex version )
c  cior            complex index of refraction with negative
c                     imaginary part (van de hulst convention)
c  cioriv          1 / cior
c  coeff           ( 2n + 1 ) / ( n ( n + 1 ) )
c  fn              floating point version of index in loop performing
c                     mie series summation
c  lita,litb(n)    mie coefficients -an-, -bn-, saved in arrays for
c                     use in calculating legendre moments *pmom*
c  maxtrm          max. possible no. of terms in mie series
c  mm              + 1 and  - 1,  alternately.
c  mim             magnitude of imaginary refractive index
c  mre             real part of refractive index
c  maxang          max. possible value of input variable -numang-
c  nangd2          (numang+1)/2 ( no. of angles in 0-90 deg; anyang=f )
c  noabs           true, sphere non-absorbing (determined by -mimcut-)
c  np1dn           ( n + 1 ) / n
c  npquan          highest-numbered phase quantity for which moments are
c                     to be calculated (the largest digit in -ipolzn-
c                     if  ipolzn .ne. 0)
c  ntrm            no. of terms in mie series
c  pass1           true on first entry, false thereafter; for self-test
c  pin(j)          angular function little-pi-sub-n ( ref. 2, eq. 3 )
c                     at j-th angle
c  pinm1(j)        little-pi-sub-(n-1) ( see -pin- ) at j-th angle
c  psinm1          ricatti-bessel function psi-sub-(n-1), argument -xx-
c  psin            ricatti-bessel function psi-sub-n of argument -xx-
c                     ( ref. 1, p. 11 ff. )
c  rbiga(n)        bessel function ratio capital-a-sub-n (ref. 2, eq. 2)
c                     ( real version, for when imag refrac index = 0 )
c  rioriv          1 / mre
c  rn              1 / n
c  rtmp            (real) temporary variable
c  sp(j)           s+  for j-th angle  ( ref. 2, p. 1507 )
c  sm(j)           s-  for j-th angle  ( ref. 2, p. 1507 )
c  sps(j)          s+  for (numang+1-j)-th angle ( anyang=false )
c  sms(j)          s-  for (numang+1-j)-th angle ( anyang=false )
c  taun            angular function little-tau-sub-n ( ref. 2, eq. 4 )
c                     at j-th angle
c  tcoef           n ( n+1 ) ( 2n+1 ) (for summing tforw,tback series)
c  twonp1          2n + 1
c  yesang          true if scattering amplitudes are to be calculated
c  zetnm1          ricatti-bessel function  zeta-sub-(n-1) of argument
c                     -xx-  ( ref. 2, eq. 17 )
c  zetn            ricatti-bessel function  zeta-sub-n of argument -xx-
c
c ----------------------------------------------------------------------
c --------  i / o specifications for subroutine miev0  -----------------
c ----------------------------------------------------------------------
      implicit none
      logical  anyang, perfct, prnt(*)
      integer  ipolzn, momdim, numang, nmom
      real*8     gqsc, mimcut, pmom( 0:momdim, * ), qext, qsca,
     $         xmu(*), xx
      complex*16  crefin, sforw, sback, s1(*), s2(*), tforw(*),
     $         tback(*)
      integer maxang,mxang2,maxtrm
      real*8 onethr
c ----------------------------------------------------------------------
c
      parameter ( maxang = 501, mxang2 = maxang/2 + 1 )
c
c                                  ** note --  maxtrm = 10100  is neces-
c                                  ** sary to do some of the test probs,
c                                  ** but 1100 is sufficient for most
c                                  ** conceivable applications
      parameter ( maxtrm = 1100 )
      parameter ( onethr = 1./3. )
c
      logical   anysav, calcmo(4), noabs, ok, pass1, persav, yesang
      integer   npquan
      integer i,j,n,nmosav,iposav,numsav,ntrm,nangd2
      real*8      mim, mimsav, mre, mm, np1dn
      real*8 rioriv,xmusav,xxsav,sq,fn,rn,twonp1,tcoef, coeff
      real*8 xinv,psinm1,chinm1,psin,chin,rtmp,taun
      real*8      rbiga( maxtrm ), pin( maxang ), pinm1( maxang )
      complex*16   an, bn, anm1, bnm1, anp, bnp, anpm, bnpm, cresav,
     $          cior, cioriv, ctmp, zet, zetnm1, zetn
      complex*16   cbiga( maxtrm ), lita( maxtrm ), litb( maxtrm ),
     $          sp( maxang ), sm( maxang ), sps( mxang2 ), sms( mxang2 )
      equivalence  ( cbiga, rbiga )
      save  pass1
      sq( ctmp ) = dble( ctmp )**2 + dimag( ctmp )**2
      data  pass1 / .true. /
c
c
      if ( pass1 )  then
c                                   ** save certain user input values
         xxsav  = xx
         cresav = crefin
         mimsav = mimcut
         persav = perfct
         anysav = anyang
         nmosav = nmom
         iposav = ipolzn
         numsav = numang
         xmusav = xmu( 1 )
c                              ** reset input values for test case
         xx      = 10.0
         crefin  = ( 1.5, - 0.1 )
         perfct  = .false.
         mimcut  = 0.0
         anyang  = .true.
         numang  = 1
         xmu( 1 )= - 0.7660444
         nmom    = 1
         ipolzn  = - 1
c
      end if
c                                        ** check input and calculate
c                                        ** certain variables from input
c
   10 call  ckinmi( numang, maxang, xx, perfct, crefin, momdim,
     $              nmom, ipolzn, anyang, xmu, calcmo, npquan )
c
      if ( perfct .and. xx .le. 0.1 )  then
c                                            ** use totally-reflecting
c                                            ** small-particle limit
c
         call  small1 ( xx, numang, xmu, qext, qsca, gqsc, sforw,
     $                  sback, s1, s2, tforw, tback, lita, litb )
         ntrm = 2
         go to 200
      end if
c
      if ( .not.perfct )  then
c
         cior = crefin
         if ( dimag( cior ) .gt. 0.0 )  cior = dconjg( cior )
         mre =     dble( cior )
         mim =  - dimag( cior )
         noabs = mim .le. mimcut
         cioriv = 1.0 / cior
         rioriv = 1.0 / mre
c
         if ( xx * dmax1( 1.d0, cdabs(cior) ) .le. 0.d1 ) then
c
c                                    ** use general-refractive-index
c                                    ** small-particle limit
c                                    ** ( ref. 2, p. 1508 )
c
            call  small2 ( xx, cior, .not.noabs, numang, xmu, qext,
     $                     qsca, gqsc, sforw, sback, s1, s2, tforw,
     $                     tback, lita, litb )
            ntrm = 2
            go to 200
         end if
c
      end if
c
      nangd2 = ( numang + 1 ) / 2
      yesang = numang .gt. 0
c                              ** estimate number of terms in mie series
c                              ** ( ref. 2, p. 1508 )
      if ( xx.le.8.0 )  then
         ntrm = xx + 4. * xx**onethr + 1.
      else if ( xx.lt.4200. )  then
         ntrm = xx + 4.05 * xx**onethr + 2.
      else
         ntrm = xx + 4. * xx**onethr + 2.
      end if
      if ( ntrm+1 .gt. maxtrm )
     $     call errmsg( 'miev0--parameter maxtrm too small', .true. )
c
c                            ** calculate logarithmic derivatives of
c                            ** j-bessel-fcn., big-a-sub-(1 to ntrm)
      if ( .not.perfct )
     $     call  biga( cior, xx, ntrm, noabs, yesang, rbiga, cbiga )
c
c                            ** initialize ricatti-bessel functions
c                            ** (psi,chi,zeta)-sub-(0,1) for upward
c                            ** recurrence ( ref. 1, eq. 19 )
      xinv = 1.0 / xx
      psinm1   = dsin( xx )
      chinm1   = dcos( xx )
      psin = psinm1 * xinv - chinm1
      chin = chinm1 * xinv + psinm1
      zetnm1 = dcmplx( psinm1, chinm1 )
      zetn   = dcmplx( psin, chin )
c                                     ** initialize previous coeffi-
c                                     ** cients for -gqsc- series
      anm1 = ( 0.0, 0.0 )
      bnm1 = ( 0.0, 0.0 )
c                             ** initialize angular function little-pi
c                             ** and sums for s+, s- ( ref. 2, p. 1507 )
      if ( anyang )  then
         do  60  j = 1, numang
            pinm1( j ) = 0.0
            pin( j )   = 1.0
            sp ( j ) = ( 0.0, 0.0 )
            sm ( j ) = ( 0.0, 0.0 )
   60    continue
      else
         do  70  j = 1, nangd2
            pinm1( j ) = 0.0
            pin( j )   = 1.0
            sp ( j ) = ( 0.0, 0.0 )
            sm ( j ) = ( 0.0, 0.0 )
            sps( j ) = ( 0.0, 0.0 )
            sms( j ) = ( 0.0, 0.0 )
   70    continue
      end if
c                         ** initialize mie sums for efficiencies, etc.
      qsca = 0.0
      gqsc = 0.0
      sforw      = ( 0., 0. )
      sback      = ( 0., 0. )
      tforw( 1 ) = ( 0., 0. )
      tback( 1 ) = ( 0., 0. )
c
c
c ---------  loop to sum mie series  -----------------------------------
c
      mm = + 1.0
      do  100  n = 1, ntrm
c                           ** compute various numerical coefficients
         fn     = n
         rn     = 1.0 / fn
         np1dn  = 1.0 + rn
         twonp1 = 2 * n + 1
         coeff  = twonp1 / ( fn * ( n + 1 ) )
         tcoef  = twonp1 * ( fn * ( n + 1 ) )
c
c                              ** calculate mie series coefficients
         if ( perfct )  then
c                                   ** totally-reflecting case
c
            an = ( ( fn*xinv ) * psin - psinm1 ) /
     $           ( ( fn*xinv ) * zetn - zetnm1 )
            bn = psin / zetn
c
         else if ( noabs )  then
c                                      ** no-absorption case
c
            an =  ( ( rioriv*rbiga(n) + ( fn*xinv ) ) * psin - psinm1 )
     $          / ( ( rioriv*rbiga(n) + ( fn*xinv ) ) * zetn - zetnm1 )
            bn =  ( (  mre * rbiga(n) + ( fn*xinv ) ) * psin - psinm1 )
     $          / ( (  mre * rbiga(n) + ( fn*xinv ) ) * zetn - zetnm1 )
         else
c                                       ** absorptive case
c
            an = ( ( cioriv * cbiga(n) + ( fn*xinv ) ) * psin - psinm1 )
     $          /( ( cioriv * cbiga(n) + ( fn*xinv ) ) * zetn - zetnm1 )
            bn = ( (   cior * cbiga(n) + ( fn*xinv ) ) * psin - psinm1 )
     $          /( (   cior * cbiga(n) + ( fn*xinv ) ) * zetn - zetnm1 )
            qsca = qsca + twonp1 * ( sq( an ) + sq( bn ) )
c
         end if
c                       ** save mie coefficients for *pmom* calculation
         lita( n ) = an
         litb( n ) = bn
c                            ** increment mie sums for non-angle-
c                            ** dependent quantities
c
         sforw      = sforw      + twonp1 * ( an + bn )
         tforw( 1 ) = tforw( 1 ) + tcoef  * ( an - bn )
         sback      = sback      + ( mm * twonp1 ) * ( an - bn )
         tback( 1 ) = tback( 1 ) + ( mm * tcoef )  * ( an + bn )
         gqsc = gqsc + ( fn - rn ) * dble( anm1 * dconjg( an )
     $                                   + bnm1 * dconjg( bn ) )
     $          + coeff * dble( an * dconjg( bn ) )
c
         if ( yesang )  then
c                                      ** put mie coefficients in form
c                                      ** needed for computing s+, s-
c                                      ** ( ref. 2, p. 1507 )
            anp = coeff * ( an + bn )
            bnp = coeff * ( an - bn )
c                                      ** increment mie sums for s+, s-
c                                      ** while upward recursing
c                                      ** angular functions little pi
c                                      ** and little tau
            if ( anyang )  then
c                                         ** arbitrary angles
c
c                                              ** vectorizable loop
               do  80  j = 1, numang
                  rtmp = ( xmu( j ) * pin( j ) ) - pinm1( j )
                  taun =  fn * rtmp - pinm1( j )
                  sp( j )  = sp( j ) + anp * ( pin( j ) + taun )
                  sm( j )  = sm( j ) + bnp * ( pin( j ) - taun )
                  pinm1( j ) = pin( j )
                  pin( j ) = ( xmu( j ) * pin( j ) ) + np1dn * rtmp
   80          continue
c
            else
c                                  ** angles symmetric about 90 degrees
               anpm = mm * anp
               bnpm = mm * bnp
c                                          ** vectorizable loop
               do  90  j = 1, nangd2
                  rtmp = ( xmu( j ) * pin( j ) ) - pinm1( j )
                  taun =  fn * rtmp - pinm1( j )
                  sp ( j ) = sp ( j ) +  anp * ( pin( j ) + taun )
                  sms( j ) = sms( j ) + bnpm * ( pin( j ) + taun )
                  sm ( j ) = sm ( j ) +  bnp * ( pin( j ) - taun )
                  sps( j ) = sps( j ) + anpm * ( pin( j ) - taun )
                  pinm1( j ) = pin( j )
                  pin( j ) = ( xmu( j ) * pin( j ) ) + np1dn * rtmp
   90          continue
c
            end if
         end if
c                          ** update relevant quantities for next
c                          ** pass through loop
         mm   =  - mm
         anm1 = an
         bnm1 = bn
c                           ** upward recurrence for ricatti-bessel
c                           ** functions ( ref. 1, eq. 17 )
c
         zet    = ( twonp1 * xinv ) * zetn - zetnm1
         zetnm1 = zetn
         zetn   = zet
         psinm1 = psin
         psin   = dble( zetn )
  100 continue
c
c ---------- end loop to sum mie series --------------------------------
c
c
      qext = 2. / xx**2 * dble( sforw )
      if ( perfct .or. noabs )  then
         qsca = qext
      else
         qsca = 2. / xx**2 * qsca
      end if
c
      gqsc = 4. / xx**2 * gqsc
      sforw = 0.5 * sforw
      sback = 0.5 * sback
      tforw( 2 ) = 0.5 * (   sforw + 0.25 * tforw( 1 ) )
      tforw( 1 ) = 0.5 * (   sforw - 0.25 * tforw( 1 ) )
      tback( 2 ) = 0.5 * (   sback + 0.25 * tback( 1 ) )
      tback( 1 ) = 0.5 * ( - sback + 0.25 * tback( 1 ) )
c
      if ( yesang )  then
c                                ** recover scattering amplitudes
c                                ** from s+, s- ( ref. 1, eq. 11 )
         if ( anyang )  then
c                                         ** vectorizable loop
            do  110  j = 1, numang
               s1( j ) = 0.5 * ( sp( j ) + sm( j ) )
               s2( j ) = 0.5 * ( sp( j ) - sm( j ) )
  110       continue
c
         else
c                                         ** vectorizable loop
            do  120  j = 1, nangd2
               s1( j ) = 0.5 * ( sp( j ) + sm( j ) )
               s2( j ) = 0.5 * ( sp( j ) - sm( j ) )
  120       continue
c                                         ** vectorizable loop
            do  130  j = 1, nangd2
               s1( numang+1 - j ) = 0.5 * ( sps( j ) + sms( j ) )
               s2( numang+1 - j ) = 0.5 * ( sps( j ) - sms( j ) )
  130       continue
         end if
c
      end if
c                                         ** calculate legendre moments
  200 if ( nmom.gt.0 )
     $     call lpcoef ( ntrm, nmom, ipolzn, momdim, calcmo, npquan,
     $                   lita, litb, pmom )
c
      if ( dimag(crefin) .gt. 0.0 )  then
c                                         ** take complex conjugates
c                                         ** of scattering amplitudes
         sforw = dconjg( sforw )
         sback = dconjg( sback )
         do  210  i = 1, 2
            tforw( i ) = dconjg( tforw(i) )
            tback( i ) = dconjg( tback(i) )
  210    continue
c
         do  220  j = 1, numang
            s1( j ) = dconjg( s1(j) )
            s2( j ) = dconjg( s2(j) )
  220    continue
c
      end if
c
      if ( pass1 )  then
c                             ** compare test case results with
c                             ** correct answers and abort if bad
c
         call  testmi ( qext, qsca, gqsc, sforw, sback, s1, s2,
     $                  tforw, tback, pmom, momdim, ok )
         if ( .not. ok )  then
            prnt(1) = .false.
            prnt(2) = .false.
            call  miprnt( prnt, xx, perfct, crefin, numang, xmu, qext,
     $                    qsca, gqsc, nmom, ipolzn, momdim, calcmo,
     $                    pmom, sforw, sback, tforw, tback, s1, s2 )
            call errmsg( 'miev0 -- self-test failed', .true. )
         end if
c                                       ** restore user input values
         xx     = xxsav
         crefin = cresav
         mimcut = mimsav
         perfct = persav
         anyang = anysav
         nmom   = nmosav
         ipolzn = iposav
         numang = numsav
         xmu(1) = xmusav
         pass1 = .false.
         go to 10
c
      end if
c
      if ( prnt(1) .or. prnt(2) )
     $   call  miprnt( prnt, xx, perfct, crefin, numang, xmu, qext,
     $                 qsca, gqsc, nmom, ipolzn, momdim, calcmo,
     $                 pmom, sforw, sback, tforw, tback, s1, s2 )
c
      return
c
      end

      subroutine  ckinmi( numang, maxang, xx, perfct, crefin, momdim, 1
     $                    nmom, ipolzn, anyang, xmu, calcmo, npquan )
c
c        check for bad input to 'miev0' and calculate -calcmo,npquan-
c
      implicit none
      logical  perfct, anyang, calcmo(*)
      integer  numang, maxang, momdim, nmom, ipolzn, npquan
      real*8    xx, xmu(*)
      integer i,l,j,ip
      complex*16  crefin
c
      character*4  string
      logical  inperr
c
      inperr = .false.
c
      if ( numang.gt.maxang )  then
         call errmsg( 'miev0--parameter maxang too small', .true. )
         inperr = .true.
      end if
      if ( numang.lt.0 )  call  wrtbad( 'numang', inperr )
      if ( xx.lt.0. )     call  wrtbad( 'xx', inperr )
      if ( .not.perfct .and. dble(crefin).le.0. )then
         print *,'crefin=',crefin
         call wrtbad( 'crefin', inperr )
      endif
      if ( momdim.lt.1 )  call wrtbad( 'momdim', inperr )
c
      if ( nmom.ne.0 )  then
         if ( nmom.lt.0 .or. nmom.gt.momdim ) call wrtbad('nmom',inperr)
         if ( iabs(ipolzn).gt.4444 )  call  wrtbad( 'ipolzn', inperr )
         npquan = 0
         do 5  l = 1, 4
            calcmo( l ) = .false.
    5    continue
         if ( ipolzn.ne.0 )  then
c                                 ** parse out -ipolzn- into its digits
c                                 ** to find which phase quantities are
c                                 ** to have their moments calculated
c
            write( string, '(i4)' )  iabs(ipolzn)
            do 10  j = 1, 4
               ip = ichar( string(j:j) ) - ichar( '0' )
               if ( ip.ge.1 .and. ip.le.4 )  calcmo( ip ) = .true.
               if ( ip.eq.0 .or. (ip.ge.5 .and. ip.le.9) )
     $              call  wrtbad( 'ipolzn', inperr )
               npquan = max0( npquan, ip )
   10       continue
         end if
      end if
c
      if ( anyang )  then
c                                ** allow for slight imperfections in
c                                ** computation of cosine
          do  20  i = 1, numang
             if ( xmu(i).lt.-1.00001 .or. xmu(i).gt.1.00001 )
     $            call wrtbad( 'xmu', inperr )
   20     continue
      else
          do  22  i = 1, ( numang + 1 ) / 2
             if ( xmu(i).lt.-0.00001 .or. xmu(i).gt.1.00001 )
     $            call wrtbad( 'xmu', inperr )
   22     continue
      end if
c
      if ( inperr )
     $     call errmsg( 'miev0--input error(s).  aborting...', .true. )
c
      if ( xx.gt.20000.0 .or. dble(crefin).gt.10.0 .or.
     $     dabs( dimag(crefin) ).gt.10.0 )  call  errmsg(
     $     'miev0--xx or crefin outside tested range', .false. )
c
      return
      end

      subroutine  lpcoef ( ntrm, nmom, ipolzn, momdim, calcmo, npquan, 1
     $                     a, b, pmom )
c
c         calculate legendre polynomial expansion coefficients (also
c         called moments) for phase quantities ( ref. 5 formulation )
c
c     input:  ntrm                    number terms in mie series
c             nmom, ipolzn, momdim    'miev0' arguments
c             calcmo                  flags calculated from -ipolzn-
c             npquan                  defined in 'miev0'
c             a, b                    mie series coefficients
c
c     output: pmom                   legendre moments ('miev0' argument)
c
c     *** notes ***
c
c         (1)  eqs. 2-5 are in error in dave, appl. opt. 9,
c         1888 (1970).  eq. 2 refers to m1, not m2;  eq. 3 refers to
c         m2, not m1.  in eqs. 4 and 5, the subscripts on the second
c         term in square brackets should be interchanged.
c
c         (2)  the general-case logic in this subroutine works correctly
c         in the two-term mie series case, but subroutine  'lpco2t'
c         is called instead, for speed.
c
c         (3)  subroutine  'lpco1t', to do the one-term case, is never
c         called within the context of 'miev0', but is included for
c         complete generality.
c
c         (4)  some improvement in speed is obtainable by combining the
c         310- and 410-loops, if moments for both the third and fourth
c         phase quantities are desired, because the third phase quantity
c         is the real part of a complex series, while the fourth phase
c         quantity is the imaginary part of that very same series.  but
c         most users are not interested in the fourth phase quantity,
c         which is related to circular polarization, so the present
c         scheme is usually more efficient.
c
      implicit none
      logical  calcmo(*)
      integer  ipolzn, momdim, nmom, ntrm, npquan
      real*8    pmom( 0:momdim, * )
      complex*16  a(*), b(*)
c
c           ** specification of local variables
c
c      am(m)       numerical coefficients  a-sub-m-super-l
c                     in dave, eqs. 1-15, as simplified in ref. 5.
c
c      bi(i)       numerical coefficients  b-sub-i-super-l
c                     in dave, eqs. 1-15, as simplified in ref. 5.
c
c      bidel(i)    1/2 bi(i) times factor capital-del in dave
c
c      cm,dm()     arrays c and d in dave, eqs. 16-17 (mueller form),
c                     calculated using recurrence derived in ref. 5
c
c      cs,ds()     arrays c and d in ref. 4, eqs. a5-a6 (sekera form),
c                     calculated using recurrence derived in ref. 5
c
c      c,d()       either -cm,dm- or -cs,ds-, depending on -ipolzn-
c
c      evenl       true for even-numbered moments;  false otherwise
c
c      idel        1 + little-del  in dave
c
c      maxtrm      max. no. of terms in mie series
c
c      maxmom      max. no. of non-zero moments
c
c      nummom      number of non-zero moments
c
c      recip(k)    1 / k
c
      integer maxtrm,maxmom,mxmom2,maxrcp
      parameter  ( maxtrm = 1102, maxmom = 2*maxtrm, mxmom2 = maxmom/2,
     $             maxrcp = 4*maxtrm + 2 )
      real*8      am( 0:maxtrm ), bi( 0:mxmom2 ), bidel( 0:mxmom2 ),
     $           recip( maxrcp )
      complex*16 cm( maxtrm ), dm( maxtrm ), cs( maxtrm ), ds( maxtrm ),
     $           c( maxtrm ), d( maxtrm )
      integer k,j,l,nummom,ld2,idel,m,i,mmax,imax
      real*8 sum
      equivalence  ( c, cm ),  ( d, dm )
      logical    pass1, evenl
      save  pass1, recip
      data  pass1 / .true. /
c
c
      if ( pass1 )  then
c
         do  1  k = 1, maxrcp
            recip( k ) = 1.0 / k
    1    continue
         pass1 = .false.
c
      end if
c
      do  5  j = 1, max0( 1, npquan )
         do  5  l = 0, nmom
            pmom( l, j ) = 0.0
    5 continue
c
      if ( ntrm.eq.1 )  then
         call  lpco1t ( nmom, ipolzn, momdim, calcmo, a, b, pmom )
         return
      else if ( ntrm.eq.2 )  then
         call  lpco2t ( nmom, ipolzn, momdim, calcmo, a, b, pmom )
         return
      end if
c
      if ( ntrm+2 .gt. maxtrm )
     $     call errmsg( 'lpcoef--parameter maxtrm too small', .true. )
c
c                                     ** calculate mueller c, d arrays
      cm( ntrm+2 ) = ( 0., 0. )
      dm( ntrm+2 ) = ( 0., 0. )
      cm( ntrm+1 ) = ( 1. - recip( ntrm+1 ) ) * b( ntrm )
      dm( ntrm+1 ) = ( 1. - recip( ntrm+1 ) ) * a( ntrm )
      cm( ntrm ) = ( recip(ntrm) + recip(ntrm+1) ) * a( ntrm )
     $             + ( 1. - recip(ntrm) ) * b( ntrm-1 )
      dm( ntrm ) = ( recip(ntrm) + recip(ntrm+1) ) * b( ntrm )
     $             + ( 1. - recip(ntrm) ) * a( ntrm-1 )
c
      do  10  k = ntrm-1, 2, -1
         cm( k ) = cm( k+2 ) - ( 1. + recip(k+1) ) * b( k+1 )
     $                       + ( recip(k) + recip(k+1) ) * a( k )
     $                       + ( 1. - recip(k) ) * b( k-1 )
         dm( k ) = dm( k+2 ) - ( 1. + recip(k+1) ) * a( k+1 )
     $                       + ( recip(k) + recip(k+1) ) * b( k )
     $                       + ( 1. - recip(k) ) * a( k-1 )
   10 continue
      cm( 1 ) = cm( 3 ) + 1.5 * ( a( 1 ) - b( 2 ) )
      dm( 1 ) = dm( 3 ) + 1.5 * ( b( 1 ) - a( 2 ) )
c
      if ( ipolzn.ge.0 )  then
c
         do  20  k = 1, ntrm + 2
            c( k ) = ( 2*k - 1 ) * cm( k )
            d( k ) = ( 2*k - 1 ) * dm( k )
   20    continue
c
      else
c                                    ** compute sekera c and d arrays
         cs( ntrm+2 ) = ( 0., 0. )
         ds( ntrm+2 ) = ( 0., 0. )
         cs( ntrm+1 ) = ( 0., 0. )
         ds( ntrm+1 ) = ( 0., 0. )
c
         do  30  k = ntrm, 1, -1
            cs( k ) = cs( k+2 ) + ( 2*k + 1 ) * ( cm( k+1 ) - b( k ) )
            ds( k ) = ds( k+2 ) + ( 2*k + 1 ) * ( dm( k+1 ) - a( k ) )
   30    continue
c
         do  40  k = 1, ntrm + 2
            c( k ) = ( 2*k - 1 ) * cs( k )
            d( k ) = ( 2*k - 1 ) * ds( k )
   40    continue
c
      end if
c
c
      if( ipolzn.lt.0 )  nummom = min0( nmom, 2*ntrm - 2 )
      if( ipolzn.ge.0 )  nummom = min0( nmom, 2*ntrm )
      if ( nummom .gt. maxmom )
     $     call errmsg( 'lpcoef--parameter maxtrm too small', .true. )
c
c                               ** loop over moments
      do  500  l = 0, nummom
         ld2 = l / 2
         evenl = mod( l,2 ) .eq. 0
c                                    ** calculate numerical coefficients
c                                    ** a-sub-m and b-sub-i in dave
c                                    ** double-sums for moments
         if( l.eq.0 )  then
c
            idel = 1
            do  60  m = 0, ntrm
               am( m ) = 2.0 * recip( 2*m + 1 )
   60       continue
            bi( 0 ) = 1.0
c
         else if( evenl )  then
c
            idel = 1
            do  70  m = ld2, ntrm
               am( m ) = ( 1. + recip( 2*m-l+1 ) ) * am( m )
   70       continue
            do  75  i = 0, ld2-1
               bi( i ) = ( 1. - recip( l-2*i ) ) * bi( i )
   75       continue
            bi( ld2 ) = ( 2. - recip( l ) ) * bi( ld2-1 )
c
         else
c
            idel = 2
            do  80  m = ld2, ntrm
               am( m ) = ( 1. - recip( 2*m+l+2 ) ) * am( m )
   80       continue
            do  85  i = 0, ld2
               bi( i ) = ( 1. - recip( l+2*i+1 ) ) * bi( i )
   85       continue
c
         end if
c                                     ** establish upper limits for sums
c                                     ** and incorporate factor capital-
c                                     ** del into b-sub-i
         mmax = ntrm - idel
         if( ipolzn.ge.0 )  mmax = mmax + 1
         imax = min0( ld2, mmax - ld2 )
         if( imax.lt.0 )  go to 600
         do  90  i = 0, imax
            bidel( i ) = bi( i )
   90    continue
         if( evenl )  bidel( 0 ) = 0.5 * bidel( 0 )
c
c                                    ** perform double sums just for
c                                    ** phase quantities desired by user
         if( ipolzn.eq.0 )  then
c
            do  110  i = 0, imax
c                                           ** vectorizable loop (cray)
               sum = 0.0
               do  100  m = ld2, mmax - i
                  sum = sum + am( m ) *
     $                      ( dble( c(m-i+1) * dconjg( c(m+i+idel) ) )
     $                      + dble( d(m-i+1) * dconjg( d(m+i+idel) ) ) )
  100          continue
               pmom( l,1 ) = pmom( l,1 ) + bidel( i ) * sum
  110       continue
            pmom( l,1 ) = 0.5 * pmom( l,1 )
            go to 500
c
         end if
c
         if ( calcmo(1) )  then
            do  160  i = 0, imax
c                                           ** vectorizable loop (cray)
               sum = 0.0
               do  150  m = ld2, mmax - i
                  sum = sum + am( m ) *
     $                        dble( c(m-i+1) * dconjg( c(m+i+idel) ) )
  150          continue
               pmom( l,1 ) = pmom( l,1 ) + bidel( i ) * sum
  160       continue
         end if
c
c
         if ( calcmo(2) )  then
            do  210  i = 0, imax
c                                           ** vectorizable loop (cray)
               sum = 0.0
               do  200  m = ld2, mmax - i
                  sum = sum + am( m ) *
     $                        dble( d(m-i+1) * dconjg( d(m+i+idel) ) )
  200          continue
               pmom( l,2 ) = pmom( l,2 ) + bidel( i ) * sum
  210       continue
         end if
c
c
         if ( calcmo(3) )  then
            do  310  i = 0, imax
c                                           ** vectorizable loop (cray)
               sum = 0.0
               do  300  m = ld2, mmax - i
                  sum = sum + am( m ) *
     $                      ( dble( c(m-i+1) * dconjg( d(m+i+idel) ) )
     $                      + dble( c(m+i+idel) * dconjg( d(m-i+1) ) ) )
  300          continue
               pmom( l,3 ) = pmom( l,3 ) + bidel( i ) * sum
  310       continue
            pmom( l,3 ) = 0.5 * pmom( l,3 )
         end if
c
c
         if ( calcmo(4) )  then
            do  410  i = 0, imax
c                                           ** vectorizable loop (cray)
               sum = 0.0
               do  400  m = ld2, mmax - i
                  sum = sum + am( m ) *
     $                      ( dimag( c(m-i+1) * dconjg( d(m+i+idel) ) )
     $                      + dimag( c(m+i+idel) * dconjg( d(m-i+1) ) ))
  400          continue
               pmom( l,4 ) = pmom( l,4 ) + bidel( i ) * sum
  410       continue
            pmom( l,4 ) = - 0.5 * pmom( l,4 )
         end if
c
  500 continue
c
c
  600 return
      end

      subroutine  lpco1t ( nmom, ipolzn, momdim, calcmo, a, b, pmom ) 1
c
c         calculate legendre polynomial expansion coefficients (also
c         called moments) for phase quantities in special case where
c         no. terms in mie series = 1
c
c        input:  nmom, ipolzn, momdim     'miev0' arguments
c                calcmo                   flags calculated from -ipolzn-
c                a(1), b(1)               mie series coefficients
c
c        output: pmom                     legendre moments
c
      implicit none
      logical  calcmo(*)
      integer  ipolzn, momdim, nmom,nummom,l
      real*8    pmom( 0:momdim, * ),sq,a1sq,b1sq
      complex*16  a(*), b(*), ctmp, a1b1c
      sq( ctmp ) = dble( ctmp )**2 + dimag( ctmp )**2
c
c
      a1sq = sq( a(1) )
      b1sq = sq( b(1) )
      a1b1c = a(1) * dconjg( b(1) )
c
      if( ipolzn.lt.0 )  then
c
         if( calcmo(1) )  pmom( 0,1 ) = 2.25 * b1sq
         if( calcmo(2) )  pmom( 0,2 ) = 2.25 * a1sq
         if( calcmo(3) )  pmom( 0,3 ) = 2.25 * dble( a1b1c )
         if( calcmo(4) )  pmom( 0,4 ) = 2.25 *dimag( a1b1c )
c
      else
c
         nummom = min0( nmom, 2 )
c                                   ** loop over moments
         do  100  l = 0, nummom
c
            if( ipolzn.eq.0 )  then
               if( l.eq.0 )  pmom( l,1 ) = 1.5 * ( a1sq + b1sq )
               if( l.eq.1 )  pmom( l,1 ) = 1.5 * dble( a1b1c )
               if( l.eq.2 )  pmom( l,1 ) = 0.15 * ( a1sq + b1sq )
               go to 100
            end if
c
            if( calcmo(1) )  then
               if( l.eq.0 )  pmom( l,1 ) = 2.25 * ( a1sq + b1sq / 3. )
               if( l.eq.1 )  pmom( l,1 ) = 1.5 * dble( a1b1c )
               if( l.eq.2 )  pmom( l,1 ) = 0.3 * b1sq
            end if
c
            if( calcmo(2) )  then
               if( l.eq.0 )  pmom( l,2 ) = 2.25 * ( b1sq + a1sq / 3. )
               if( l.eq.1 )  pmom( l,2 ) = 1.5 * dble( a1b1c )
               if( l.eq.2 )  pmom( l,2 ) = 0.3 * a1sq
            end if
c
            if( calcmo(3) )  then
               if( l.eq.0 )  pmom( l,3 ) = 3.0 * dble( a1b1c )
               if( l.eq.1 )  pmom( l,3 ) = 0.75 * ( a1sq + b1sq )
               if( l.eq.2 )  pmom( l,3 ) = 0.3 * dble( a1b1c )
            end if
c
            if( calcmo(4) )  then
               if( l.eq.0 )  pmom( l,4 ) = - 1.5 * dimag( a1b1c )
               if( l.eq.1 )  pmom( l,4 ) = 0.0
               if( l.eq.2 )  pmom( l,4 ) = 0.3 * dimag( a1b1c )
            end if
c
  100    continue
c
      end if
c
      return
      end

      subroutine  lpco2t ( nmom, ipolzn, momdim, calcmo, a, b, pmom ) 1
c
c         calculate legendre polynomial expansion coefficients (also
c         called moments) for phase quantities in special case where
c         no. terms in mie series = 2
c
c        input:  nmom, ipolzn, momdim     'miev0' arguments
c                calcmo                   flags calculated from -ipolzn-
c                a(1-2), b(1-2)           mie series coefficients
c
c        output: pmom                     legendre moments
c
      implicit none
      logical  calcmo(*)
      integer  ipolzn, momdim, nmom,l,nummom
      real*8    pmom( 0:momdim, * ),sq,a1sq,b1sq,pm1,pm2,a2sq,b2sq
      complex*16  a(*), b(*)
      complex*16  a2c, b2c, ctmp, ca, cac, cat, cb, cbc, cbt, cg, ch
      sq( ctmp ) = dble( ctmp )**2 + dimag( ctmp )**2
c
c
      ca = 3. * a(1) - 5. * b(2)
      cat= 3. * b(1) - 5. * a(2)
      cac = dconjg( ca )
      a2sq = sq( a(2) )
      b2sq = sq( b(2) )
      a2c = dconjg( a(2) )
      b2c = dconjg( b(2) )
c
      if( ipolzn.lt.0 )  then
c                                   ** loop over sekera moments
         nummom = min0( nmom, 2 )
         do  50  l = 0, nummom
c
            if( calcmo(1) )  then
               if( l.eq.0 ) pmom( l,1 ) = 0.25 * ( sq(cat) +
     $                                             (100./3.) * b2sq )
               if( l.eq.1 ) pmom( l,1 ) = (5./3.) * dble( cat * b2c )
               if( l.eq.2 ) pmom( l,1 ) = (10./3.) * b2sq
            end if
c
            if( calcmo(2) )  then
               if( l.eq.0 ) pmom( l,2 ) = 0.25 * ( sq(ca) +
     $                                             (100./3.) * a2sq )
               if( l.eq.1 ) pmom( l,2 ) = (5./3.) * dble( ca * a2c )
               if( l.eq.2 ) pmom( l,2 ) = (10./3.) * a2sq
            end if
c
            if( calcmo(3) )  then
               if( l.eq.0 ) pmom( l,3 ) = 0.25 * dble( cat*cac +
     $                                           (100./3.)*b(2)*a2c )
               if( l.eq.1 ) pmom( l,3 ) = 5./6. * dble( b(2)*cac +
     $                                                  cat*a2c )
               if( l.eq.2 ) pmom( l,3 ) = 10./3. * dble( b(2) * a2c )
            end if
c
            if( calcmo(4) )  then
               if( l.eq.0 ) pmom( l,4 ) = -0.25 * dimag( cat*cac +
     $                                           (100./3.)*b(2)*a2c )
               if( l.eq.1 ) pmom( l,4 ) = -5./6. * dimag( b(2)*cac +
     $                                                  cat*a2c )
               if( l.eq.2 ) pmom( l,4 ) = -10./3. * dimag( b(2) * a2c )
            end if
c
   50    continue
c
      else
c
         cb = 3. * b(1) + 5. * a(2)
         cbt= 3. * a(1) + 5. * b(2)
         cbc = dconjg( cb )
         cg = ( cbc*cbt + 10.*( cac*a(2) + b2c*cat) ) / 3.
         ch = 2.*( cbc*a(2) + b2c*cbt )
c
c                                   ** loop over mueller moments
         nummom = min0( nmom, 4 )
         do  100  l = 0, nummom
c
            if( ipolzn.eq.0 .or. calcmo(1) )  then
               if( l.eq.0 ) pm1 = 0.25 * sq(ca) + sq(cb) / 12.
     $                            + (5./3.) * dble(ca*b2c) + 5.*b2sq
               if( l.eq.1 ) pm1 = dble( cb * ( cac/6. + b2c ) )
               if( l.eq.2 ) pm1 = sq(cb)/30. + (20./7.) * b2sq
     $                            + (2./3.) * dble( ca * b2c )
               if( l.eq.3 ) pm1 = (2./7.) * dble( cb * b2c )
               if( l.eq.4 ) pm1 = (40./63.) * b2sq
               if ( calcmo(1) )  pmom( l,1 ) = pm1
            end if
c
            if( ipolzn.eq.0 .or. calcmo(2) )  then
               if( l.eq.0 ) pm2 = 0.25*sq(cat) + sq(cbt) / 12.
     $                            + (5./3.) * dble(cat*a2c) + 5.*a2sq
               if( l.eq.1 ) pm2 = dble( cbt * ( dconjg(cat)/6. + a2c) )
               if( l.eq.2 ) pm2 = sq(cbt)/30. + (20./7.) * a2sq
     $                            + (2./3.) * dble( cat * a2c )
               if( l.eq.3 ) pm2 = (2./7.) * dble( cbt * a2c )
               if( l.eq.4 ) pm2 = (40./63.) * a2sq
               if ( calcmo(2) )  pmom( l,2 ) = pm2
            end if
c
            if( ipolzn.eq.0 )  then
               pmom( l,1 ) = 0.5 * ( pm1 + pm2 )
               go to 100
            end if
c
            if( calcmo(3) )  then
               if( l.eq.0 ) pmom( l,3 ) = 0.25 * dble( cac*cat + cg +
     $                                                 20.*b2c*a(2) )
               if( l.eq.1 ) pmom( l,3 ) = dble( cac*cbt + cbc*cat +
     $                                          3.*ch ) / 12.
               if( l.eq.2 ) pmom( l,3 ) = 0.1 * dble( cg + (200./7.) *
     $                                                b2c * a(2) )
               if( l.eq.3 ) pmom( l,3 ) = dble( ch ) / 14.
               if( l.eq.4 ) pmom( l,3 ) = 40./63. * dble( b2c * a(2) )
            end if
c
            if( calcmo(4) )  then
               if( l.eq.0 ) pmom( l,4 ) = 0.25 * dimag( cac*cat + cg +
     $                                                  20.*b2c*a(2) )
               if( l.eq.1 ) pmom( l,4 ) = dimag( cac*cbt + cbc*cat +
     $                                           3.*ch ) / 12.
               if( l.eq.2 ) pmom( l,4 ) = 0.1 * dimag( cg + (200./7.) *
     $                                                 b2c * a(2) )
               if( l.eq.3 ) pmom( l,4 ) = dimag( ch ) / 14.
               if( l.eq.4 ) pmom( l,4 ) = 40./63. * dimag( b2c * a(2) )
            end if
c
  100    continue
c
      end if
c
      return
      end

      subroutine  biga( cior, xx, ntrm, noabs, yesang, rbiga, cbiga ) 1
c
c        calculate logarithmic derivatives of j-bessel-function
c
c     input :  cior, xx, ntrm, noabs, yesang  (defined in 'miev0')
c
c    output :  rbiga or cbiga  (defined in 'miev0')
c
c    internal variables :
c
c       confra     value of lentz continued fraction for -cbiga(ntrm)-,
c                     used to initialize downward recurrence.
c       down       = true, use down-recurrence.  false, do not.
c       f1,f2,f3   arithmetic statement functions used in determining
c                     whether to use up-  or down-recurrence
c                     ( ref. 2, eqs. 6-8 )
c       mre        real refractive index
c       mim        imaginary refractive index
c       rezinv     1 / ( mre * xx ); temporary variable for recurrence
c       zinv       1 / ( cior * xx ); temporary variable for recurrence
c
      implicit none
      logical  down, noabs, yesang
      integer  ntrm,n
      real*8    mre, mim, rbiga(*), xx, rezinv, rtmp, f1,f2,f3
      complex*16  cior, ctmp, confra, cbiga(*), zinv
      f1( mre ) =  - 8.0 + mre**2 * ( 26.22 + mre * ( - 0.4474
     $             + mre**3 * ( 0.00204 - 0.000175 * mre ) ) )
      f2( mre ) = 3.9 + mre * ( - 10.8 + 13.78 * mre )
      f3( mre ) =  - 15.04 + mre * ( 8.42 + 16.35 * mre )
c
c                                  ** decide whether 'biga' can be
c                                  ** calculated by up-recurrence
      mre =  dble( cior )
      mim =  dabs( dimag( cior ) )
      if ( mre.lt.1.0 .or. mre.gt.10.0 .or. mim.gt.10.0 )  then
         down = .true.
      else if ( yesang )  then
         down = .true.
         if ( mim*xx .lt. f2( mre ) )  down = .false.
      else
         down = .true.
         if ( mim*xx .lt. f1( mre ) )  down = .false.
      end if
c
      zinv  = 1.0 / ( cior * xx )
      rezinv = 1.0 / ( mre * xx )
c
      if ( down )  then
c                          ** compute initial high-order 'biga' using
c                          ** lentz method ( ref. 1, pp. 17-20 )
c
         ctmp = confra( ntrm, zinv, xx )
c
c                                   *** downward recurrence for 'biga'
c                                   *** ( ref. 1, eq. 22 )
         if ( noabs )  then
c                                            ** no-absorption case
            rbiga( ntrm ) = dble( ctmp )
            do  25  n = ntrm, 2, - 1
               rbiga( n-1 ) = (n*rezinv)
     $                         - 1.0 / ( (n*rezinv) + rbiga( n ) )
   25       continue
c
         else
c                                            ** absorptive case
            cbiga( ntrm ) = ctmp
            do  30  n = ntrm, 2, - 1
               cbiga( n-1 ) = (n*zinv) - 1.0 / ( (n*zinv) + cbiga( n ) )
   30       continue
c
         end if
c
      else
c                              *** upward recurrence for 'biga'
c                              *** ( ref. 1, eqs. 20-21 )
         if ( noabs )  then
c                                            ** no-absorption case
            rtmp = dsin( mre*xx )
            rbiga( 1 ) =  - rezinv
     $                     + rtmp / ( rtmp*rezinv - dcos( mre*xx ) )
            do  40  n = 2, ntrm
               rbiga( n ) = - ( n*rezinv )
     $                       + 1.0 / ( ( n*rezinv ) - rbiga( n-1 ) )
   40       continue
c
         else
c                                                ** absorptive case
            ctmp = cdexp( - dcmplx(0.d0,2.d0) * cior * xx )
            cbiga( 1 ) = - zinv + (1.-ctmp) / ( zinv * (1.-ctmp) - 
     $                     dcmplx(0.d0,1.d0)*(1.+ctmp) )
            do  50  n = 2, ntrm
               cbiga( n ) = - (n*zinv) + 1.0 / ((n*zinv) - cbiga( n-1 ))
   50       continue
         end if
c
      end if
c
      return
      end

      complex*16 function  confra( n, zinv, xx )
c
c         compute bessel function ratio capital-a-sub-n from its
c         continued fraction using lentz method ( ref. 1, pp. 17-20 )
c
c         zinv = reciprocal of argument of capital-a
c
c    i n t e r n a l    v a r i a b l e s
c    ------------------------------------
c
c    cak      term in continued fraction expansion of capital-a
c                ( ref. 1, eq. 25 )
c    capt     factor used in lentz iteration for capital-a
c                ( ref. 1, eq. 27 )
c    cdenom   denominator in -capt-  ( ref. 1, eq. 28b )
c    cnumer   numerator   in -capt-  ( ref. 1, eq. 28a )
c    cdtd     product of two successive denominators of -capt-
c                factors  ( ref. 1, eq. 34c )
c    cntn     product of two successive numerators of -capt-
c                factors  ( ref. 1, eq. 34b )
c    eps1     ill-conditioning criterion
c    eps2     convergence criterion
c    kk       subscript k of -cak-  ( ref. 1, eq. 25b )
c    kount    iteration counter ( used only to prevent runaway )
c    maxit    max. allowed no. of iterations
c    mm       + 1  and - 1, alternately
c
      implicit none
      integer   n,maxit,mm,kk,kount
      real*8     xx,eps1,eps2
      complex*16   zinv
      complex*16   cak, capt, cdenom, cdtd, cnumer, cntn
      data  eps1 / 1.e - 2 /, eps2 / 1.e - 8 /
      data  maxit / 10000 /
c
c                                      *** ref. 1, eqs. 25a, 27
      confra = ( n + 1 ) * zinv
      mm     =  - 1
      kk     = 2 * n + 3
      cak    = ( mm * kk ) * zinv
      cdenom = cak
      cnumer = cdenom + 1.0 / confra
      kount  = 1
c
   20 kount = kount + 1
      if ( kount.gt.maxit )
     $     call errmsg( 'confra--iteration failed to converge$', .true.)
c
c                                         *** ref. 2, eq. 25b
      mm  =  - mm
      kk  = kk + 2
      cak = ( mm * kk ) * zinv
c                                         *** ref. 2, eq. 32
      if (      cdabs( cnumer/cak ).le.eps1
     $     .or. cdabs( cdenom/cak ).le.eps1 )  then
c
c                                  ** ill-conditioned case -- stride
c                                  ** two terms instead of one
c
c                                         *** ref. 2, eqs. 34
         cntn   = cak * cnumer + 1.0
         cdtd   = cak * cdenom + 1.0
         confra = ( cntn / cdtd ) * confra
c                                             *** ref. 2, eq. 25b
         mm  =  - mm
         kk  = kk + 2
         cak = ( mm * kk ) * zinv
c                                         *** ref. 2, eqs. 35
         cnumer = cak + cnumer / cntn
         cdenom = cak + cdenom / cdtd
         kount  = kount + 1
         go to 20
c
      else
c                                ** well-conditioned case
c
c                                        *** ref. 2, eqs. 26, 27
         capt   = cnumer / cdenom
         confra = capt * confra
c                                    ** check for convergence
c                                    ** ( ref. 2, eq. 31 )
c
         if (      dabs( dble(capt) - 1.0 ).ge.eps2
     $        .or. dabs( dimag(capt) )      .ge.eps2 )  then
c
c                                        *** ref. 2, eqs. 30a-b
            cnumer = cak + 1.0 / cnumer
            cdenom = cak + 1.0 / cdenom
            go to 20
         end if
      end if
c
      return
c
      end

      subroutine  miprnt( prnt, xx, perfct, crefin, numang, xmu, 2
     $                    qext, qsca, gqsc, nmom, ipolzn, momdim,
     $                    calcmo, pmom, sforw, sback, tforw, tback,
     $                    s1, s2 )
c
c         print scattering quantities of a single particle
c
      implicit none
      logical  perfct, prnt(*), calcmo(*)
      integer  ipolzn, momdim, nmom, numang,i,m,j
      real*8    gqsc, pmom( 0:momdim, * ), qext, qsca, xx, xmu(*)
      real*8 fi1,fi2,fnorm
      complex*16  crefin, sforw, sback, tforw(*), tback(*), s1(*), s2(*)
      character*22  fmt
c
c
      if ( perfct )  write ( 59, '(''1'',10x,a,1p,e11.4)' )
     $                'perfectly conducting case, size parameter =', xx
      if ( .not.perfct )  write ( 59, '(''1'',10x,3(a,1p,e11.4))' )
     $                  'refractive index:  real ', dble(crefin),
     $             '  imag ', dimag(crefin), ',   size parameter =', xx
c
      if ( prnt(1) .and. numang.gt.0 )  then
c
         write ( 59, '(/,a)' )
     $    '    cos(angle)  ------- s1 ---------  ------- s2 ---------'//
     $    '  --- s1*conjg(s2) ---   i1=s1**2   i2=s2**2  (i1+i2)/2'//
     $    '  deg polzn'
         do  10  i = 1, numang
            fi1 = dble( s1(i) ) **2 + dimag( s1(i) )**2
            fi2 = dble( s2(i) ) **2 + dimag( s2(i) )**2
            write( 59, '( i4, f10.6, 1p,10e11.3 )'   )
     $              i, xmu(i), s1(i), s2(i), s1(i)*dconjg(s2(i)),
     $              fi1, fi2, 0.5*(fi1+fi2), (fi2-fi1)/(fi2+fi1)
   10    continue
c
      end if
c
c
      if ( prnt(2) )  then
c
         write ( 59, '(/,a,9x,a,17x,a,17x,a,/,(0p,f7.2, 1p,6e12.3) )' )
     $           '  angle', 's-sub-1', 't-sub-1', 't-sub-2',
     $               0.0,     sforw,    tforw(1),  tforw(2),
     $              180.,     sback,    tback(1),  tback(2)
         write ( 59, '(/,4(a,1p,e11.4))' )
     $           ' efficiency factors,  extinction:', qext,
     $                              '   scattering:', qsca,
     $                              '   absorption:', qext-qsca,
     $                           '   rad. pressure:', qext-gqsc
c
         if ( nmom.gt.0 )  then
c
            write( 59, '(/,a)' )  ' normalized moments of :'
            if ( ipolzn.eq.0 ) write ( 59, '(''+'',27x,a)' ) 'phase fcn'
            if ( ipolzn.gt.0 )  write ( 59, '(''+'',33x,a)' )
     $         'm1           m2          s21          d21'
            if ( ipolzn.lt.0 )  write ( 59, '(''+'',33x,a)' )
     $         'r1           r2           r3           r4'
c
            fnorm = 4. / ( xx**2 * qsca )
            do  20  m = 0, nmom
               write ( 59, '(a,i4)' )  '      moment no.', m
               do 20  j = 1, 4
                  if( calcmo(j) )  then
                     write( fmt, 98 )  24 + (j-1)*13
                     write ( 59,fmt )  fnorm * pmom(m,j)
                  end if
   20       continue
         end if
c
      end if
c
      return
c
   98 format( '( ''+'', t', i2, ', 1p,e13.4 )' )
      end

      subroutine  small1 ( xx, numang, xmu, qext, qsca, gqsc, sforw, 1
     $                     sback, s1, s2, tforw, tback, a, b )
c
c       small-particle limit of mie quantities in totally reflecting
c       limit ( mie series truncated after 2 terms )
c
c        a,b       first two mie coefficients, with numerator and
c                  denominator expanded in powers of -xx- ( a factor
c                  of xx**3 is missing but is restored before return
c                  to calling program )  ( ref. 2, p. 1508 )
c
      implicit none
      integer  numang,j
      real*8    gqsc, qext, qsca, xx, xmu(*)
      real*8 twothr,fivthr,fivnin,sq,rtmp
      complex*16  a( 2 ), b( 2 ), sforw, sback, s1(*), s2(*),
     $         tforw(*), tback(*)
c
      parameter  ( twothr = 2./3., fivthr = 5./3., fivnin = 5./9. )
      complex*16    ctmp
      sq( ctmp ) = dble( ctmp )**2 + dimag( ctmp )**2
c
c
      a( 1 ) = dcmplx ( 0.d0, twothr * ( 1. - 0.2 * xx**2 ) )
     $       / dcmplx ( 1.d0 - 0.5 * xx**2, twothr * xx**3 )
c
      b( 1 ) = dcmplx ( 0.d0, - ( 1. - 0.1 * xx**2 ) / 3. )
     $       / dcmplx ( 1.d0 + 0.5 * xx**2, - xx**3 / 3. )
c
      a( 2 ) = dcmplx ( 0.d0,   xx**2 / 30. )
      b( 2 ) = dcmplx ( 0.d0, - xx**2 / 45. )
c
      qsca = 6. * xx**4 * ( sq( a(1) ) + sq( b(1) )
     $                      + fivthr * ( sq( a(2) ) + sq( b(2) ) ) )
      qext = qsca
      gqsc = 6. * xx**4 * dble( a(1) * dconjg( a(2) + b(1) )
     $                    + ( b(1) + fivnin * a(2) ) * dconjg( b(2) ) )
c
      rtmp = 1.5 * xx**3
      sforw      = rtmp * ( a(1) + b(1) + fivthr * ( a(2) + b(2) ) )
      sback      = rtmp * ( a(1) - b(1) - fivthr * ( a(2) - b(2) ) )
      tforw( 1 ) = rtmp * ( b(1) + fivthr * ( 2.*b(2) - a(2) ) )
      tforw( 2 ) = rtmp * ( a(1) + fivthr * ( 2.*a(2) - b(2) ) )
      tback( 1 ) = rtmp * ( b(1) - fivthr * ( 2.*b(2) + a(2) ) )
      tback( 2 ) = rtmp * ( a(1) - fivthr * ( 2.*a(2) + b(2) ) )
c
      do  10  j = 1, numang
         s1( j ) = rtmp * ( a(1) + b(1) * xmu(j) + fivthr *
     $              ( a(2) * xmu(j) + b(2) * ( 2.*xmu(j)**2 - 1. )) )
         s2( j ) = rtmp * ( b(1) + a(1) * xmu(j) + fivthr *
     $              ( b(2) * xmu(j) + a(2) * ( 2.*xmu(j)**2 - 1. )) )
   10 continue
c                                     ** recover actual mie coefficients
      a( 1 ) = xx**3 * a( 1 )
      a( 2 ) = xx**3 * a( 2 )
      b( 1 ) = xx**3 * b( 1 )
      b( 2 ) = xx**3 * b( 2 )
c
      return
      end

      subroutine  small2 ( xx, cior, calcqe, numang, xmu, qext, qsca, 1
     $                     gqsc, sforw, sback, s1, s2, tforw, tback,
     $                     a, b )
c
c       small-particle limit of mie quantities for general refractive
c       index ( mie series truncated after 2 terms )
c
c        a,b       first two mie coefficients, with numerator and
c                  denominator expanded in powers of -xx- ( a factor
c                  of xx**3 is missing but is restored before return
c                  to calling program )  ( ref. 2, p. 1508 )
c
c        ciorsq    square of refractive index
c
      implicit none
      logical  calcqe
      integer  numang,j
      real*8    gqsc, qext, qsca, xx, xmu(*)
      real*8 twothr,fivthr,sq,rtmp
      complex*16  a( 2 ), b( 2 ), cior, sforw, sback, s1(*), s2(*),
     $         tforw(*), tback(*)
c
      parameter  ( twothr = 2./3., fivthr = 5./3. )
      complex*16  ctmp, ciorsq
      sq( ctmp ) = dble( ctmp )**2 + dimag( ctmp )**2
c
c
      ciorsq = cior**2
      ctmp = dcmplx( 0.d0, twothr ) * ( ciorsq - 1.0 )
      a(1) = ctmp * ( 1.0 - 0.1 * xx**2 + (ciorsq/350. + 1./280.)*xx**4)
     $       / ( ciorsq + 2.0 + ( 1.0 - 0.7 * ciorsq ) * xx**2
     $           - ( ciorsq**2/175. - 0.275 * ciorsq + 0.25 ) * xx**4
     $           + xx**3 * ctmp * ( 1.0 - 0.1 * xx**2 ) )
c
      b(1) = (xx**2/30.) * ctmp * ( 1.0 + (ciorsq/35. - 1./14.) *xx**2 )
     $       / ( 1.0 - ( ciorsq/15. - 1./6. ) * xx**2 )
c
      a(2) = ( 0.1 * xx**2 ) * ctmp * ( 1.0 - xx**2 / 14. )
     $       / ( 2. * ciorsq + 3. - ( ciorsq/7. - 0.5 ) * xx**2 )
c
      qsca = 6. * xx**4 * ( sq(a(1)) + sq(b(1)) + fivthr * sq(a(2)) )
      gqsc = 6. * xx**4 * dble( a(1) * dconjg( a(2) + b(1) ) )
      qext = qsca
      if ( calcqe ) qext = 6. * xx * dble( a(1) + b(1) + fivthr * a(2) )
c
      rtmp = 1.5 * xx**3
      sforw      = rtmp * ( a(1) + b(1) + fivthr * a(2) )
      sback      = rtmp * ( a(1) - b(1) - fivthr * a(2) )
      tforw( 1 ) = rtmp * ( b(1) - fivthr * a(2) )
      tforw( 2 ) = rtmp * ( a(1) + 2. * fivthr * a(2) )
      tback( 1 ) = tforw( 1 )
      tback( 2 ) = rtmp * ( a(1) - 2. * fivthr * a(2) )
c
      do  10  j = 1, numang
         s1( j ) = rtmp * ( a(1) + ( b(1) + fivthr * a(2) ) * xmu(j) )
         s2( j ) = rtmp * ( b(1) + a(1) * xmu(j) + fivthr * a(2)
     $                      * ( 2. * xmu(j)**2 - 1. ) )
   10 continue
c                                     ** recover actual mie coefficients
      a( 1 ) = xx**3 * a( 1 )
      a( 2 ) = xx**3 * a( 2 )
      b( 1 ) = xx**3 * b( 1 )
      b( 2 ) = ( 0., 0. )
c
      return
      end

      subroutine  testmi ( qext, qsca, gqsc, sforw, sback, s1, s2, 1
     $                     tforw, tback, pmom, momdim, ok )
c
c         compare mie code test case results with correct answers
c         and return  ok=false  if even one result is inaccurate.
c
c         the test case is :  mie size parameter = 10
c                             refractive index   = 1.5 - 0.1 i
c                             scattering angle = 140 degrees
c                             1 sekera moment
c
c         results for this case may be found among the test cases
c         at the end of reference (1).
c
c         *** note *** when running on some computers, esp. in single
c         precision, the 'accur' criterion below may have to be relaxed.
c         however, if 'accur' must be set larger than 10**-3 for some
c         size parameters, your computer is probably not accurate
c         enough to do mie computations for those size parameters.
c
      implicit none
      integer momdim,m,n
      real*8    qext, qsca, gqsc, pmom( 0:momdim, * )
      complex*16  sforw, sback, s1(*), s2(*), tforw(*), tback(*)
      logical  ok, wrong
c
      real*8    accur, testqe, testqs, testgq, testpm( 0:1 )
      complex*16 testsf, testsb,tests1,tests2,testtf(2), testtb(2)
      data   testqe / 2.459791 /,  testqs / 1.235144 /,
     $       testgq / 1.139235 /,  testsf / ( 61.49476, -3.177994 ) /,
     $       testsb / ( 1.493434, 0.2963657 ) /,
     $       tests1 / ( -0.1548380, -1.128972) /,
     $       tests2 / ( 0.05669755, 0.5425681) /,
     $       testtf / ( 12.95238, -136.6436 ), ( 48.54238, 133.4656 ) /,
     $       testtb / ( 41.88414, -15.57833 ), ( 43.37758, -15.28196 )/,
     $       testpm / 227.1975, 183.6898 /
      real*8 calc,exact
c      data   accur / 1.e-5 /
      data   accur / 1.e-4 /
      wrong( calc, exact ) = dabs( (calc - exact) / exact ) .gt. accur
c
c
      ok = .true.
      if ( wrong( qext,testqe ) )
     $     call  tstbad( 'qext', abs((qext - testqe) / testqe), ok )
      if ( wrong( qsca,testqs ) )
     $     call  tstbad( 'qsca', abs((qsca - testqs) / testqs), ok )
      if ( wrong( gqsc,testgq ) )
     $     call  tstbad( 'gqsc', abs((gqsc - testgq) / testgq), ok )
c
      if ( wrong(  dble(sforw),  dble(testsf) ) .or.
     $     wrong( dimag(sforw), dimag(testsf) ) )
     $     call  tstbad( 'sforw', cdabs((sforw - testsf) / testsf), ok )
c
      if ( wrong(  dble(sback),  dble(testsb) ) .or.
     $     wrong( dimag(sback), dimag(testsb) ) )
     $     call  tstbad( 'sback', cdabs((sback - testsb) / testsb), ok )
c
      if ( wrong(  dble(s1(1)),  dble(tests1) ) .or.
     $     wrong( dimag(s1(1)), dimag(tests1) ) )
     $     call  tstbad( 's1', cdabs((s1(1) - tests1) / tests1), ok )
c
      if ( wrong(  dble(s2(1)),  dble(tests2) ) .or.
     $     wrong( dimag(s2(1)), dimag(tests2) ) )
     $     call  tstbad( 's2', cdabs((s2(1) - tests2) / tests2), ok )
c
      do  20  n = 1, 2
         if ( wrong(  dble(tforw(n)),  dble(testtf(n)) ) .or.
     $        wrong( dimag(tforw(n)), dimag(testtf(n)) ) )
     $        call  tstbad( 'tforw', cdabs( (tforw(n) - testtf(n)) /
     $                                     testtf(n) ), ok )
         if ( wrong(  dble(tback(n)),  dble(testtb(n)) ) .or.
     $        wrong( dimag(tback(n)), dimag(testtb(n)) ) )
     $        call  tstbad( 'tback', cdabs( (tback(n) - testtb(n)) /
     $                                      testtb(n) ), ok )
   20 continue
c
      do  30  m = 0, 1
         if ( wrong( pmom(m,1), testpm(m) ) )
     $        call  tstbad( 'pmom', dabs( (pmom(m,1)-testpm(m)) /
     $                                   testpm(m) ), ok )
   30 continue
c
      return
c
      end

      subroutine  errmsg( messag, fatal ) 9
c
c        print out a warning or error message;  abort if error
c
      implicit none
      logical       fatal, once
      character*(*) messag
      integer       maxmsg, nummsg
      save          maxmsg, nummsg, once
      data nummsg / 0 /,  maxmsg / 100 /,  once / .false. /
c
c
      if ( fatal )  then
         write ( *, '(2a)' )  ' ******* error >>>>>>  ', messag
         stop
      end if
c
      nummsg = nummsg + 1
      if ( nummsg.gt.maxmsg )  then
         if ( .not.once )  write ( *,99 )
         once = .true.
      else
         write ( *, '(2a)' )  ' ******* warning >>>>>>  ', messag
      endif
c
      return
c
   99 format( ///,' >>>>>>  too many warning messages --  ',
     $   'they will no longer be printed  <<<<<<<', /// )
      end

      subroutine  wrtbad ( varnam, erflag ) 9
c
c          write names of erroneous variables
c
c      input :   varnam = name of erroneous variable to be written
c                         ( character, any length )
c
c      output :  erflag = logical flag, set true by this routine
c ----------------------------------------------------------------------
      implicit none
      character*(*)  varnam
      logical        erflag
      integer        maxmsg, nummsg
      save  nummsg, maxmsg
      data  nummsg / 0 /,  maxmsg / 50 /
c
c
      nummsg = nummsg + 1
      write ( *, '(3a)' )  ' ****  input variable  ', varnam,
     $                     '  in error  ****'
      erflag = .true.
      if ( nummsg.eq.maxmsg )
     $   call  errmsg ( 'too many input errors.  aborting...$', .true. )
      return
c
      end

      subroutine  tstbad( varnam, relerr, ok ) 10
c
c       write name (-varnam-) of variable failing self-test and its
c       percent error from the correct value.  return  ok = false.
c
      implicit none
      character*(*)  varnam
      logical        ok
      real*8          relerr
c
c
      ok = .false.
      write( *, '(/,3a,1p,e11.2,a)' )
     $       ' output variable  ', varnam,'  differed by', 100.*relerr,
     $       '  per cent from correct value.  self-test failed.'
      return
c
      end