text:
<file_sep>      subroutine bcoher2_b(nsect,ninp,nref,c2thresh,
     $                     ffts,c2flag,c2,info)
c
c birrp
c
c multiple coherence estimation on each section by block averaging
c
c  input variables:
c     nsect--number of sections in ffts
c     ninp--number of output (i.e., local magnetic field) time series
c     nref--number of input (i.e., remote magnetic field) time series
c     c2thresh-coherence threshold
c     ffts--complex array containing nsect section fft's
c           for ninp+nref variables
c  output variables:
c     c2flag-logical vector, .true. if coherence threshold is exceeded
c     c2--array containing nsect/nblk section average coherence
c         estimates for ninp output variables
c     info--error flag, 0 for normal return, 1 for singular matrix
c
      include 'parameters.h'
      parameter (nblk=10)
      complex ffts
      logical c2flag
      dimension ffts(nsectm,*),
     $          c2(nsectm/nblk,*),c2flag(*)
      double precision syy,rcond
      double complex sxx,sxy,syx,z,sypyp
      dimension sxx(nrefm,nrefm),syx(nrefm),sxy(nrefm),
     $          ipvt(nrefm),z(nrefm)
      info=0
      do 50 n=0,nsect-1,nblk
        do 40 m=1,ninp
          do 10 i=1,nref
            syx(i)=0.
            do 10 j=1,nref
   10         sxx(i,j)=0.
          syy=0.
          do 20 ii=n+1,n+nblk
            syy=syy+abs(ffts(ii,m))**2
            do 20 i=1,nref
              syx(i)=syx(i)+conjg(ffts(ii,m))*ffts(ii,i+ninp)
              do 20 j=1,nref
   20           sxx(i,j)=sxx(i,j)+conjg(ffts(ii,i+ninp))*
     $                   ffts(ii,j+ninp)
          do 25 i=1,nref
   25       sxy(i)=conjg(syx(i))
          call zgeco(sxx,nrefm,nref,ipvt,rcond,z)
          if(1.d0+rcond.eq.1.d0)info=1
          job=0
          call zgesl(sxx,nrefm,nref,ipvt,sxy,job)
          sypyp=0.
          do 30 i=1,nref
   30       sypyp=sypyp+syx(i)*sxy(i)
   40     c2(n/nblk+1,m)=dreal(sypyp)/syy
   50   continue
      if(c2thresh.eq.0.)return
      do 80 nn=1,ninp
        do 80 i=1,nsect/nblk
          if(c2(i,nn).le.c2thresh)c2flag(i)=.false.
   80     continue
      return
      end
      subroutine bcoher2_e(nsect,n1,nout,ninp,c2thresh,
     $                     ffts,c2flag,c2,info)
c
c birrp
c
c multiple coherence estimation on each section by block averaging for remote
c reference data
c
c  input variables:
c     nsect--number of sections in ffts
c     n1--number of output time series to process
c     nout--number of output (i.e., electric field) time series
c     ninp--number of input (i.e., magnetic field)time series
c     c2thresh-coherence threshold
c     ffts--complex array containing nsect section fft's
c           for nout+ninp variables
c  output variables:
c     c2flag-logical vector, .true. if coherence threshold is exceeded
c     c2--array containing nsect/nblk section average coherence
c         estimates for nout output variables
c     info--error flag, 0 for normal return, 1 for singular matrix
c
      include 'parameters.h'
      parameter (nblk=10)
      complex ffts
      logical c2flag
      dimension ffts(nsectm,*),
     $          c2(nsectm/nblk,*),c2flag(*)
      double precision syy,rcond
      double complex sxrx,sxry,sxx,syx,a,sypyp,syyp
      dimension sxrx(ninpm,ninpm),sxry(ninpm),
     $          sxx(ninpm,ninpm),syx(ninpm),
     $          ipvt(ninpm),a(ninpm)
      info=0
      do 50 n=0,nsect-1,nblk
        do 40 m=1,n1
          do 10 i=1,ninp
            sxry(i)=0.
            syx(i)=0.
            do 10 j=1,ninp
              sxx(i,j)=0.
   10         sxrx(i,j)=0.
          syy=0.
          do 20 ii=n+1,n+nblk
            syy=syy+abs(ffts(ii,m))**2
            do 20 i=1,ninp
              sxry(i)=sxry(i)+conjg(ffts(ii,i+nout+ninp))*
     $             ffts(ii,m)
              syx(i)=syx(i)+conjg(ffts(ii,m))*ffts(ii,i+nout)
              do 20 j=1,ninp
                sxx(i,j)=sxx(i,j)+conjg(ffts(ii,i+nout))*
     $                   ffts(ii,j+nout)
   20           sxrx(i,j)=sxrx(i,j)+conjg(ffts(ii,i+nout+ninp))*
     $                 ffts(ii,j+nout)
          call zgeco(sxrx,ninpm,ninp,ipvt,rcond,a)
          if(1.d0+rcond.eq.1.d0)info=1
          job=0
          call zgesl(sxrx,ninpm,ninp,ipvt,sxry,job)
          sypyp=0.
          syyp=0.
          do 30 i=1,ninp
            a(i)=0.
            do 25 j=1,ninp
   25         a(i)=a(i)+sxx(i,j)*sxry(j)
            syyp=syyp+syx(i)*sxry(i)
   30       sypyp=sypyp+conjg(sxry(i))*a(i)
   40     c2(n/nblk+1,m)=abs(syyp)**2/(syy*dreal(sypyp))
   50   continue
      if(c2thresh.eq.0.)return
      do 80 i=1,nsect/nblk
        do 80 nn=1,n1
          if(c2(i,nn).le.c2thresh)c2flag(i)=.false.
   80     continue
      return
      end
      subroutine ccoher1(nsct,ninp,nref,nn,ftsec,h,hd1,wt,gd1,g,
     $                  glo,ghi)
c
c  birrp
c
c  compute complex coherence between measured and predicted output variables
c
c  input variables:
c
c  nsct--number of sections
c  ninp--number of output variables
c  nref--number of input variables
c  nn--index of output variable
c  ftsec--complex array containing nsct ffts
c  h--complex array containing transfer functions between ninp output and
c      nref input variables
c  hd1--complex array of delete one transfer function estimates
c  wt--weight vector
c  gd1--work array of length at least nsct
c
c  output variables
c  g--complex coherence (not squared coherence!)
c  glo--lower 95% confidence limit on coherence magnitude
c  ghi--upper 95% confidence limit on coherence magnitude
      include 'parameters.h'
      complex ftsec,h,hd1,g
      dimension ftsec(nsectm,*),h(ninpm,*),
     $          hd1(nrefm+1,*),wt(*),gd1(*)
      double precision pwr,gd1av,syy,var
      double complex bb,sxx,yps,zt0,t1,sxx1,yp
      dimension bb(nrefm),sxx(nrefm,nrefm),yp(nrefm)
      pwr=0.
      do 10 i=1,nref
        bb(i)=0.
        do 10 j=1,nref
   10     sxx(i,j)=0.
      do 20 ii=1,nsct
        pwr=pwr+(wt(ii)*abs(ftsec(ii,nn)))**2
        do 20 i=1,nref
           bb(i)=bb(i)+wt(ii)*wt(ii)*ftsec(ii,ninp+i)*
     $                 conjg(ftsec(ii,nn))
           do 20 j=1,nref
   20        sxx(i,j)=sxx(i,j)+wt(ii)*wt(ii)*
     $                conjg(ftsec(ii,ninp+i))*
     $                ftsec(ii,ninp+j)
      yps=0.
      zt0=0.
      do 30 i=1,nref
        yp(i)=0.
        do 25 j=1,nref
   25     yp(i)=yp(i)+sxx(i,j)*h(nn,j)
        yps=yps+conjg(h(nn,i))*yp(i)
   30   zt0=zt0+bb(i)*h(nn,i)
      g=zt0/sqrt(pwr*yps)
c  compute jackknifed estimate of coherence 95% confidence interval
      gd1av=0.
      nd=0
      do 50 ii=1,nsct
        if(wt(ii).gt.0.)then
          nd=nd+1
          syy=pwr-(wt(ii)*abs(ftsec(ii,nn)))**2
          zt0=0.
          yps=0.
          do 40 i=1,nref
            t1=bb(i)-wt(ii)*wt(ii)*ftsec(ii,ninp+i)*
     $               conjg(ftsec(ii,nn))
            zt0=zt0+t1*hd1(i,ii)
            yp(i)=0.
            do 35 j=1,nref
              sxx1=sxx(i,j)-wt(ii)*wt(ii)*conjg(ftsec(ii,ninp+i))*
     $             ftsec(ii,ninp+j)
   35         yp(i)=yp(i)+sxx1*hd1(j,ii)
   40       yps=yps+conjg(hd1(i,ii))*yp(i)
            gd=abs(zt0/sqrt(syy*yps))
            gd1(nd)=arctanh(gd)
            gd1av=gd1av+gd1(nd)
        endif
   50   continue
      gd1av=gd1av/nd
      var=0.
      do 60 i=1,nd
   60   var=var+(gd1av-gd1(i))**2
      err=sqrt((nd-1)*var/nd)
      g1=arctanh(abs(g))
      glo=max(0.,tanh1(g1-1.96*err))
      ghi=min(tanh1(g1+1.96*err),1.)
      return
      end
      subroutine ccoher2(nsct,nout,ninp,nn,ftsec,h,hd1,wt,gd1,g,
     $                  glo,ghi)
c
c  birrp
c
c  compute complex coherence between measured and predicted output variables
c
c  input variables:
c
c  nsct--number of sections
c  nout--number of output variables
c  ninp--number of input variables
c  nn--index of output variable
c  ftsec--complex array containing nsct ffts
c  h--complex array containing transfer functions between nout output and
c      ninp input variables
c  hd1--complex array of delete one transfer function estimates
c  wt--weight vector
c  gd1--work array of length at least nsct
c
c  output variables
c  g--complex coherence (not squared coherence!)
c  glo--lower 95% confidence limit on coherence magnitude
c  ghi--upper 95% confidence limit on coherence magnitude
      include 'parameters.h'
      complex ftsec,h,hd1,g
      dimension ftsec(nsectm,*),h(noutm,*),
     $          hd1(nrefm+1,*),wt(*),gd1(*)
      double precision pwr,gd1av,syy,var
      double complex bb,sxx,yps,zt0,t1,sxx1,yp
      dimension bb(ninpm),sxx(ninpm,ninpm),yp(ninpm)
      pwr=0.
      do 10 i=1,ninp
        bb(i)=0.
        do 10 j=1,ninp
   10     sxx(i,j)=0.
      do 20 ii=1,nsct
        pwr=pwr+(wt(ii)*abs(ftsec(ii,nn)))**2
        do 20 i=1,ninp
           bb(i)=bb(i)+wt(ii)*wt(ii)*ftsec(ii,nout+i)*
     $                 conjg(ftsec(ii,nn))
           do 20 j=1,ninp
   20        sxx(i,j)=sxx(i,j)+wt(ii)*wt(ii)*
     $                conjg(ftsec(ii,nout+i))*
     $                ftsec(ii,nout+j)
      yps=0.
      zt0=0.
      do 30 i=1,ninp
        yp(i)=0.
        do 25 j=1,ninp
   25     yp(i)=yp(i)+sxx(i,j)*h(nn,j)
        yps=yps+conjg(h(nn,i))*yp(i)
   30   zt0=zt0+bb(i)*h(nn,i)
      g=zt0/sqrt(pwr*yps)
c  compute jackknifed estimate of coherence 95% confidence interval
      gd1av=0.
      nd=0
      do 50 ii=1,nsct
        if(wt(ii).gt.0.)then
          nd=nd+1
          syy=pwr-(wt(ii)*abs(ftsec(ii,nn)))**2
          zt0=0.
          yps=0.
          do 40 i=1,ninp
            t1=bb(i)-wt(ii)*wt(ii)*ftsec(ii,nout+i)*
     $               conjg(ftsec(ii,nn))
            zt0=zt0+t1*hd1(i,ii)
            yp(i)=0.
            do 35 j=1,ninp
              sxx1=sxx(i,j)-wt(ii)*wt(ii)*conjg(ftsec(ii,nout+i))*
     $             ftsec(ii,nout+j)
   35         yp(i)=yp(i)+sxx1*hd1(j,ii)
   40       yps=yps+conjg(hd1(i,ii))*yp(i)
            gd=abs(zt0/sqrt(syy*yps))
            gd1(nd)=arctanh(gd)
            gd1av=gd1av+gd1(nd)
        endif
   50   continue
      gd1av=gd1av/nd
      var=0.
      do 60 i=1,nd
   60   var=var+(gd1av-gd1(i))**2
      err=sqrt((nd-1)*var/nd)
      g1=arctanh(abs(g))
      if(g1-1.96*err.lt.0.)then
        glo=0.
      else
        glo=tanh1(g1-1.96*err)
      endif
      ghi=min(tanh1(g1+1.96*err),1.)
      return
      end
      real function arctanh(z)
      arctanh=0.5*log((1.+z)/(1.-z))
      return
      end
      real function tanh1(z)
      tanh1=(1.-exp(-2.*z))/(1.+exp(-2.*z))
      return
      end

<file_sep>      subroutine qqout(filnam,period,nsect,nsct,nw,ninp,llo,lhi,
     $                 wt,res,hat)
      include 'parameters.h'
      character*(*) filnam
      logical llo,lhi
      dimension llo(*),lhi(*),wt(*),res(*),hat(*)
      dimension temp(nsectm),xindex(nsectm),qq(nsectm),yindex(nsectm)
      open (unit=40,file=filnam,status='unknown')
      xnsect=nsect
      xnw=nw
      m1=0
      m2=0
      do 10 i=1,nsect
        if(llo(i))m1=m1+1
   10   if(lhi(i))m2=m2+1
c  apportion data thresholded or eliminated as outliers between upper and lower ends of
c  beta distribution
      nray=nsect-nw-m1-m2
      nloh=nray/2
      nhih=nray-nloh
c apportion data thresholded or eliminated as leverage points between upper and lower
c  ends of rayleigh distribution
      nbeta=nsect-nsct+m1+m2
      nlor=nbeta/2
      nhir=nbeta-nlor
      nr=nsct-nw-m1-m2
      var=0.
      do 20 i=1,nsect
        temp(i)=(wt(i)*res(i))**2
   20   var=var+temp(i)
c  scale regression residuals
c  set second moment to 2 as expected for rayleigh-distributed variate
      var=sqrt(2.*xnsect/var)
      do 30 i=1,nsect
        xindex(i)=i
        qq(i)=var*sqrt(temp(i))
	yindex(i)=i
        temp(i)=xnsect*hat(i)/ninp
   30   continue
      call ssort(qq,xindex,nsect,2)
      call ssort(temp,yindex,nsect,2)
      do 40 i=1,nsect
        if((qq(i).gt.0.).and.(temp(i).gt.0.))then
          nq=i
          goto 41
        endif
   40   continue
   41 continue
      ft1=0.
      if(nlor.gt.0)then
        t1=sqrt(-2.*log(1.-(nlor-.5)/xnsect))
        ft1=1.-exp(-t1*t1/2.)
      endif
      ft2=1.
      if((nr.gt.0).or.(nhir.gt.0))then
        t2=sqrt(-2.*log(1.-(xnsect-nhir-nr-.5)/xnsect))
        ft2=1.-exp(-t2*t2/2.)-ft1
      endif
      ft3=0.
      if((m1.gt.0).or.(nloh.gt.0))then
        t3=qbeta((float(m1+nloh)-.5)/xnsect,ninp,nsect-ninp)
        ft3=betai(t3,float(ninp),xnsect-float(ninp))
      endif
      ft4=1.
      if((m2.gt.0).or.(nhih.gt.0))then
        t4=qbeta((float(nsect-m2-nhih)-.5)/xnsect,ninp,nsect-ninp)
        ft4=betai(t4,float(ninp),xnsect-float(ninp))-ft3
      endif
      write(40,999)period,0.,0.,0.,0.,0.
      do 50 i=nq,ifix(0.1*xnw)+nq
        p=(float(i-nq+1)-.5)/xnw
   50   write(40,999)sqrt(-2.*log(1.-ft2*p-ft1)),
     $               qq(i),xindex(i),
     $               xnsect*qbeta(ft4*p+ft3,ninp,nsect-ninp)/ninp,
     $               temp(i),yindex(i)
      do 60 i=ifix(0.1*xnw)+nq+1,ifix(0.9*xnw)+nq,
     $        max(nint(log10(xnw)**1.5),1)
        p=(float(i-nq+1)-.5)/xnw
   60   write(40,999)sqrt(-2.*log(1.-ft2*p-ft1)),
     $               qq(i),xindex(i),
     $               xnsect*qbeta(ft4*p+ft3,ninp,nsect-ninp)/ninp,
     $               temp(i),yindex(i)
      do 70 i=ifix(0.9*xnw)+nq+1,nsect
        p=(float(i-nq+1)-.5)/xnw
   70   write(40,999)sqrt(-2.*log(1.-ft2*p-ft1)),
     $               qq(i),xindex(i),
     $               xnsect*qbeta(ft4*p+ft3,ninp,nsect-ninp)/ninp,
     $               temp(i),yindex(i)
      close (unit=40)
  999 format(1x,6g15.7)
      return
      end
      subroutine diagout(filnam,period,nsect,ninp,
     $                   res,pwro,pwri,wt,hat)
      character*(*) filnam
      dimension res(*),pwro(*),pwri(*),wt(*),
     $          hat(*)
      xnsect=nsect
      open (unit=40,file=filnam,status='unknown')
      respm=0.
      pwrom=0.
      pwrim=0.
      do 10 i=1,nsect
        respm=max(respm,abs(res(i))**2)
        pwrom=max(pwrom,pwro(i))
   10   pwrim=max(pwrim,pwri(i))
      write(40,999)period,respm,pwrom,pwrim
      do 20 i=1,nsect
        if(wt(i).gt.0.)write(40,999)xnsect*hat(i)/ninp,
     $                 abs(res(i))**2/respm,pwro(i)/pwrom,
     $                 pwri(i)/pwrim
   20   continue
      close(unit=40)
  999 format(1x,4g15.7)
      return
      end
<file_sep>FC = ifort
FCFLAGS= -O0 -debug -traceback -check -ftrapuv

TARGETS= clean birrp

OBJSOC= strlen.f diagnostic.f math.f rtpss.f zlinpack.f coherence.f fft.f rarfilt.f utils.f dataft.f filter.f response.f weight.f  birrp.f

all:  $(TARGETS)

clean:$
		rm -f *.o *.mod
		rm -f birrp

birrp:$(OBJSOC)
		$(FC) $(FCFLAGS) -o $@ $(OBJSOC)

# General compile rules

.SUFFIXES: .f .o

.f .o:
	$(FC) $(FCFLAGS) -c -o $@ $<
<file_sep>      subroutine dataft(nsect,jj,nf1,nfinc,nfsect,nfft,noff,
     $                  nfil,nar,deltat,dpss,wsave,rdata,fpar,cpar,
     $                  arf,fft,ffts)
c
c  birrp
c
c  computes fourier transforms of data, corrects for prewhitening
c  and instrument response, and returns selected frequencies
c
c  input variables
c    nsect-number of sections
c    jj-series index in ffts
c    nf1-starting frequency index
c    nfinc-frequency index increment
c    nfsect-number of frequencies per section starting with nf1
c    nfft-length of fft
c    noff-offset between sections
c    nfil-number of filter parameters in fpar if .gt.0 and
c         indicates filter parameters are contained in file cpar if .lt.0
c    nar-length of ar filter less leading 1
c    deltat-data sample interval
c    dpss-double precision vector containing slepian sequence data window
c    wsave-vector containing sinusoids for fft
c    rdata-vector containing data sequence
c    fpar-vector of filter parameters
c    cpar-character string of filter parameters
c    arf-vector of ar prewhitening filter coefficients
c    fft-complex work space of length nfft
c
c  output variables
c    ffts-complex array containing fourier transforms for each section
c         and component at selected frequencies
c
      include 'parameters.h'
      parameter (narm=100,nfilm=47)
      parameter (nserm=noutm+ninpm+nrefm)
      character cpar*(*)
      double precision dpss,darf,pi,tpi,om,ct,st
      complex fft,ffts,ar,fil,filter,t0,t1
      dimension dpss(*),wsave(*),rdata(*),fpar(*),arf(*),
     $          fft(*),ffts(nsectm,nserm,*)
      dimension ffreq(nfilm),ffreq1(nfilm),rfpar(nfilm),
     $          afpar(nfilm),s(2*nfilm,6),rbrk(2*nfilm),
     $          rcoef(4,2*nfilm),abrk(2*nfilm),acoef(4,2*nfilm)
      dimension darf(narm+1)
      parameter (pi=3.141592653589793d0,tpi=2.d0*pi)
      write(*,*)cpar
      xnfft=nfft
      if(nar.ne.0)then
        darf(1)=1.d0
        do 1 ii=2,nar+1
    1     darf(ii)=arf(ii-1)
      endif
      if(nfil.lt.0)then
        call strlen(cpar,i1,i2)
        open(unit=10,file=cpar(i1:i2),status='old')
        read(10,*)scal
        do 5 i=1,nfilm
    5     read(10,*,end=6)ffreq(i),rfpar(i),afpar(i)
    6   nfi=i-1
        close(unit=10)
        do 7 i=1,nfi
    7     ffreq1(i)=ffreq(i)
        call ssort(ffreq,rfpar,nfi,2)

        call tautsp(ffreq,rfpar,nfi,5.5,s,rbrk,rcoef,
     $              lr,kr,iflag)

        call ssort(ffreq1,afpar,nfi,2)
        call tautsp(ffreq,afpar,nfi,5.5,s,abrk,acoef,
     $              la,ka,iflag)
      endif
      k=1
      nn=nsect/2
      do 30 n=1,2*nn,2
        do 10 i=1,nfft
          fft(i)=dpss(i)*cmplx(rdata(k),rdata(k+noff))
   10     k=k+1
        call cfftf(nfft,fft,wsave)
        kk=1
        do 20 i=nf1,nf1+(nfsect-1)*nfinc,nfinc
          if(nfil.gt.0)then
            fil=filter(float(i)/(deltat*xnfft),fpar,nfil+1)
          elseif(nfil.lt.0)then
            fr=float(i)/(deltat*xnfft)
            fil=cmplx(ppvalu(rbrk,rcoef,lr,kr,fr,0),
     $                ppvalu(abrk,acoef,la,ka,fr,0))
            if(nfil.eq.-2)fil=1./fil
            fil=scal*fil
          else
            fil=1.
          endif
          if(nar.ne.0)then
            om=tpi*dfloat(i)/dble(xnfft)
            call sft(darf,nar+1,om,ct,st)
            ar=cmplx(ct,st)
          else
            ar=1.
          endif
          t0=fft(i+1)
          t1=fft(nfft-i+1)
          ffts(n,jj,kk)=0.5*fil*(t0+conjg(t1))/ar
          ffts(n+1,jj,kk)=-cmplx(0.,0.5)*fil*(t0-
     $                     conjg(t1))/ar
          kk=kk+1
   20     continue
   30   k=k-nfft+2*noff
      if(mod(nsect,2).ne.0)then
        do 40 i=1,nfft
          fft(i)=dpss(i)*rdata(k)
   40     k=k+1
        call cfftf(nfft,fft,wsave)
        kk=1
        do 60 i=nf1,nf1+(nfsect-1)*nfinc,nfinc
          if(nfil.gt.0)then
            fil=filter(float(i)/(deltat*xnfft),fpar,nfil)
          elseif(nfil.lt.0)then
            fr=float(i)/(deltat*xnfft)
            fil=cmplx(ppvalu(rbrk,rcoef,lr,kr,fr,0),
     $                ppvalu(abrk,acoef,la,ka,fr,0))
          else
            fil=1.
          endif
          if(nar.ne.0)then
            om=tpi*dfloat(i)/dble(xnfft)
            call sft(darf,nar+1,om,ct,st)
            ar=cmplx(ct,st)
          else
            ar=1.
          endif
          ffts(nsect,jj,kk)=fil*fft(i+1)/ar
          kk=kk+1
   60     continue
      endif
      return
      end
      subroutine rotate(nsect,theta1,theta2,phi,fftx,ffty)
c
c  birrp
c
c  rotate ffts to new coordinate system
c
c  input variables:
c
c  nsect--number of sections
c  theta1--angle of first component pos cw wrt geomagnetic north
c  theta2--angle of second component pos cw wrt geomagnetic north
c  phi--pos cw rotation angle of geomagnetic coordinate system
c  fftx--complex array containing nsect section fft's for
c        x component (overwritten on return)
c  ffty--complex array containing nsect section fft's for
c        y component (overwritten on return)
c
c  output variables:
c
c  fftx--complex array containing nsect section fft's for x component
c  ffty--complex array containing nsect section fft's for y component
c
c  if original data are collected in orthogonal coordinate
c  system, set theta1=0, theta2=90
c
      complex fftx,ffty,t0
      dimension fftx(*),ffty(*)
      parameter (pi=3.141592653589793,rad=pi/180.)
      if(theta1.eq.0.)then
        spt1=sin(rad*phi)
        cpt1=cos(rad*phi)
      else
        spt1=sin(rad*(phi-theta1))
        cpt1=cos(rad*(phi-theta1))
      endif
      if(theta2.eq.90.)then
        spt2=-cos(rad*phi)
        cpt2=sin(rad*phi)
      else
        spt2=sin(rad*(phi-theta2))
        cpt2=cos(rad*(phi-theta2))
      endif
      st2t1=sin(rad*(theta2-theta1))
      do 10 i=1,nsect
        t0=(-fftx(i)*cpt2+ffty(i)*cpt1)/st2t1
        fftx(i)=(-fftx(i)*spt2+ffty(i)*spt1)/st2t1
 10     ffty(i)=t0
      return
      end
<file_sep>      subroutine zgeco(a,lda,n,ipvt,rcond,z)
c      integer lda,n,ipvt(*)
c      complex*16 a(lda,*),z(*)
      integer lda,n,ipvt(n)
      complex*16 a(lda,n),z(n)
      double precision rcond
c
c     zgeco factors a complex*16 matrix by gaussian elimination
c     and estimates the condition of the matrix.
c
c     if  rcond  is not needed, zgefa is slightly faster.
c     to solve  a*x = b , follow zgeco by zgesl.
c     to compute  inverse(a)*c , follow zgeco by zgesl.
c     to compute  determinant(a) , follow zgeco by zgedi.
c     to compute  inverse(a) , follow zgeco by zgedi.
c
c     on entry
c
c        a       complex*16(lda, n)
c                the matrix to be factored.
c
c        lda     integer
c                the leading dimension of the array  a .
c
c        n       integer
c                the order of the matrix  a .
c
c     on return
c
c        a       an upper triangular matrix and the multipliers
c                which were used to obtain it.
c                the factorization can be written  a = l*u  where
c                l  is a product of permutation and unit lower
c                triangular matrices and  u  is upper triangular.
c
c        ipvt    integer(n)
c                an integer vector of pivot indices.
c
c        rcond   double precision
c                an estimate of the reciprocal condition of  a .
c                for the system  a*x = b , relative perturbations
c                in  a  and  b  of size  epsilon  may cause
c                relative perturbations in  x  of size  epsilon/rcond .
c                if  rcond  is so small that the logical expression
c                           1.0 + rcond .eq. 1.0
c                is true, then  a  may be singular to working
c                precision.  in particular,  rcond  is zero  if
c                exact singularity is detected or the estimate
c                underflows.
c
c        z       complex*16(n)
c                a work vector whose contents are usually unimportant.
c                if  a  is close to a singular matrix, then  z  is
c                an approximate null vector in the sense that
c                norm(a*z) = rcond*norm(a)*norm(z) .
c
c     linpack. this version dated 08/14/78 .
c     <NAME>, university of new mexico, argonne national lab.
c
c     subroutines and functions
c
c     linpack zgefa
c     blas zaxpy,zdotc,zdscal,dzasum
c     fortran dabs,dmax1,dcmplx,dconjg
c
c     internal variables
c
      complex*16 zdotc,ek,t,wk,wkm
      double precision anorm,s,dzasum,sm,ynorm
      integer info,j,k,kb,kp1,l
c
      complex*16 zdum,zdum1,zdum2,csign1
      double precision cabs1
c      double precision dreal,dimag
c      complex*16 zdumr,zdumi
c      dreal(zdumr) = zdumr
c      dimag(zdumi) = (0.0d0,-1.0d0)*zdumi
      cabs1(zdum) = dabs(dreal(zdum)) + dabs(dimag(zdum))
      csign1(zdum1,zdum2) = cabs1(zdum1)*(zdum2/cabs1(zdum2))
c
c     compute 1-norm of a
c
      anorm = 0.0d0
      do 10 j = 1, n
         anorm = dmax1(anorm,dzasum(n,a(1,j),1))
   10 continue
c
c     factor
c
      call zgefa(a,lda,n,ipvt,info)
c
c     rcond = 1/(norm(a)*(estimate of norm(inverse(a)))) .
c     estimate = norm(z)/norm(y) where  a*z = y  and  ctrans(a)*y = e .
c     ctrans(a)  is the conjugate transpose of a .
c     the components of  e  are chosen to cause maximum local
c     growth in the elements of w  where  ctrans(u)*w = e .
c     the vectors are frequently rescaled to avoid overflow.
c
c     solve ctrans(u)*w = e
c
      ek = (1.0d0,0.0d0)
      do 20 j = 1, n
         z(j) = (0.0d0,0.0d0)
   20 continue
      do 100 k = 1, n
         if (cabs1(z(k)) .ne. 0.0d0) ek = csign1(ek,-z(k))
         if (cabs1(ek-z(k)) .le. cabs1(a(k,k))) go to 30
            s = cabs1(a(k,k))/cabs1(ek-z(k))
            call zdscal(n,s,z,1)
            ek = dcmplx(s,0.0d0)*ek
   30    continue
         wk = ek - z(k)
         wkm = -ek - z(k)
         s = cabs1(wk)
         sm = cabs1(wkm)
         if (cabs1(a(k,k)) .eq. 0.0d0) go to 40
            wk = wk/dconjg(a(k,k))
            wkm = wkm/dconjg(a(k,k))
         go to 50
   40    continue
            wk = (1.0d0,0.0d0)
            wkm = (1.0d0,0.0d0)
   50    continue
         kp1 = k + 1
         if (kp1 .gt. n) go to 90
            do 60 j = kp1, n
               sm = sm + cabs1(z(j)+wkm*dconjg(a(k,j)))
               z(j) = z(j) + wk*dconjg(a(k,j))
               s = s + cabs1(z(j))
   60       continue
            if (s .ge. sm) go to 80
               t = wkm - wk
               wk = wkm
               do 70 j = kp1, n
                  z(j) = z(j) + t*dconjg(a(k,j))
   70          continue
   80       continue
   90    continue
         z(k) = wk
  100 continue
      s = 1.0d0/dzasum(n,z,1)
      call zdscal(n,s,z,1)
c
c     solve ctrans(l)*y = w
c
      do 120 kb = 1, n
         k = n + 1 - kb
         if (k .lt. n) z(k) = z(k) + zdotc(n-k,a(k+1,k),1,z(k+1),1)
         if (cabs1(z(k)) .le. 1.0d0) go to 110
            s = 1.0d0/cabs1(z(k))
            call zdscal(n,s,z,1)
  110    continue
         l = ipvt(k)
         t = z(l)
         z(l) = z(k)
         z(k) = t
  120 continue
      s = 1.0d0/dzasum(n,z,1)
      call zdscal(n,s,z,1)
c
      ynorm = 1.0d0
c
c     solve l*v = y
c
      do 140 k = 1, n
         l = ipvt(k)
         t = z(l)
         z(l) = z(k)
         z(k) = t
         if (k .lt. n) call zaxpy(n-k,t,a(k+1,k),1,z(k+1),1)
         if (cabs1(z(k)) .le. 1.0d0) go to 130
            s = 1.0d0/cabs1(z(k))
            call zdscal(n,s,z,1)
            ynorm = s*ynorm
  130    continue
  140 continue
      s = 1.0d0/dzasum(n,z,1)
      call zdscal(n,s,z,1)
      ynorm = s*ynorm
c
c     solve  u*z = v
c
      do 160 kb = 1, n
         k = n + 1 - kb
         if (cabs1(z(k)) .le. cabs1(a(k,k))) go to 150
            s = cabs1(a(k,k))/cabs1(z(k))
            call zdscal(n,s,z,1)
            ynorm = s*ynorm
  150    continue
         if (cabs1(a(k,k)) .ne. 0.0d0) z(k) = z(k)/a(k,k)
         if (cabs1(a(k,k)) .eq. 0.0d0) z(k) = (1.0d0,0.0d0)
         t = -z(k)
         call zaxpy(k-1,t,a(1,k),1,z(1),1)
  160 continue
c     make znorm = 1.0
      s = 1.0d0/dzasum(n,z,1)
      call zdscal(n,s,z,1)
      ynorm = s*ynorm
c
      if (anorm .ne. 0.0d0) rcond = ynorm/anorm
      if (anorm .eq. 0.0d0) rcond = 0.0d0
      return
      end
      subroutine zgefa(a,lda,n,ipvt,info)
c      integer lda,n,ipvt(*),info
c      complex*16 a(lda,*)
      integer lda,n,ipvt(n),info
      complex*16 a(lda,n)
c
c     zgefa factors a complex*16 matrix by gaussian elimination.
c
c     zgefa is usually called by zgeco, but it can be called
c     directly with a saving in time if  rcond  is not needed.
c     (time for zgeco) = (1 + 9/n)*(time for zgefa) .
c
c     on entry
c
c        a       complex*16(lda, n)
c                the matrix to be factored.
c
c        lda     integer
c                the leading dimension of the array  a .
c
c        n       integer
c                the order of the matrix  a .
c
c     on return
c
c        a       an upper triangular matrix and the multipliers
c                which were used to obtain it.
c                the factorization can be written  a = l*u  where
c                l  is a product of permutation and unit lower
c                triangular matrices and  u  is upper triangular.
c
c        ipvt    integer(n)
c                an integer vector of pivot indices.
c
c        info    integer
c                = 0  normal value.
c                = k  if  u(k,k) .eq. 0.0 .  this is not an error
c                     condition for this subroutine, but it does
c                     indicate that zgesl or zgedi will divide by zero
c                     if called.  use  rcond  in zgeco for a reliable
c                     indication of singularity.
c
c     linpack. this version dated 08/14/78 .
c     <NAME>, university of new mexico, argonne national lab.
c
c     subroutines and functions
c
c     blas zaxpy,zscal,izamax
c     fortran dabs
c
c     internal variables
c
      complex*16 t
      integer izamax,j,k,kp1,l,nm1
c
      complex*16 zdum
      double precision cabs1
c      double precision dreal,dimag
c      complex*16 zdumr,zdumi
c      dreal(zdumr) = zdumr
c      dimag(zdumi) = (0.0d0,-1.0d0)*zdumi
      cabs1(zdum) = dabs(dreal(zdum)) + dabs(dimag(zdum))
c
c     gaussian elimination with partial pivoting
c
      info = 0
      nm1 = n - 1
      if (nm1 .lt. 1) go to 70
      do 60 k = 1, nm1
         kp1 = k + 1
c
c        find l = pivot index
c
         l = izamax(n-k+1,a(k,k),1) + k - 1
         ipvt(k) = l
c
c        zero pivot implies this column already triangularized
c
         if (cabs1(a(l,k)) .eq. 0.0d0) go to 40
c
c           interchange if necessary
c
            if (l .eq. k) go to 10
               t = a(l,k)
               a(l,k) = a(k,k)
               a(k,k) = t
   10       continue
c
c           compute multipliers
c
            t = -(1.0d0,0.0d0)/a(k,k)
            call zscal(n-k,t,a(k+1,k),1)
c
c           row elimination with column indexing
c
            do 30 j = kp1, n
               t = a(l,j)
               if (l .eq. k) go to 20
                  a(l,j) = a(k,j)
                  a(k,j) = t
   20          continue
               call zaxpy(n-k,t,a(k+1,k),1,a(k+1,j),1)
   30       continue
         go to 50
   40    continue
            info = k
   50    continue
   60 continue
   70 continue
      ipvt(n) = n
      if (cabs1(a(n,n)) .eq. 0.0d0) info = n
      return
      end
      subroutine zgesl(a,lda,n,ipvt,b,job)
c      integer lda,n,ipvt(*),job
c      complex*16 a(lda,*),b(*)
      integer lda,n,ipvt(n),job
      complex*16 a(lda,n),b(n)
c
c     zgesl solves the complex*16 system
c     a * x = b  or  ctrans(a) * x = b
c     using the factors computed by zgeco or zgefa.
c
c     on entry
c
c        a       complex*16(lda, n)
c                the output from zgeco or zgefa.
c
c        lda     integer
c                the leading dimension of the array  a .
c
c        n       integer
c                the order of the matrix  a .
c
c        ipvt    integer(n)
c                the pivot vector from zgeco or zgefa.
c
c        b       complex*16(n)
c                the right hand side vector.
c
c        job     integer
c                = 0         to solve  a*x = b ,
c                = nonzero   to solve  ctrans(a)*x = b  where
c                            ctrans(a)  is the conjugate transpose.
c
c     on return
c
c        b       the solution vector  x .
c
c     error condition
c
c        a division by zero will occur if the input factor contains a
c        zero on the diagonal.  technically this indicates singularity
c        but it is often caused by improper arguments or improper
c        setting of lda .  it will not occur if the subroutines are
c        called correctly and if zgeco has set rcond .gt. 0.0
c        or zgefa has set info .eq. 0 .
c
c     to compute  inverse(a) * c  where  c  is a matrix
c     with  p  columns
c           call zgeco(a,lda,n,ipvt,rcond,z)
c           if (rcond is too small) go to ...
c           do 10 j = 1, p
c              call zgesl(a,lda,n,ipvt,c(1,j),0)
c        10 continue
c
c     linpack. this version dated 08/14/78 .
c     <NAME>, university of new mexico, argonne national lab.
c
c     subroutines and functions
c
c     blas zaxpy,zdotc
c     fortran dconjg
c
c     internal variables
c
      complex*16 zdotc,t
      integer k,kb,l,nm1
c      double precision dreal,dimag
c      complex*16 zdumr,zdumi
c      dreal(zdumr) = zdumr
c      dimag(zdumi) = (0.0d0,-1.0d0)*zdumi
c
      nm1 = n - 1
      if (job .ne. 0) go to 50
c
c        job = 0 , solve  a * x = b
c        first solve  l*y = b
c
         if (nm1 .lt. 1) go to 30
         do 20 k = 1, nm1
            l = ipvt(k)
            t = b(l)
            if (l .eq. k) go to 10
               b(l) = b(k)
               b(k) = t
   10       continue
            call zaxpy(n-k,t,a(k+1,k),1,b(k+1),1)
   20    continue
   30    continue
c
c        now solve  u*x = y
c
         do 40 kb = 1, n
            k = n + 1 - kb
            b(k) = b(k)/a(k,k)
            t = -b(k)
            call zaxpy(k-1,t,a(1,k),1,b(1),1)
   40    continue
      go to 100
   50 continue
c
c        job = nonzero, solve  ctrans(a) * x = b
c        first solve  ctrans(u)*y = b
c
         do 60 k = 1, n
            t = zdotc(k-1,a(1,k),1,b(1),1)
            b(k) = (b(k) - t)/dconjg(a(k,k))
   60    continue
c
c        now solve ctrans(l)*x = y
c
         if (nm1 .lt. 1) go to 90
         do 80 kb = 1, nm1
            k = n - kb
            b(k) = b(k) + zdotc(n-k,a(k+1,k),1,b(k+1),1)
            l = ipvt(k)
            if (l .eq. k) go to 70
               t = b(l)
               b(l) = b(k)
               b(k) = t
   70       continue
   80    continue
   90    continue
  100 continue
      return
      end
      subroutine zhidi(a,lda,n,kpvt,det,inert,work,job)
      integer lda,n,job
c      complex*16 a(lda,*),work(*)
      complex*16 a(lda,n),work(n)
      double precision det(2)
c      integer kpvt(1),inert(3)
      integer kpvt(n),inert(3)
c
c     zhidi computes the determinant, inertia and inverse
c     of a complex*16 hermitian matrix using the factors from zhifa.
c
c     on entry
c
c        a       complex*16(lda,n)
c                the output from zhifa.
c
c        lda     integer
c                the leading dimension of the array a.
c
c        n       integer
c                the order of the matrix a.
c
c        kpvt    integer(n)
c                the pivot vector from zhifa.
c
c        work    complex*16(n)
c                work vector.  contents destroyed.
c
c        job     integer
c                job has the decimal expansion  abc  where
c                   if  c .ne. 0, the inverse is computed,
c                   if  b .ne. 0, the determinant is computed,
c                   if  a .ne. 0, the inertia is computed.
c
c                for example, job = 111  gives all three.
c
c     on return
c
c        variables not requested by job are not used.
c
c        a      contains the upper triangle of the inverse of
c               the original matrix.  the strict lower triangle
c               is never referenced.
c
c        det    double precision(2)
c               determinant of original matrix.
c               determinant = det(1) * 10.0**det(2)
c               with 1.0 .le. dabs(det(1)) .lt. 10.0
c               or det(1) = 0.0.
c
c        inert  integer(3)
c               the inertia of the original matrix.
c               inert(1)  =  number of positive eigenvalues.
c               inert(2)  =  number of negative eigenvalues.
c               inert(3)  =  number of zero eigenvalues.
c
c     error condition
c
c        a division by zero may occur if the inverse is requested
c        and  zhico  has set rcond .eq. 0.0
c        or  zhifa  has set  info .ne. 0 .
c
c     linpack. this version dated 08/14/78 .
c     <NAME>, univ. calif. san diego, argonne nat. lab
c
c     subroutines and functions
c
c     blas zaxpy,zcopy,zdotc,zswap
c     fortran dabs,cdabs,dcmplx,dconjg,iabs,mod
c
c     internal variables.
c
      complex*16 akkp1,zdotc,temp
      double precision ten,d,t,ak,akp1
      integer j,jb,k,km1,ks,kstep
      logical noinv,nodet,noert
c      double precision dreal
c      complex*16 zdumr
c      dreal(zdumr) = zdumr
c
      noinv = mod(job,10) .eq. 0
      nodet = mod(job,100)/10 .eq. 0
      noert = mod(job,1000)/100 .eq. 0
c
      if (nodet .and. noert) go to 140
         if (noert) go to 10
            inert(1) = 0
            inert(2) = 0
            inert(3) = 0
   10    continue
         if (nodet) go to 20
            det(1) = 1.0d0
            det(2) = 0.0d0
            ten = 10.0d0
   20    continue
         t = 0.0d0
         do 130 k = 1, n
            d = dreal(a(k,k))
c
c           check if 1 by 1
c
            if (kpvt(k) .gt. 0) go to 50
c
c              2 by 2 block
c              use det (d  s)  =  (d/t * c - t) * t  ,  t = cdabs(s)
c                      (s  c)
c              to avoid underflow/overflow troubles.
c              take two passes through scaling.  use  t  for flag.
c
               if (t .ne. 0.0d0) go to 30
                  t = cdabs(a(k,k+1))
                  d = (d/t)*dreal(a(k+1,k+1)) - t
               go to 40
   30          continue
                  d = t
                  t = 0.0d0
   40          continue
   50       continue
c
            if (noert) go to 60
               if (d .gt. 0.0d0) inert(1) = inert(1) + 1
               if (d .lt. 0.0d0) inert(2) = inert(2) + 1
               if (d .eq. 0.0d0) inert(3) = inert(3) + 1
   60       continue
c
            if (nodet) go to 120
               det(1) = d*det(1)
               if (det(1) .eq. 0.0d0) go to 110
   70             if (dabs(det(1)) .ge. 1.0d0) go to 80
                     det(1) = ten*det(1)
                     det(2) = det(2) - 1.0d0
                  go to 70
   80             continue
   90             if (dabs(det(1)) .lt. ten) go to 100
                     det(1) = det(1)/ten
                     det(2) = det(2) + 1.0d0
                  go to 90
  100             continue
  110          continue
  120       continue
  130    continue
  140 continue
c
c     compute inverse(a)
c
      if (noinv) go to 270
         k = 1
  150    if (k .gt. n) go to 260
            km1 = k - 1
            if (kpvt(k) .lt. 0) go to 180
c
c              1 by 1
c
               a(k,k) = dcmplx(1.0d0/dreal(a(k,k)),0.0d0)
               if (km1 .lt. 1) go to 170
                  call zcopy(km1,a(1,k),1,work,1)
                  do 160 j = 1, km1
                     a(j,k) = zdotc(j,a(1,j),1,work,1)
                     call zaxpy(j-1,work(j),a(1,j),1,a(1,k),1)
  160             continue
                  a(k,k) = a(k,k)
     *                     + dcmplx(dreal(zdotc(km1,work,1,a(1,k),1)),
     *                              0.0d0)
  170          continue
               kstep = 1
            go to 220
  180       continue
c
c              2 by 2
c
               t = cdabs(a(k,k+1))
               ak = dreal(a(k,k))/t
               akp1 = dreal(a(k+1,k+1))/t
               akkp1 = a(k,k+1)/t
               d = t*(ak*akp1 - 1.0d0)
               a(k,k) = dcmplx(akp1/d,0.0d0)
               a(k+1,k+1) = dcmplx(ak/d,0.0d0)
               a(k,k+1) = -akkp1/d
               if (km1 .lt. 1) go to 210
                  call zcopy(km1,a(1,k+1),1,work,1)
                  do 190 j = 1, km1
                     a(j,k+1) = zdotc(j,a(1,j),1,work,1)
                     call zaxpy(j-1,work(j),a(1,j),1,a(1,k+1),1)
  190             continue
                  a(k+1,k+1) = a(k+1,k+1)
     *                         + dcmplx(dreal(zdotc(km1,work,1,
     *                                              a(1,k+1),1)),0.0d0)
                  a(k,k+1) = a(k,k+1) + zdotc(km1,a(1,k),1,a(1,k+1),1)
                  call zcopy(km1,a(1,k),1,work,1)
                  do 200 j = 1, km1
                     a(j,k) = zdotc(j,a(1,j),1,work,1)
                     call zaxpy(j-1,work(j),a(1,j),1,a(1,k),1)
  200             continue
                  a(k,k) = a(k,k)
     *                     + dcmplx(dreal(zdotc(km1,work,1,a(1,k),1)),
     *                              0.0d0)
  210          continue
               kstep = 2
  220       continue
c
c           swap
c
            ks = iabs(kpvt(k))
            if (ks .eq. k) go to 250
               call zswap(ks,a(1,ks),1,a(1,k),1)
               do 230 jb = ks, k
                  j = k + ks - jb
                  temp = dconjg(a(j,k))
                  a(j,k) = dconjg(a(ks,j))
                  a(ks,j) = temp
  230          continue
               if (kstep .eq. 1) go to 240
                  temp = a(ks,k+1)
                  a(ks,k+1) = a(k,k+1)
                  a(k,k+1) = temp
  240          continue
  250       continue
            k = k + kstep
         go to 150
  260    continue
  270 continue
      return
      end
      subroutine zhifa(a,lda,n,kpvt,info)
c      integer lda,n,kpvt(*),info
c      complex*16 a(lda,*)
      integer lda,n,kpvt(n),info
      complex*16 a(lda,n)
c
c     zhifa factors a complex*16 hermitian matrix by elimination
c     with symmetric pivoting.
c
c     to solve  a*x = b , follow zhifa by zhisl.
c     to compute  inverse(a)*c , follow zhifa by zhisl.
c     to compute  determinant(a) , follow zhifa by zhidi.
c     to compute  inertia(a) , follow zhifa by zhidi.
c     to compute  inverse(a) , follow zhifa by zhidi.
c
c     on entry
c
c        a       complex*16(lda,n)
c                the hermitian matrix to be factored.
c                only the diagonal and upper triangle are used.
c
c        lda     integer
c                the leading dimension of the array  a .
c
c        n       integer
c                the order of the matrix  a .
c
c     on return
c
c        a       a block diagonal matrix and the multipliers which
c                were used to obtain it.
c                the factorization can be written  a = u*d*ctrans(u)
c                where  u  is a product of permutation and unit
c                upper triangular matrices , ctrans(u) is the
c                conjugate transpose of  u , and  d  is block diagonal
c                with 1 by 1 and 2 by 2 blocks.
c
c        kpvt    integer(n)
c                an integer vector of pivot indices.
c
c        info    integer
c                = 0  normal value.
c                = k  if the k-th pivot block is singular. this is
c                     not an error condition for this subroutine,
c                     but it does indicate that zhisl or zhidi may
c                     divide by zero if called.
c
c     linpack. this version dated 08/14/78 .
c     <NAME>, univ. calif. san diego, argonne nat. lab.
c
c     subroutines and functions
c
c     blas zaxpy,zswap,izamax
c     fortran dabs,dmax1,dcmplx,dconjg,dsqrt
c
c     internal variables
c
      complex*16 ak,akm1,bk,bkm1,denom,mulk,mulkm1,t
      double precision absakk,alpha,colmax,rowmax
      integer imax,imaxp1,j,jj,jmax,k,km1,km2,kstep,izamax
      logical swap
c
      complex*16 zdum
      double precision cabs1
c      double precision dreal,dimag
c      complex*16 zdumr,zdumi
c      dreal(zdumr) = zdumr
c      dimag(zdumi) = (0.0d0,-1.0d0)*zdumi
      cabs1(zdum) = dabs(dreal(zdum)) + dabs(dimag(zdum))
c
c     initialize
c
c     alpha is used in choosing pivot block size.
      alpha = (1.0d0 + dsqrt(17.0d0))/8.0d0
c
      info = 0
c
c     main loop on k, which goes from n to 1.
c
      k = n
   10 continue
c
c        leave the loop if k=0 or k=1.
c
c     ...exit
         if (k .eq. 0) go to 200
         if (k .gt. 1) go to 20
            kpvt(1) = 1
            if (cabs1(a(1,1)) .eq. 0.0d0) info = 1
c     ......exit
            go to 200
   20    continue
c
c        this section of code determines the kind of
c        elimination to be performed.  when it is completed,
c        kstep will be set to the size of the pivot block, and
c        swap will be set to .true. if an interchange is
c        required.
c
         km1 = k - 1
         absakk = cabs1(a(k,k))
c
c        determine the largest off-diagonal element in
c        column k.
c
         imax = izamax(k-1,a(1,k),1)
         colmax = cabs1(a(imax,k))
         if (absakk .lt. alpha*colmax) go to 30
            kstep = 1
            swap = .false.
         go to 90
   30    continue
c
c           determine the largest off-diagonal element in
c           row imax.
c
            rowmax = 0.0d0
            imaxp1 = imax + 1
            do 40 j = imaxp1, k
               rowmax = dmax1(rowmax,cabs1(a(imax,j)))
   40       continue
            if (imax .eq. 1) go to 50
               jmax = izamax(imax-1,a(1,imax),1)
               rowmax = dmax1(rowmax,cabs1(a(jmax,imax)))
   50       continue
            if (cabs1(a(imax,imax)) .lt. alpha*rowmax) go to 60
               kstep = 1
               swap = .true.
            go to 80
   60       continue
            if (absakk .lt. alpha*colmax*(colmax/rowmax)) go to 70
               kstep = 1
               swap = .false.
            go to 80
   70       continue
               kstep = 2
               swap = imax .ne. km1
   80       continue
   90    continue
         if (dmax1(absakk,colmax) .ne. 0.0d0) go to 100
c
c           column k is zero.  set info and iterate the loop.
c
            kpvt(k) = k
            info = k
         go to 190
  100    continue
         if (kstep .eq. 2) go to 140
c
c           1 x 1 pivot block.
c
            if (.not.swap) go to 120
c
c              perform an interchange.
c
               call zswap(imax,a(1,imax),1,a(1,k),1)
               do 110 jj = imax, k
                  j = k + imax - jj
                  t = dconjg(a(j,k))
                  a(j,k) = dconjg(a(imax,j))
                  a(imax,j) = t
  110          continue
  120       continue
c
c           perform the elimination.
c
            do 130 jj = 1, km1
               j = k - jj
               mulk = -a(j,k)/a(k,k)
               t = dconjg(mulk)
               call zaxpy(j,t,a(1,k),1,a(1,j),1)
               a(j,j) = dcmplx(dreal(a(j,j)),0.0d0)
               a(j,k) = mulk
  130       continue
c
c           set the pivot array.
c
            kpvt(k) = k
            if (swap) kpvt(k) = imax
         go to 190
  140    continue
c
c           2 x 2 pivot block.
c
            if (.not.swap) go to 160
c
c              perform an interchange.
c
               call zswap(imax,a(1,imax),1,a(1,k-1),1)
               do 150 jj = imax, km1
                  j = km1 + imax - jj
                  t = dconjg(a(j,k-1))
                  a(j,k-1) = dconjg(a(imax,j))
                  a(imax,j) = t
  150          continue
               t = a(k-1,k)
               a(k-1,k) = a(imax,k)
               a(imax,k) = t
  160       continue
c
c           perform the elimination.
c
            km2 = k - 2
            if (km2 .eq. 0) go to 180
               ak = a(k,k)/a(k-1,k)
               akm1 = a(k-1,k-1)/dconjg(a(k-1,k))
               denom = 1.0d0 - ak*akm1
               do 170 jj = 1, km2
                  j = km1 - jj
                  bk = a(j,k)/a(k-1,k)
                  bkm1 = a(j,k-1)/dconjg(a(k-1,k))
                  mulk = (akm1*bk - bkm1)/denom
                  mulkm1 = (ak*bkm1 - bk)/denom
                  t = dconjg(mulk)
                  call zaxpy(j,t,a(1,k),1,a(1,j),1)
                  t = dconjg(mulkm1)
                  call zaxpy(j,t,a(1,k-1),1,a(1,j),1)
                  a(j,k) = mulk
                  a(j,k-1) = mulkm1
                  a(j,j) = dcmplx(dreal(a(j,j)),0.0d0)
  170          continue
  180       continue
c
c           set the pivot array.
c
            kpvt(k) = 1 - k
            if (swap) kpvt(k) = -imax
            kpvt(k-1) = kpvt(k)
  190    continue
         k = k - kstep
      go to 10
  200 continue
      return
      end
      double precision function dcabs1(z)
      double complex z,zz
      double precision t(2)
      equivalence (zz,t(1))
      zz = z
      dcabs1 = dabs(t(1)) + dabs(t(2))
      return
      end
      double precision function dzasum(n,zx,incx)
c
c     takes the sum of the absolute values.
c     <NAME>, 3/11/78.
c
c      double complex zx(*)
      double complex zx(n)
      double precision stemp,dcabs1
c
      dzasum = 0.0d0
      stemp = 0.0d0
      if(n.le.0)return
      if(incx.eq.1)go to 20
c
c        code for increments not equal to 1
c
      ix = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      do 10 i = 1,n
        stemp = stemp + dcabs1(zx(ix))
        ix = ix + incx
   10 continue
      dzasum = stemp
      return
c
c        code for increments equal to 1
c
   20 do 30 i = 1,n
        stemp = stemp + dcabs1(zx(i))
   30 continue
      dzasum = stemp
      return
      end
      integer function izamax(n,zx,incx)
c
c     finds the index of element having max. absolute value.
c     <NAME>, 3/11/78.
c
c      double complex zx(*)
      double complex zx(n)
      double precision smax
      double precision dcabs1
c
      izamax = 1
      if(n.le.1)return
      if(incx.eq.1)go to 20
c
c        code for increments not equal to 1
c
      ix = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      smax = dcabs1(zx(1))
      ix = ix + incx
      do 10 i = 2,n
         if(dcabs1(zx(ix)).le.smax) go to 5
         izamax = ix
         smax = dcabs1(zx(ix))
    5    ix = ix + incx
   10 continue
      return
c
c        code for increments equal to 1
c
   20 smax = dcabs1(zx(1))
      do 30 i = 2,n
         if(dcabs1(zx(i)).le.smax) go to 30
         izamax = i
         smax = dcabs1(zx(i))
   30 continue
      return
      end
      subroutine zaxpy(n,za,zx,incx,zy,incy)
c
c     constant times a vector plus a vector.
c     <NAME>, 3/11/78.
c
c      double complex zx(*),zy(*),za
      double complex zx(n),zy(n),za
      double precision dcabs1
      if(n.le.0)return
      if (dcabs1(za) .eq. 0.0d0) return
      if (incx.eq.1.and.incy.eq.1)go to 20
c
c        code for unequal increments or equal increments
c          not equal to 1
c
      ix = 1
      iy = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      if(incy.lt.0)iy = (-n+1)*incy + 1
      do 10 i = 1,n
        zy(iy) = zy(iy) + za*zx(ix)
        ix = ix + incx
        iy = iy + incy
   10 continue
      return
c
c        code for both increments equal to 1
c
   20 do 30 i = 1,n
        zy(i) = zy(i) + za*zx(i)
   30 continue
      return
      end
      subroutine  zcopy(n,zx,incx,zy,incy)
c
c     copies a vector, x, to a vector, y.
c     <NAME>, linpack, 4/11/78.
c
c      double complex zx(*),zy(*)
      double complex zx(n),zy(n)
      integer i,incx,incy,ix,iy,n
c
      if(n.le.0)return
      if(incx.eq.1.and.incy.eq.1)go to 20
c
c        code for unequal increments or equal increments
c          not equal to 1
c
      ix = 1
      iy = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      if(incy.lt.0)iy = (-n+1)*incy + 1
      do 10 i = 1,n
        zy(iy) = zx(ix)
        ix = ix + incx
        iy = iy + incy
   10 continue
      return
c
c        code for both increments equal to 1
c
   20 do 30 i = 1,n
        zy(i) = zx(i)
   30 continue
      return
      end
      double complex function zdotc(n,zx,incx,zy,incy)
c
c     forms the dot product of a vector.
c     <NAME>, 3/11/78.
c
c      double complex zx(*),zy(*),ztemp
      double complex zx(n),zy(n),ztemp
      ztemp = (0.0d0,0.0d0)
      zdotc = (0.0d0,0.0d0)
      if(n.le.0)return
      if(incx.eq.1.and.incy.eq.1)go to 20
c
c        code for unequal increments or equal increments
c          not equal to 1
c
      ix = 1
      iy = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      if(incy.lt.0)iy = (-n+1)*incy + 1
      do 10 i = 1,n
        ztemp = ztemp + dconjg(zx(ix))*zy(iy)
        ix = ix + incx
        iy = iy + incy
   10 continue
      zdotc = ztemp
      return
c
c        code for both increments equal to 1
c
   20 do 30 i = 1,n
        ztemp = ztemp + dconjg(zx(i))*zy(i)
   30 continue
      zdotc = ztemp
      return
      end
      subroutine  zdscal(n,da,zx,incx)
c
c     scales a vector by a constant.
c    <NAME>, 3/11/78.
c
c      double complex zx(*)
      double complex zx(n)
      double precision da
      if(n.le.0)return
      if(incx.eq.1)go to 20
c
c        code for increments not equal to 1
c
      ix = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      do 10 i = 1,n
        zx(ix) = dcmplx(da,0.0d0)*zx(ix)
        ix = ix + incx
   10 continue
      return
c
c        code for increments equal to 1
c
   20 do 30 i = 1,n
        zx(i) = dcmplx(da,0.0d0)*zx(i)
   30 continue
      return
      end
      subroutine  zscal(n,za,zx,incx)
c
c    scales a vector by a constant.
c    <NAME>, 3/11/78.
c
c      double complex za,zx(*)
      double complex za,zx(n)
      if(n.le.0)return
      if(incx.eq.1)go to 20
c
c        code for increments not equal to 1
c
      ix = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      do 10 i = 1,n
        zx(ix) = za*zx(ix)
        ix = ix + incx
   10 continue
      return
c
c        code for increments equal to 1
c
   20 do 30 i = 1,n
        zx(i) = za*zx(i)
   30 continue
      return
      end
      subroutine  zswap (n,zx,incx,zy,incy)
c
c     interchanges two vectors.
c     <NAME>, 3/11/78.
c
c      double complex zx(*),zy(*),ztemp
      double complex zx(n),zy(n),ztemp
c
      if(n.le.0)return
      if(incx.eq.1.and.incy.eq.1)go to 20
c
c       code for unequal increments or equal increments not equal
c         to 1
c
      ix = 1
      iy = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      if(incy.lt.0)iy = (-n+1)*incy + 1
      do 10 i = 1,n
        ztemp = zx(ix)
        zx(ix) = zy(iy)
        zy(iy) = ztemp
        ix = ix + incx
        iy = iy + incy
   10 continue
      return
c
c       code for both increments equal to 1
   20 do 30 i = 1,n
        ztemp = zx(i)
        zx(i) = zy(i)
        zy(i) = ztemp
   30 continue
      return
      end
<file_sep>      program birrp
c
c  Revision 1 Oct 2001 added robust ar filter computation as default
c  Revision 2 Nov 2001 added basic and advanced input options, input of all components from one
c                      ascii file,use of dimensional period instead of Nyquists for input and
c                      output, output of apparent resistivity and phase
c  Revision 3 Mar 2002 numerous minor changes
c                      bug fixes in output section, provision of both period and frequency
c                      in output, allowance of sample rate as well as sample interval,
c                      change to scale estimate for Thomson weights
c  Revision 3.1        fixed minor errors in rarfilt
c  Revision 3.2        changed convergence flag to integer
c  Revision 3.3        added immediate termination if all weights go to zero
c  Revision 4 Dec 2002 major improvements to robust ar filter routine, including exclusive
c                      use of double precision to get acvs and ar filter
c                      ar filter is checked for minimum phase behavior
c                      ar filter and poles output in diagnostic file
c                      added option to input prewhitened data and prewhitening filter
c  Revision 5 Mar 2004 Major code revision
c                      changed convention for frequency input to FILTER to dimensional units, added
c	               automatic interpolation feature from filter data input from file when nfil<0
c                      added J-format output, added option for automatic computation of data bounds
c                      given start and end times of each time series, integrated selection of
c                      delete one files with output level, added sort feature for responses in
c                      case frequencies are not increasing, added diagnostic output for first
c                      stage, made minor corrections to qq plot output, removed l1 initial solution
c                      option, substantially reduced memory usage, added full output of transfer function,
c                      jackknife errors, and coherences for stage 1
c  Revision 5.1        Fixed coherence thresholding so frequency selection works
c                      forced fft size in call to rarfilt to be even to
c                      make levinson recursion stable
c  Revision 5.2        Changed to Bonferroni confidence intervals for
c                      apparent resistivity and phase
c  Revision 5.2.1      Corrected fatal error in nonrobust processing using 2 stage approach
c  Revision 5.2.2      Corrected indexing error in ccoher1 and ccoher2
c  Revision 5.2.3      Changed zeromean of data segments to zero median
c                      Changed to direct median computation in mad
c
c  Computes transfer function and multiple coherence between up to
c  three output and three input data series using bounded influence,
c  two stage least squares method.
c
c  Computation is by section averaging using variable section lengths.
c  Robust weights are computed using a Rayleigh distribution model on the
c  regression residuals and applied equally to the real and imaginary parts.
c  Leverage weights are computed by comparing the hat matrix diagonal elements
c  to their expected value. Optional coherence thresholding can be applied with
c  a combination of a selected coherence value and/or a fractional trim value.
c  Confidence limits are obtained using the unbalanced jackknife.
c
c  parameter list in 'parameters.h' appears below
c
c  inter = logical flag for interactive (.true.) or runfile (.false.) version
c  npcsm = maximum number of data pieces
c  nptsm = maximum number of data in all pieces
c  nptssm = maximum fft section length
c  noutm = maximum number of output time series
c  ninpm = maximum number of input time series
c  nrefm = maximum number of reference time series, must be .ge. ninpm
c  nrsitem = maximum number of reference sites
c  nsectm = maximum number of data sections, should be set to
c           nptsm*nsctinc**(nsctmax-1)/(nptssm*offs), where
c           offs=0.57-0.07*tbw and tbw is the time bandwidth
c
      include 'parameters.h'
      parameter (nserm=noutm+ninpm+nrefm)
c
c  additional parameters which should not need to be changed frequently
c
c  nblk = block size for coherence thresholding, set to 10
c            if changed, it must also be adjusted in bcoher2_e and bcoher2_b
      parameter (nblk=10)
c  nfsm = maximum number of frequencies to be used for a given section size
      parameter (nfsm=2)
c  nfm = maximum number of output frequencies
      parameter (nfm=100)
c  nfilm = maximum number of filter parameters
      parameter (nfilm=100)
c         if changed, it must also be adjusted in dataft
c  narm = maximum ar filter length
c         if changed, it must also be adjusted in dataft, rarfilt1, and binput
      parameter (narm=100)
c
c  mfftm = maximum value of mfft
      parameter (mfftm=10)
c
c  nrecl = maximum length of a binary record, set to 30000 in subroutine input
c
      character filnam*80,fildat(nserm,npcsm)*80,frm*1,ofil*70,
     $          postfix*30,cn*3,cpar(nserm)*80,jlabel1(2,2)*3,
     $          jlabel2(3,2)*8,dstim(nserm,npcsm)*19,
     $          wstim(nserm,npcsm)*19,wetim(nserm,npcsm)*19,
     $          cvar(3)*20,cvar1(3)*20
      integer tdiff,dssec,wssec,wesec,wsmax,wemin
      dimension dssec(nserm,npcsm),wssec(nserm,npcsm),
     $          wesec(nserm,npcsm),wsmax(npcsm),wemin(npcsm)
      double complex b,aa,bb,ob,root
      dimension b(nrefm),ob(nrefm),aa(nrefm,nrefm),bb(nrefm),
     $          root(narm+1)
      complex fft,ffts,tbn,tbr,hn,hr,hd1,gn1,gn2,gr1,gr2,resq,oresq
      dimension fft(nptssm),ffts(nsectm,nserm,nfsm),
     $          tbn(ninpm,nrefm,nfm),hn(noutm,ninpm,nfm),
     $          tbr(ninpm,nrefm,nfm),hr(noutm,ninpm,nfm),
     $          gn1(ninpm,nfm),gn2(noutm,nfm),
     $          gr1(ninpm,nfm),gr2(noutm,nfm),
     $          gn1lo(ninpm,nfm),gn1hi(ninpm,nfm),
     $          gr1lo(ninpm,nfm),gr1hi(ninpm,nfm),
     $          gn2lo(noutm,nfm),gn2hi(noutm,nfm),
     $          gr2lo(noutm,nfm),gr2hi(noutm,nfm),
     $          dfn1(ninpm,nfm),dfn2(noutm,nfm),
     $          dfr1(ninpm,nfm),dfr2(noutm,nfm),
     $          hd1(nrefm+1,nsectm),gd1(nsectm)
      double precision sum,var,wtsum,dpss,dwork,dofscal,evalu,coef
      dimension dpss(nptssm),dwork(6*nptssm+13),coef(narm+1)
      dimension frej(nfm),rdata(nptsm,nserm),
     $          work(14*nptsm+7*nptsm*mfftm/nptssm+18*nptssm+32),
     $          fpar(nfilm+1,nserm),arf(narm,nserm,npcsm),
     $          wsave(4*nptssm+15),hat(nsectm),
     $          res(nsectm),pwro(nsectm),pwri(nsectm),
     $          xindex(nsectm),w(nsectm),
     $          what(nsectm),wt(nsectm),wt1(nsectm)
      dimension varn1(ninpm,nrefm,nfm),varn2(noutm,ninpm,nfm),
     $          varr1(ninpm,nrefm,nfm),varr2(noutm,ninpm,nfm)
      dimension temp(nsectm),freq(nfm),arft(narm),
     $          theta1(nrsitem+2),theta2(nrsitem+2),
     $          phi(nrsitem+2),c2b(nsectm/nblk,ninpm),
     $          c2e(nsectm/nblk,noutm),
     $          fracthresh1(ninpm,nfm),fracdat1(ninpm,nfm),
     $          fracthresh2(noutm,nfm),fracdat2(noutm,nfm)
      integer convflag1,convflag2
      dimension nstart(npcsm+1),npts(npcsm),nfil(nserm),
     $          ncomp(nserm),iindex(noutm+ninpm,nserm),
     $          nskip(nserm,npcsm),nread(npcsm),nblock(nserm),
     $          nfr(nfm),convflag1(ninpm,nfm),convflag2(noutm,nfm)
      logical compare,c2flag,c2flag1,cflag1,cflag2,
     $        lwt,lwt1,llo,lhi,llo1,lhi1,ilev
      dimension c2flag(nsectm/nblk),c2flag1(nsectm/nblk),
     $          lwt(nsectm),lwt1(nsectm),llo(nsectm),lhi(nsectm),
     $          llo1(nsectm),lhi1(nsectm)
      double precision pi,rad
      parameter (pi=3.141592653589793d0,rad=pi/180.d0)
      equivalence (ffts,dwork,work)
      data nrr/0/,nrr1/0/,nr2/1/,nr3/0/,c2threshe/0./,c2threshe1/0./,
     $     c2threshb/0./,nz/0/,nblock/nserm*0/,mfft/2/,nprej/0/,
     $     cn/'   '/
      data f2lo/0./,f2hi/0.5/,eps/0.01/,eps1/0.1/
      data jlabel1(1,1)/'RXX'/,jlabel1(1,2)/'RXY'/,
     $     jlabel1(2,1)/'RYX'/,jlabel1(2,2)/'RYY'/
      data jlabel2(1,1)/'ZXX S.I.'/,jlabel2(1,2)/'ZXY S.I.'/,
     $     jlabel2(2,1)/'ZYX S.I.'/,jlabel2(2,2)/'ZYY S.I.'/,
     $     jlabel2(3,1)/'TZX     '/,jlabel2(3,2)/'TZY     '/
      data ilev/.false./
c
c  input run parameters
c
      if(inter)write(6,5)
      read(5,*)nlev
      if(nlev.eq.1)ilev=.true.
      if(inter)write(6,6)
      read(5,*)nout
      if(inter)write(6,7)
      read(5,*)ninp
      if(ilev)then
        if(inter)write(6,8)
        read(5,*)nref
        if(nref.gt.3)then
          nrr=1
          if(inter)write(6,9)
          read(5,*)nr3,nr2
        elseif(nref.eq.3)then
          if(ninp.lt.3)nrr=1
          nr3=1
          nr2=0
        endif
      else
        nref=ninp
      endif
      nser=nout+ninp+nref
      if(ilev)then
        if(inter)write(6,10)
        read(5,*)nrr1
        if((nrr.eq.1).and.(nrr1.eq.0))then
          if(inter)write(6,*)' 2 stage processing required with this',
     $                       ' input/output combination--set to 1'
        nrr1=1
        endif
        nrr=nrr1
      endif
    1 if(inter)write(6,11)
      read(5,*)tbw
      if(inter)then
        if((tbw.lt.1.).or.(tbw.gt.4.))then
          write(6,*)' time-bandwidth out of bounds-should be 1 to 4'
          goto 1
        endif
      endif
      offs=0.57-0.07*tbw
      if(inter)write(6,12)
      read(5,*)deltat
      if(deltat.eq.0.)deltat=1.
      if(deltat.lt.0.)deltat=1./abs(deltat)
    2 continue
      if(ilev)then
        if(inter)write(6,13)
        read(5,*)nfft,nsctinc,nsctmax
      else
        if(inter)write(6,14)
        read(5,*)nfft,nsctmax
        nsctinc=2
      endif
      if(mod(nfft,2).ne.0)nfft=nfft+1
      if(ilev)then
        if(inter)write(6,15)
        read(5,*)nf1,nfinc,nfsect
      else
        nf1=nint(tbw+2.)
        nfinc=nint(tbw)
        nfsect=2
      endif
      if(inter)then
        if(nptsm*float(nsctinc**(nsctmax-1))/(nfft*offs).gt.nsectm)then
          write(6,*)' number of sections exceeds dimension of nsectm'
          goto 2
        endif
        if(nfft.gt.nptssm)then
          write(6,*)' fft length exceeds dimension of nptssm'
          goto 2
        endif
        if(nsctmax*nfsect.gt.nfm)then
          write(6,*)' number of periods exceeds dimension of',nfm
          goto 2
        endif
        if(nfsect.gt.nfsm)then
          write(6,*)' periods per section exceeds dimension of',nfsm
          goto 2
        endif
        write(6,*)' table of output periods by section length'
        nfft1=nfft
        do 3 i=1,nsctmax
          write(6,*)(deltat*nfft1/(nf1+j*nfinc),j=0,nfsect-1)
   3      nfft1=nfft1/nsctinc
        write(6,16)
        read(5,'(a)')frm
        if((frm.eq.'n').or.(frm.eq.'N'))goto 2
      endif
      if(ilev)then
        write(6,17)
        read(5,*)mfft
      endif
      if(nfft/mfft.lt.nptssm/mfftm)then
        mfft=nfft*mfftm/nptssm
        if(mfft.eq.0)then
          write(6,*)' mfftm is too small for input value of nfft'
          stop
        endif
        write(6,*)' mfft adjusted to',mfft
      endif
      if(ilev)then
        if(inter)write(6,18)
        read(5,*)uin,ainlin,ainuin
      else
        ainlin=-999
        write(6,19)
        read(5,*)uin,ainuin
      endif
      if(nrr.eq.1)then
        if(inter)write(6,20)
        read(5,*)c2threshb
        c2threshb=min(c2threshb,1.)
      endif
      if(inter)write(6,21)
      read(5,*)c2threshe
      c2threshe=min(c2threshe,1.)
      if(nout.eq.3)then
        if(inter)write(6,22)
        read(5,*)nz
        if(nz.eq.0)then
          if(inter)write(6,21)
          read(5,*)c2threshe1
        endif
      endif
      if(ilev)then
        if((c2threshb.ne.0.).or.(c2threshe.ne.0.).or.
     $     (c2threshe1.ne.0))then
           if(inter)write(6,23)
          read(5,*)perlo,perhi
          if(perlo.lt.0)perlo=1./abs(perlo)
          if(perhi.lt.0.)perhi=1./abs(perhi)
          f2lo=deltat/perlo
          f2hi=min(0.5,deltat/perhi)
        endif
      endif
      c2crit=1.-0.05**(2./(2.*(nblk-ninp)))
      if((inter).and.(c2threshb.ne.0.).and.(c2threshb.lt.c2crit))then
        write(6,*)' zero coherence at 95% significance of',c2crit
        write(6,*)' is larger than specified value of ',c2threshb
        write(6,*)' for 1st stage'
      endif
      if((inter).and.(c2threshe.ne.0.).and.(c2threshe.lt.c2crit))then
        write(6,*)' zero coherence at 95% significance of',c2crit
        write(6,*)' is larger than specified value of ',c2threshe
        write(6,*)' for 2nd stage'
      endif
      if((inter).and.(nz.eq.0).and.(c2threshe1.ne.0.).and.
     $   (c2threshe1.lt.c2crit))then
        write(6,*)' zero coherence at 95% significance of',c2crit
        write(6,*)' is larger than specified value of ',c2threshe1
        write(6,*)' for third output variable'
      endif
      if(inter)write(6,24)
      read(5,'(a)')ofil
      call strlen(ofil,l1,l2)
c
c  open diagnostic file
c
      open (unit=19,file=ofil(l1:l2)//'.diag',
     $      status='unknown')
      if(.not.inter)then
        if((tbw.lt.1.).or.(tbw.gt.4.))then
          write(19,*)' ERROR-time-bandwidth out of bounds-',
     $                 ' should be 1 to 4'
          stop
        endif
        if(nptsm*float(nsctinc**(nsctmax-1))/(nfft*offs).gt.nsectm)then
          write(19,*)' ERROR-number of sections exceeds',
     $                 ' dimension of',nsectm
          stop
        endif
        if(nfft.gt.nptssm)then
          write(19,*)' ERROR-fft length exceeds dimension',
     $                 ' of',nptssm
          stop
        endif
        if(nsctmax*nfsect.gt.nfm)then
          write(19,*)' ERROR-number of frequencies exceeds',
     $                 ' dimension of',nfm
          stop
        endif
        if(nfsect.gt.nfsm)then
          write(19,*)' ERROR-frequencies per section exceeds',
     $                 ' dimension of',nfsm
          stop
        endif
      endif
      if(inter)write(6,25)
      read(5,*)nlev
      if(ilev)then
        if(inter)write(6,26)
        read(5,*)nprej
        if(nprej.ne.0)then
          if(inter)write(6,27)
          do 4 i=1,nprej
            read(5,*)prej
            if(prej.lt.0.)prej=1./abs(prej)
    4       frej(i)=deltat/prej
        endif
      endif
    5 format(' select the input level (0=basic,1=advanced):',$)
    6 format(' input the number of output time series:',$)
    7 format(' input the number of input time series:',$)
    8 format(' input the number of reference time series:',$)
    9 format(' input the number of 3/2 component reference sites:',$)
   10 format(' select r-r (0) or 2-stage robust method (1):',$)
   11 format(' select tbw for prolate data window (1 to 4):',$)
   12 format(' input the data sample interval:',$)
   13 format(' input the initial section length, divisor,',
     $       ' and maximum number of sections:',$)
   14 format(' input the initial section length and',
     $       ' maximum number of sections:',$)
   15 format(' input the starting index, increment, and number of',
     $       ' frequencies per section:',$)
   16 format(' are these values acceptable (y or n)?',$)
   17 format(' input the robust ar filter section length divisor:',$)
   18 format(' input the robustness and lower/upper leverage',
     $       ' parameters (-999 to omit):',$)
   19 format(' input the robustness and leverage parameters',
     $       ' (0 and >0.99 are recommended):',$)
   20 format(' input the 1st stage coherence threshold:',$)
   21 format(' input the 2nd stage coherence threshold:',$)
   22 format(' input the 3rd variable threshold mode',
     $       ' (0 to threshold separately, 1 to threshold using',
     $       '  2nd stage value, and 2 to threshold simultaneously',
     $       '  with 2nd stage variables):',$)
   23 format(' input the longest and shortest periods:',$)
   24 format(' input the output filename root:',$)
   25 format(' input the output level (-3 to 3):',$)
   26 format(' input the number of rejection frequencies:',$)
   27 format(' input the frequencies')
c
c  input data
c
      if(inter)write(6,50)
      read(5,*)npcs
      if(inter)write(6,51)
      read(5,*)nar
      if(inter)write(6,52)
      read(5,*)imode
      if(inter)write(6,53)
      read(5,*)jmode
      if(imode.eq.0)then
        frm='f'
      elseif(imode.eq.1)then
        frm='u'
      endif
      if(uin.ne.-999.)then
c output header block for j-file
        filnam=ofil(l1:l2)//'.j'
	open(unit=18,file=filnam,status='unknown')
	call jfinit(ilev,nout,ninp,nref,nr3,nr2,nrr,
     $              tbw,deltat,nfft,nsctinc,nsctmax,nf1,
     $              nfinc,nfsect,mfft,uin,ainlin,ainuin,
     $              c2threshb,c2threshe,nz,c2threshe1,
     $              perlo,perhi,nprej,frej,npcs,nar,imode,
     $              jmode)
      endif
c
c input data parameters
c
      if(imode.lt.2)then
        do 36 nn=1,npcs
	  if(jmode.eq.0)then
	    if(inter)write(6,54)
	    read(5,*)nread(nn)
	  endif
          do 36 n=1,nser
            if(nn.eq.1)then
              if(inter)write(6,55)
              read(5,*)nfil(n)
              if(nfil(n).gt.nfilm)then
                if(inter)then
                  write(6,*)' number of filter coefficients exceeds',
     $                      ' dimension'
                else
                  write(19,*)' ERROR-number of filter coefficients',
     $                         ' exceeds dimension'
                endif
                stop
              endif
              if(nfil(n).gt.0)then
                if(inter)write(6,56)
                read(5,*)(fpar(i,n),i=1,nfil(n))
	        fpar(nfil(n)+1,n)=deltat
              elseif(nfil(n).lt.0)then
	        if(inter)write(6,57)
	        read(5,'(a)')cpar(n)
	      endif
              if(imode.eq.1)then
                if(inter)write(6,58)
                read(5,*)nblock(n)
              endif
	    endif
            if(nar.lt.0)then
              if(inter)write(6,59)
              read(5,'(a)')filnam
              open(unit=10,file=filnam,status='old')
              do 33 i=1,-nar
   33           read(10,*,end=34)arf(i,n,nn)
              close(unit=10)
              goto 35
   34         if(inter)then
                write(6,*)' end of file for ar filter at series',n,
     $                    ' piece',nn
              else
                write(19,*)' ERROR-end of file for ar filter at',
     $                       ' series',n,' piece',nn
              endif
              stop
   35         continue
            endif
            if(inter)write(6,60)
            read(5,'(a)')fildat(n,nn)
            if(jmode.eq.0)then
              if(inter)write(6,61)
              read(5,*)nskip(n,nn)
            else
              if(inter)write(6,62)
              read(5,'(a19)')dstim(n,nn)
              read(5,'(a19)')wstim(n,nn)
              read(5,'(a19)')wetim(n,nn)
            endif
   36       continue
      else
        do 37 n=1,nser
          if(inter)write(6,55)
          read(5,*)nfil(n)
          if(nfil(n).gt.nfilm)then
            if(inter)then
              write(6,*)' number of filter coefficients exceeds',
     $                  ' maximum dimension'
            else
              write(19,*)' ERROR-number of filter coefficients',
     $                     ' exceeds maximum dimension'
            endif
            stop
          endif
          if(nfil(n).gt.0)then
            if(inter)write(6,56)
            read(5,*)(fpar(i,n),i=1,nfil(n))
	    fpar(nfil(n)+1,n)=deltat
          elseif(nfil(n).lt.0)then
	    if(inter)write(6,57)
	    read(5,'(a)')cpar(n)
	  endif
   37     continue
        if(inter)write(6,63)
        read(5,*)ncomp(1),(iindex(i,1),i=1,nout+ninp)
        do 38 nn=1,npcs
          if(inter)write(6,60)
          read(5,'(a)')fildat(1,nn)
          if(jmode.eq.0)then
            if(inter)write(6,61)
            read(5,*)nskip(1,nn)
            if(inter)write(6,54)
            read(5,*)nread(nn)
          else
            if(inter)write(6,62)
            read(5,'(a19)')dstim(1,nn)
            read(5,'(a19)')wstim(1,nn)
            read(5,'(a19)')wetim(1,nn)
          endif
   38     continue
        do 41 n=1,nr3
          if(inter)write(6,63)
          read(5,*)ncomp(n+1),(iindex(i,n+1),i=1,3)
          do 41 nn=1,npcs
            if(inter)write(6,60)
            read(5,'(a)')fildat(n+1,nn)
            if(jmode.eq.0)then
              if(inter)write(6,61)
              read(5,*)nskip(n+1,nn)
            else
              if(inter)write(6,62)
              read(5,'(a19)')dstim(n+1,nn)
              read(5,'(a19)')wstim(n+1,nn)
              read(5,'(a19)')wetim(n+1,nn)
            endif
   41       continue
        do 43 n=1,nr2
          if(inter)write(6,63)
          read(5,*)ncomp(n+nr3+1),(iindex(i,n+nr3+1),i=1,2)
          do 43 nn=1,npcs
            if(inter)write(6,60)
            read(5,'(a)')fildat(n+nr3+1,nn)
            if(jmode.eq.0)then
              if(inter)write(6,61)
              read(5,*)nskip(n+nr3+1,nn)
            else
              if(inter)write(6,62)
              read(5,'(a19)')dstim(n+nr3+1,nn)
              read(5,'(a19)')wstim(n+nr3+1,nn)
              read(5,'(a19)')wetim(n+nr3+1,nn)
            endif
   43       continue
      endif
c
   50 format(' input the number of data pieces:',$)
   51 format(' input the length of the ar filter (0 for none,'
     $       ' <0 for filename):',$)
   52 format(' select the file mode (0=separate ascii files,',
     $       ' 1=separate binary files',
     $       ' 2=all component ascii files',
     $       ' 3=ts ascii file:',$)
   53 format(' select the input mode (0=by points, 1=by date/time):',$)
   54 format(' input the number of points to read:',$)
   55 format(' input the number of filter parameters',
     $       ' (<0 for filename):',$)
   56 format(' input the filter parameters')
   57 format(' input the filter filename:',$)
   58 format(' input the block size:',$)
   59 format(' input the ar filter filename:',$)
   60 format(' input the data filename:',$)
   61 format(' input the number of points to skip:',$)
   62 format(' input the data start and window start/end times'
     $       ' (yyyy-mm-dd hh:mm:ss):',$)
   63 format(' input the number of components and the indices',
     $       ' by component:',$)
c
c align time series if date/times were input
c
      if(jmode.eq.1)then
c
c  reference time differences to 1980-01-01 00:00:00
c
        if(imode.lt.2)then
          m=nser
        else
          m=1+nr3+nr2
        endif
        do 65 nn=1,npcs
         wsmax(nn)=0
         wemin(nn)=86400*365*50
         do 65 n=1,m
            dssec(n,nn)=tdiff('1980-01-01 00:00:00',dstim(n,nn))
            wssec(n,nn)=tdiff('1980-01-01 00:00:00',wstim(n,nn))
            wesec(n,nn)=tdiff('1980-01-01 00:00:00',wetim(n,nn))
            wsmax(nn)=max(wsmax(nn),wssec(n,nn))
   65       wemin(nn)=min(wemin(nn),wesec(n,nn))
        do 66 nn=1,npcs
          nread(nn)=dble(wemin(nn)-wsmax(nn))/dble(deltat)
          if(nread(nn).le.0)then
            if(inter)then
              write(6,*)' nread not positive for piece',nn
            else
              write(19,*)' nread not positive for piece',nn
            endif
            stop
          endif
          do 66 n=1,m
   66       nskip(n,nn)=dble(wsmax(nn)-dssec(n,nn))/dble(deltat)
      endif
c
c  input data
c
      nstart(1)=1
      nptstot=0
      if(imode.lt.2)then
        do 76 n=1,nser
          if(uin.ne.-999.)then
            write(18,996)'#nfil=',nfil(n)
          endif
          do 76 nn=1,npcs
            if(uin.ne.-999.)then
               write(18,'(2a)')'#filnam=',fildat(n,nn)
              write(18,996)'#nskip=',nskip(n,nn),' nread=',nread(nn)
            endif
            call input(fildat(n,nn),frm,nblock(n),nskip(n,nn),
     $                 nread(nn),rdata(nstart(nn),n))
            if(nread(nn).eq.0)then
              if(inter)then
                write(6,*)' end of file at series',n,' piece',nn
              else
                write(19,*)' ERROR-end of file at series',n,
     $                       ' piece',nn
              endif
              stop
            endif
            if(n.eq.1)then
              nptstot=nptstot+nread(nn)
              npts(nn)=nread(nn)
              nstart(nn+1)=nstart(nn)+nread(nn)
              if(nptstot.gt.nptsm)then
                if(inter)then
                  write(6,*)' number of data exceeds dimension of',
     $                      nptsm
                else
                  write(19,*)' ERROR-number of data exceeds',
     $                         ' dimension of',nptsm
                endif
                stop
              endif
            elseif(nread(nn).ne.npts(nn))then
              if(inter)then
                write(6,*)' number of data incorrect at series',n,
     $                    ' piece',nn,' nread=',nread(nn)
              else
                write(19,*)' ERROR-number of data incorrect at',
     $                       ' series', n,' piece',nn,
     $                       ' nread=',nread(nn)
              endif
              stop
            endif
   76       continue
      else
        do 77 n=1,nser
          if(uin.ne.-999.)then
            write(18,996)'#nfil=',nfil(n)
          endif
   77     continue
        if(uin.ne.-999.)then
          write(18,996)'#ncomp=',ncomp(1)
          write(18,997)'#indices=',(iindex(i,1),i=1,nout+ninp)
        endif
        do 78 nn=1,npcs
          if(uin.ne.-999.)then
            write(18,'(2a)')'#filnam=',fildat(1,nn)
            write(18,996)'#nskip=',nskip(1,nn),' nread=',nread(nn)
          endif
          call binput(fildat(1,nn),imode-1,nskip(1,nn),nread(nn),
     $                nar,ncomp,nout+ninp,iindex(1,1),work,
     $                rdata(nstart(nn),1),arf(1,1,nn),cvar)
          if(nread(nn).eq.0)then
            if(inter)then
              write(6,*)' end of file at piece',nn
            else
              write(19,*)' ERROR-end of file at piece',nn
            endif
            stop
          endif
          nptstot=nptstot+nread(nn)
          if(nptstot.gt.nptsm)then
            if(inter)then
              write(6,*)' number of data exceeds dimension of',nptsm,
     $                  ' at piece',nn
            else
              write(19,*)' ERROR-number of data exceeds',
     $                     ' dimension of',nptsm,' at piece',nn
            endif
            stop
          endif
          npts(nn)=nread(nn)
   78     nstart(nn+1)=nstart(nn)+nread(nn)
        mser=nout+ninp+1
        do 82 n=1,nr3
          if(uin.ne.-999.)then
            write(18,996)'#ncomp=',ncomp(n+1)
            write(18,997)'#indices=',(iindex(i,n+1),i=1,3)
          endif
          do 81 nn=1,npcs
            if(uin.ne.-999.)then
              write(18,'(2a)')'#filnam=',fildat(n+1,nn)
              write(18,996)'#nskip=',nskip(n+1,nn),
     $                     ' nread=',nread(nn)
            endif
            call binput(fildat(n+1,nn),imode-1,nskip(n+1,nn),
     $                  nread(nn),nar,ncomp(n+1),3,iindex(1,n+1),work,
     $                  rdata(nstart(nn),mser),arf(1,mser,nn),cvar1)
             if(nread(nn).eq.0)then
              if(inter)then
                write(6,*)' end of file for reference',n,
     $                    ' at piece',nn
              else
                write(19,*)' ERROR-end of file for reference',n,
     $                       ' at piece',nn
              endif
              stop
            elseif(nread(nn).ne.npts(nn))then
              if(inter)then
                write(6,*)' number of data incorrect for reference',n,
     $                    ' at piece',nn
              else
                write(19,*)' ERROR-number of data incorrect for',
     $                       ' reference',n,' at piece',nn
              endif
              stop
            endif
   81       continue
   82     mser=mser+3
        do 84 n=1,nr2
          if(uin.ne.-999.)then
            write(18,996)'#ncomp=',ncomp(n+nr3+1)
            write(18,997)'#indices=',(iindex(i,n+nr3+1),i=1,2)
          endif
          do 83 nn=1,npcs
            if(uin.ne.-999.)then
              write(18,'(2a)')'#filnam=',fildat(n+nr3+1,nn)
              write(18,996)'#nskip=',nskip(n+nr3+1,nn),
     $                     ' nread=',nread(nn)
            endif
            call binput(fildat(n+nr3+1,nn),imode-1,
     $                  nskip(n+nr3+1,nn),nread(nn),nar,
     $                  ncomp(n+nr3+1),2,iindex(1,n+nr3+1),
     $                  work,rdata(nstart(nn),mser),
     $                  arf(1,mser,nn),cvar1)
            if(nread(nn).eq.0)then
              if(inter)then
                write(6,*)' end of file for reference',n+nr3+1,
     $                    ' at piece',nn
              else
                write(19,*)' ERROR-end of file for reference',
     $                       n+nr3+1,' at piece',nn
              endif
              stop
            elseif(nread(nn).ne.npts(nn))then
              if(inter)then
                write(6,*)' number of data incorrect for reference',
     $                    n+nr3+1,' at piece',nn
              else
                write(19,*)' ERROR-number of data incorrect for',
     $                       ' reference',n+nr3+1,' at piece',nn
              endif
              stop
            endif
   83       continue
   84     mser=mser+2
      endif
c
c  force data to have zero median for each piece unless data have been prewhitened
c
      if(nar.ge.0)then
        do 88 n=1,nser
          do 88 nn=1,npcs
            xmed=xmedian(rdata(nstart(nn),n),npts(nn))
            do 87 i=nstart(nn),nstart(nn)+npts(nn)-1
   87         rdata(i,n)=rdata(i,n)-xmed
   88       continue
      endif
c
c  input rotation parameters
c
      if(inter)write(6,95)
      if(nout.ge.2)read(5,*)theta1(1),theta2(1),phi(1)
      if(uin.ne.-999.)write(18,998)'#theta1=',theta1(1),
     $                             ' theta2=',theta2(1),
     $                             ' phi=',phi(1)
      read(5,*)theta1(2),theta2(2),phi(2)
      if(uin.ne.-999.)write(18,998)'#theta1=',theta1(2),
     $                             ' theta2=',theta2(2),
     $                             ' phi=',phi(2)
      do 90 i=1,nr3+nr2
        read(5,*)theta1(2+i),theta2(2+i),phi(2+i)
   90   if(uin.ne.-999.)write(18,998)'#theta1=',theta1(2+i),
     $                               ' theta2=',theta2(2+i),
     $                               ' phi=',phi(2+i)
   95 format(' input the rotation angles (cw=+)')
c
c  open robust delete-one files
c
      if(nlev.lt.0)then
        do 162 nn=1,nout
          filnam=ofil(l1:l2)//'.'//char(48+nn)//'r.d1rf'
          open (unit=32+nn,file=filnam,form='unformatted',
     $          status='unknown')
  162   continue
      endif
c
c  prewhiten data series with robust ar filter if required
c
        if(nar.gt.0)then
c          nfftmin=nfft/(nsctinc**(nsctmax-1))
c  use average of logs of shortest and longest fft for ar filter ffts
c          nfft1=exp((log(float(nfft))+log(float(nfftmin)))/2.)
          nfft1=nfft/mfft
          if(mod(nfft1,2).ne.0)nfft1=nfft1+1
          write(19,*)' ar filter fft length=',nfft1
          do 164 jj=1,npcs
            n1=nstart(jj)
            do 163 j=1,nser
              n=npts(jj)
              call rarfilt(n,nfft1,nar,rdata(n1,j),work,arft,info)
              if(info.gt.0)then
                write(19,*)' WARNING-error in call to rarfilt',
     $                       ' series=',j,' piece=',jj,
     $                       ' info=',info
                if(inter)then
                  write(6,*)' Error in call to rarfilt',
     $                      ' series=',j,' piece=',jj,
     $                      ' info=',info
                endif
              endif
              call prewhiten(n,nar,rdata(n1,j),arft,rdata(n1,j))
              do 163 i=1,nar
  163           arf(i,j,jj)=arft(i)
  164       if(j.eq.nser)npts(jj)=n
        endif
c
c check ar filter for minimum phase behavior
c
        do 167 jj=1,npcs
          do 167 j=1,nser
            coef(1)=1.
            do 165 i=2,nar+1
  165         coef(i)=arf(i-1,j,jj)
            call dpqr79(nar,coef,root,ierr,work)
            write(19,*)' poles of ar z-transform and distance from',
     $                   ' unit circle for series=',j,' piece=',jj
            do 166 i=1,nar
              if(abs(root(i)).ge.1.)then
                if(inter)write(6,*)' Non-minimum phase ar filter for',
     $                             ' series ',j,' piece ',jj
                write(19,*)' WARNING-non minimum phase ar filter'
              endif
              x1=dreal(root(i))
              y1=dimag(root(i))
              if(x1.eq.0.)then
                dist=abs(1.-y1)
              else
                x0=sign(sqrt(x1*x1/(x1*x1+y1*y1)),x1)
                y0=y1*x0/x1
                dist=sqrt((x1-x0)**2+(y1-y0)**2)
              endif
              write(19,*)x1,y1,dist
  166         continue
            write(19,*)' ar filter coefficients for series=',j,
     $                   ' piece=',jj
            write(19,*)(arf(i,j,jj),i=1,nar)
  167       continue
c
c  begin outer loop pivoting on section length
c
      nfl=1
      do 171 j=1,nfm
	do 170 n=1,nout
  170     convflag2(n,j)=0
        do 171 n=1,ninp
  171     convflag1(n,j)=0
      do 790 nsc=1,nsctmax
        write(19,*)'*******************************************'
        write(19,*)' section length=',nfft
        xnfft=nfft
c
c  initialize fft computation and compute slepian sequence data window
c
        call rtpss(nptssm,nfft,1,dble(tbw/xnfft),dpss,evalu,
     $             info,dwork)
        if(info.ne.0)then
          if(inter)write(6,*)' error in call to rtpss info=',info
          write(19,*)' WARNING-error in call to rtpss info=',info
        endif
        call cffti(nfft,wsave)
c
c  compute section ffts and correct for instrument response and prewhitening
c
        do 189 k=1,nfsm
          do 189 j=1,nserm
            do 189 i=1,nsectm
              ffts(i,j,k)=0.
  189         continue
        nsect=0
        noff=offs*xnfft+1
        do 190 jj=1,npcs
          if(npts(jj).le.nfft)goto 190
          nsct=float(npts(jj)-nfft-1)/float(noff)+1
          if(npts(jj)-((nsct-1)*noff+nfft+1).ge.nfft)nsct=nsct+1
          ko=nstart(jj)
          do 180 j=1,nser
            call dataft(nsct,j,nf1,nfinc,nfsect,nfft,noff,
     $                  nfil(j),abs(nar),deltat,dpss,wsave,
     $                  rdata(ko,j),fpar(1,j),cpar(j),arf(1,j,jj),
     $                  fft,ffts(nsect+1,1,1))
  180       continue
          nsect=nsect+nsct
  190     continue
        nsect=(nsect/nblk)*nblk
        if(nsect.gt.nsectm)then
          if(inter)then
            write(6,*)' number of sections ',nsect,
     $                ' is larger than maximum dimension of ',nsectm
          else
            write(19,*)' ERROR-number of sections ',nsect,
     $                   ' is larger than maximum dimension of ',nsectm
          endif
          stop
        elseif(nsect.eq.0)then
          goto 790
        endif
        xnsect=nsect
c
c  rotate ffts to new coordinate system
c  theta1 is angle of first component pos cw wrt geomagnetic north
c  theta2 is same for second component
c  phi is pos cw rotation angle of geomagnetic coordinate system
c  if original data are collected in orthogonal coordinate
c  system, set theta1=0, theta2=90
c
        if(nout.gt.1)then
c  first two ffts are assumed to be x and y and are rotated
c  if nout=3, third series is assumed to be z and is not rotated
          do 200 i=1,nfsect
            call rotate(nsect,theta1(1),theta2(1),phi(1),
     $                  ffts(1,1,i),ffts(1,2,i))
  200       continue
        endif
c
c  always rotate input ffts
c  if ninp=3, third series is assumed to be z and is not rotated
c
        if(ninp.gt.1)then
          do 202 i=1,nfsect
            call rotate(nsect,theta1(2),theta2(2),phi(2),
     $                  ffts(1,nout+1,i),ffts(1,nout+2,i))
  202       continue
        endif
c
c  always rotate remote reference ffts if nref.gt.1
c
        if(nref.gt.1)then
          do 204 j=1,nr3
            do 204 i=1,nfsect
              call rotate(nsect,theta1(2+j),theta2(2+j),phi(2+j),
     $                    ffts(1,nout+ninp+3*j-2,i),
     $                    ffts(1,nout+ninp+3*j-1,i))
  204         continue
          do 205 j=1,nr2
            do 205 i=1,nfsect
              call rotate(nsect,theta1(2+nr3+j),theta2(2+nr3+j),
     $                    phi(2+nr3+j),
     $                    ffts(1,nout+ninp+3*nr3+2*j-1,i),
     $                    ffts(1,nout+ninp+3*nr3+2*j,i))
  205         continue
        endif
c
c  compute degrees of freedom inflation factor
c
        dofscal=1.
        nm=max(0,min(nfft,(nptstot-nfft-npcs*abs(nar))/(nsect-1)))
        do 210 i=1,nsect-1
          sum=0.d0
          do 209 j=1,nfft
            if(j+i*nm.le.nfft)sum=sum+dpss(j)*dpss(j+i*nm)
  209       continue
  210     dofscal=dofscal+2.*(1-float(i/nsect))*sum**2
        dofscal=1./dofscal
c
c  begin second loop pivoting on frequency
c
        do 780 nf=1,nfsect
          frq=float(nf1+(nf-1)*nfinc)/xnfft
          do 215 k=1,nprej
            if(compare(frq,frej(k),4))goto 780
  215       continue
          freq(nfl)=frq
          write(19,*)' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'
          write(19,*)' period=',deltat/freq(nfl)
	  do 218 i=1,nsect
	      llo1(i)=.false.
	      lhi1(i)=.false.
              lwt1(i)=.true.
  218         wt1(i)=1.0
c
c  compute projected local magnetic field if required
c
          if(nrr.eq.0)goto 400
c
c  begin first stage
c
c coherence estimation by block averaging
c
          do 219 i=1,nsect/nblk
            c2flag(i)=.true.
	    do 219 j=1,ninp
  219         c2b(i,j)=1.0
          if(((nlev.ge.2).or.(c2threshb.gt.0.)).and.
     $       ((freq(nfl).ge.f2lo).and.(freq(nfl).le.f2hi)))then
            call bcoher2_b(nsect,ninp,nref,c2threshb,
     $                     ffts(1,nout+1,nf),c2flag,c2b,info)
            if(info.ne.0)then
              write(19,*)
     $          ' WARNING-singular matrix detected in',
     $          ' stage 1 coherence threshold at nsc=',nsc,' nf=',nf
            endif
          endif
          nsct=nsect
          do 221 i=1,nsect/nblk
            if(.not.c2flag(i))then
              do 220 ii=(i-1)*nblk+1,i*nblk
                nsct=nsct-1
  220           lwt1(ii)=.false.
            endif
  221       continue
          write(19,*)' stage 1 coherence threshold=',c2threshb
          if(c2threshb.gt.0.)
     $      write(19,*)nsect-nsct,' sections discarded'
          write(19,*)' initial number of data=',nsct
          if(nsct.eq.0)goto 780
          xnsct=nsct
c
c  begin third loop pivoting on input variable
c
	  do 385 nn=1,ninp
            write(19,*)' ++++++++++++++++++++++++++++++'
            write(19,*)' input series=',nn
c
c  compute section powers
c
	    fracthresh1(nn,nfl)=xnsct/xnsect
            do 224 i=1,nsect
              pwro(i)=2.*abs(ffts(i,nout+nn,nf))**2
              pwri(i)=0.
              do 223 j=1,nref
  223           pwri(i)=pwri(i)+abs(ffts(i,nout+ninp+j,nf))**2
	      pwri(i)=2.*pwri(i)/nref
  224         continue
c
c  compute nonrobust transfer function
c
            do 225 i=1,nsect
              wt(i)=0.
  225         if(lwt1(i))wt(i)=1.
            call transfer(nsect,ninp,nref,nn,wt,ffts(1,nout+1,nf),
     $                    b,aa,bb,info)
            if(info.eq.1)then
              write(19,*)' WARNING-singular matrix detected in',
     $                   ' nonrobust magnetic transfer section'
            endif
            write(19,*)
     $       ' initial transfer function indexed by reference variable'
            do 230 i=1,nref
              tbn(nn,i,nfl)=b(i)
  230         write(19,*)i,tbn(nn,i,nfl)
c
c  compute residuals
c
            call residual(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                    b,wt,nw,res,oresq)
c
c  compute jackknife estimate of transfer function standard error
c  compute hat matrix diagonal
c
            call hatdiag(nsect,nref,ffts(1,nout+ninp+1,nf),
     $                   wt,hat,info)
            if(info.ne.0)then
              write(19,*)
     $              ' WARNING-pivot block singular in nonrobust',
     $              ' magnetic transfer call to hatdiag info=',info
            endif
c
c  compute delete one solutions for transfer functions
c
            call delone1(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                   wt,aa,bb,hd1,info)
            if(info.ne.0)then
              write(19,*)
     $              ' WARNING-singular matrix detected in',
     $              ' nonrobust magnetic transfer jackknife'
            endif
c
c  form jackknife variance excluding estimates with zero weights
c
            do 240 ii=1,nref
              var=0.
              do 239 i=1,nsect
                if(wt(i).gt.0.)then
                  var=var+abs((1.-hat(i))*(tbn(nn,ii,nfl)-
     $                                     hd1(ii,i)))**2
                endif
  239           continue
  240         varn1(nn,ii,nfl)=xnsct*var/(xnsct-nref)
c
c  compute nonrobust complex coherence between measured and predicted output
c  variables
c
            call ccoher1(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                   tbn(nn,1,nfl),hd1,wt,gd1,gn1(nn,nfl),
     $                   gn1lo(nn,nfl),gn1hi(nn,nfl))
            dfn1(nn,nfl)=2.*dofscal*(nsct-ninp)
c
c output nonrobust diagnostics if requested
c
            if(abs(nlev).ge.1)then
              if(nfl.le.9)then
                cn(1:1)=char(48)
                cn(2:2)=char(48+nfl)
              elseif(nfl.le.99)then
                write(cn(1:2),'(i2)')nfl
              else
                write(cn,'(i3)')nfl
              endif
              call strlen(cn,m1,m2)
              filnam=ofil(l1:l2)//'.'//char(48+nn)//
     $               '.oq1.'//cn(m1:m2)
              call qqout(filnam,deltat/freq(nfl),nsect,nsct,nw,
     $                   nref,llo1,lhi1,wt,res,hat)
            endif
            if(abs(nlev).eq.3)then
              filnam=ofil(l1:l2)//'.'//char(48+nn)//'.or1.'//
     $               cn(m1:m2)
              call diagout(filnam,deltat/freq(nfl),nsect,nref,
     $                     res,pwro,pwri,wt,hat)
            endif
            if(uin.eq.-999.)then
              do 241 i=1,nref
  241           tbr(nn,i,nfl)=tbn(nn,i,nfl)
              goto 385
            endif
c
c begin robust transfer function computation
c
c
c  compute initial robust scale estimate using nonrobust residuals
c
            nr=0
	    do 245 i=1,nsect
	      xindex(i)=i
              if(wt(i).gt.0.)then
                nr=nr+1
                temp(nr)=res(i)
              endif
  245         continue
            if(nr.eq.0)goto 780
            call mad(nr,temp,scale)
c
c  huber weight regression section
c
c
c  compute number of hat matrix iterations
c
	    call ssort(hat,xindex,nsect,2)
	    khat=1
            if(ainuin.eq.-999.)then
              ainu=0.
              ainu1=0.
            elseif((ainuin.gt.0.).and.(ainuin.lt.1.))then
              ainu=nsct*qbeta(ainuin,nref,nsct-nref)/nref
	      ainu1=xnsct*hat(nsct)/nref
	      khat=max(log(ainu1/ainu)/log(2.)+1.,1.)
            elseif(.not.ilev)then
              ainu=nsct*qbeta(0.999,nref,nsct-nref)/nref
	      ainu1=xnsct*hat(nsct)/nref
	      khat=max(log(ainu1/ainu)/log(2.)+1.,1.)
            else
              ainu=abs(ainuin)
	      ainu1=xnsct*hat(nsct)/nref
	      khat=max(log(ainu1/ainu)/log(2.)+1.,1.)
            endif
            if(ainlin.eq.-999.)then
              ainl=0.
              ainl1=0.
            else
              do 256 k=1,nsect
  256           if(hat(k).ne.0.)goto 257
  257         ainl1=xnsct*hat(k)/nref
              if((ainlin.gt.0.).and.(ainlin.lt.1.))then
                ainl=nsct*qbeta(ainlin,nref,nsct-nref)/nref
              else
                ainl=abs(ainlin)
              endif
	      khat=max(float(khat),log(ainl/ainl1)/log(2.)+1.)
            endif
	    call ssort(xindex,hat,nsect,2)
	    write(19,*)' hat matrix iterations=',khat
            do 258 i=1,nsect
              what(i)=0.
  258         if(lwt1(i))what(i)=1.
            do 290 k=1,khat
c
c  begin hat matrix weight loop
c
              ainu1=max(ainu1/2.,ainu)
              ainl1=min(2.*ainl1,ainl)
              write(19,*)' lower cutoff=',ainl1,' upper cutoff=',ainu1
              do 280 niter=1,10
c
c begin huber regression weight loop
c
                write(19,*)' huber iteration=',niter,' scale=',scale
                if((ainlin.ne.-999.).or.(ainuin.ne.-999.))
     $            call hatwt(nsect,nref,ainl1,ainu1,llo1,lhi1,hat,what)
                call huberwt(nsect,scale,lwt1,res,w)
		do 260 i=1,nsect
  260             wt(i)=what(i)*w(i)
c
c  compute robust transfer function
c
                call transfer(nsect,ninp,nref,nn,wt,
     $                        ffts(1,nout+1,nf),b,aa,bb,info)
                if(info.eq.1)then
                  write(19,*)
     $                  ' WARNING-singular matrix detected in',
     $                  '  huber magnetic transfer section'
                  write(19,*)' niter=',niter
                endif
c
c  compute residuals
c
                call residual(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                        b,wt,nw,res,resq)
c
c  compute robust scale estimate
c
                nr=0
                do 276 i=1,nsect
                  if(wt(i).gt.0.)then
                    nr=nr+1
                    temp(nr)=res(i)
                  endif
  276             continue
                if(nr.eq.0)goto 780
                call mad(nr,temp,scale)
                if((ainlin.ne.-999.).or.(ainuin.ne.-999.))then
c
c  compute hat matrix diagonal
c
                  call hatdiag(nsect,nref,ffts(1,nout+ninp+1,nf),
     $                         wt,hat,info)
                  if(info.ne.0)then
                    write(19,*)
     $                ' WARNING-pivot block singular in huber magnetic',
     $                ' transfer call to hatdiag'
                    write(19,*)' info=',info,' niter=',niter
                  endif
                endif
                write(19,*)' normalized residual sum of squares=',
     $                       abs(resq-oresq)/abs(resq)
                if(abs(resq-oresq).lt.2.*eps*abs(resq))goto 285
  280           oresq=resq
              write(19,*)
     $              ' WARNING-huber iterations did not converge',
     $              ' at hat matrix iteration=',k
  285         oresq=resq
              write(19,*)' number of data=',nw
              write(19,*)
     $         ' huber transfer function indexed by reference variable'
              do 290 i=1,nref
                ob(i)=b(i)
  290           write(19,*)i,cmplx(b(i))
c
c  thomson weight regression section
c
            if(.not.ilev)then
              if((uin.eq.0.).or.(abs(uin).ge.1.))then
                u0=sqrt(2.*log(xnsct/(abs(uin)+0.5)))
              elseif((abs(uin).gt.0.).and.(abs(uin).lt.1.))then
                u0=sqrt(-2.*log(1.-abs(uin)))
              endif
            else
              if((uin.eq.0.).or.(uin.ge.1.))then
                u0=sqrt(2.*log(xnsct/(uin+0.5)))
              elseif((uin.gt.0.).and.(uin.lt.1.))then
                u0=sqrt(-2.*log(1.-uin))
              else
                u0=abs(uin)
              endif
            endif
            if((ainlin.ne.-999.).or.(ainuin.ne.-999.))
     $        call hatwt(nsect,nref,ainl,ainu,llo1,lhi1,hat,what)
            call expwt(nsect,u0,scale,lwt1,res,w)
            do 300 i=1,nsect
  300         wt(i)=what(i)*w(i)
            do 340 niter=1,15
c
c  begin iteration on thomson regression weights
c
              write(19,*)
     $              ' thomson iteration=',niter,' scale=',scale
c
c  compute robust transfer function
c
              call transfer(nsect,ninp,nref,nn,wt,
     $                      ffts(1,nout+1,nf),b,aa,bb,info)
              if(info.eq.1)then
                write(19,*)
     $                ' WARNING-singular matrix detected in thomson',
     $                '  magnetic transfer section'
              endif
c
c  compute residuals
c
              call residual(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                      b,wt,nw,res,resq)
              write(19,*)' number of data=',nw
              write(19,*)
     $         ' thomson solution vector indexed by reference variable'
              do 315 i=1,nref
  315           write(19,*)i,cmplx(b(i))
              write(19,*)' normalized residual sum of squares=',
     $                     abs(resq-oresq)/abs(resq)
c
c  compute robust scale estimate
c
c              if(niter.le.2)then
              if(niter.eq.1)then
                nr=0
                do 320 i=1,nsect
                  if(wt(i).gt.0.)then
                    nr=nr+1
                    temp(nr)=res(i)
                  endif
  320             continue
                if(nr.eq.0)goto 780
                call mad(nr,temp,scale)
              endif
c
c  compute hat matrix diagonal
c
              call hatdiag(nsect,nref,ffts(1,nout+ninp+1,nf),
     $                     wt,hat,info)
              if(info.ne.0)then
                write(19,*)
     $                  ' WARNING-pivot block singular in',
     $                  ' thomson magnetic transfer call to hatdiag'
                write(19,*)' info=',info,' niter=',niter
              endif
              if((ainuin.ne.-999.).or.(ainlin.ne.-999.))
     $          call hatwt(nsect,nref,ainl,ainu,llo1,lhi1,hat,what)
	      call expwt(nsect,u0,scale,lwt1,res,w)
	      do 325 i=1,nsect
  325           wt(i)=what(i)*w(i)
c
c  compute jackknife estimate of transfer function standard error
c
c
c  compute delete one solutions for transfer functions
c
              call delone1(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                     wt,aa,bb,hd1,info)
	      if(info.ne.0)then
	        write(19,*)
     $              ' WARNING-singular matrix detected in stage 1',
     $              ' robust jackknife niter=',niter
              endif
c
c  form jackknife variance excluding values with zero weights
c
              do 330 ii=1,nref
	        var=0.
	        do 327 i=1,nsect
	          if(wt(i).gt.0.)then
		    var=var+abs((1.-hat(i))*
     $                      (b(ii)-hd1(ii,i)))**2
                  endif
  327         continue
  330         varr1(nn,ii,nfl)=nw*var/(nw-ninp)
	      cflag1=.true.
	      do 335 i=1,nref
		sdev=sqrt(varr1(nn,i,nfl))
		if((abs(dreal(ob(i)-b(i))).ge.eps1*sdev).or.
     $             (abs(dimag(ob(i)-b(i))).ge.eps1*sdev))
     $             cflag1=.false.
  335           ob(i)=b(i)
              cflag2=.false.
	      if((abs(real(resq-oresq)).lt.eps*real(resq)).and.
     $           (abs(aimag(resq-oresq)).lt.eps*aimag(resq)))
     $           cflag2=.true.
	      if(cflag1.or.cflag2)goto 345
  340         oresq=resq
	    convflag1(nn,nfl)=1
	    write(19,*)' WARNING-thomson iterations did not converge'
  345       if(cflag1)write(19,*)' convergence on response'
	    if(cflag2)write(19,*)' convergence on residuals'
  350       do 360 i=1,nref
  360         tbr(nn,i,nfl)=b(i)
c
c  compute complex coherence between measured and predicted output variables
c
            call ccoher1(nsect,ninp,nref,nn,ffts(1,nout+1,nf),
     $                   tbr(nn,1,nfl),hd1,wt,gd1,gr1(nn,nfl),
     $                   gr1lo(nn,nfl),gr1hi(nn,nfl))
	    wtsum=0.
	    do 370 i=1,nsect
  370         wtsum=wtsum+wt(i)
	    dfr1(nn,nfl)=2.*dofscal*(wtsum-ninp)
	    fracdat1(nn,nfl)=fracthresh1(nn,nfl)*wtsum/xnsct
c
c  output robust diagnostics as required
c
	    if(abs(nlev).ge.1)then
	      filnam=ofil(l1:l2)//'.'//char(48+nn)//
     $               '.fq1.'//cn(m1:m2)
              call hatdiag(nsect,nref,ffts(1,nout+ninp+1,nf),
     $                     wt,hat,info)
              if(info.ne.0)then
                write(19,*)
     $                ' WARNING-pivot block singular in',
     $                ' thomson magnetic transfer call to hatdiag'
                write(19,*)' info=',info,' niter=',niter
              endif
              call qqout(filnam,deltat/freq(nfl),nsect,nsct,nw,
     $                   nref,llo1,lhi1,wt,res,hat)
	    endif
	    if(abs(nlev).eq.3)then
	      filnam=ofil(l1:l2)//'.'//char(48+nn)//'.fr1.'//
     $               cn(m1:m2)
	      call diagout(filnam,deltat/freq(nfl),nsect,nref,
     $                     res,pwro,pwri,wt,hat)
            endif
 	    do 381 i=1,nsect
  381         wt1(i)=min(wt1(i),wt(i))
  385       continue
c
c  compute projected local magnetic field
c
        do 395 k=1,nsect
	      do 390 i=1,ninp
	        b(i)=0.
            do 390 j=1,nref
  390         b(i)=b(i)+ffts(k,nout+ninp+j,nf)*tbr(i,j,nfl)
            do 395 i=1,ninp
              ffts(k,nout+ninp+i,nf)=b(i)
  395         ffts(k,nout+i,nf)=ffts(k,nout+ninp+i,nf)
  400     continue
c
c  begin second stage
c
c coherence estimation by block averaging
c
          do 405 i=1,nsect/nblk
            c2flag(i)=.true.
            c2flag1(i)=.true.
            do 405 j=1,nout
  405         c2e(i,j)=1.0
          if(((nlev.ge.2).or.(c2threshe.gt.0.).or.
     $       (c2threshe1.gt.0.)).and.
     $       ((freq(nfl).ge.f2lo).and.(freq(nfl).le.f2hi)))then
            n1=min(nout,2)
            if((nout.eq.3).and.(nz.gt.0))n1=3
            call bcoher2_e(nsect,n1,nout,ninp,c2threshe,
     $                     ffts(1,1,nf),c2flag,c2e,info)
            if(info.ne.0)then
              write(19,*)
     $          ' WARNING-singular matrix detected in',
     $          ' stage 2 coherence threshold at nsc=',nsc,' nf=',nf
            endif
            if(nz.gt.0)then
              do 406 i=1,nsect/nblk
  406           c2flag1(i)=c2flag(i)
            endif
            if((nout.eq.3).and.(nz.eq.0))then
              call bcoher2_e(nsect,1,1,ninp,c2threshe1,
     $                       ffts(1,nout,nf),c2flag1,c2e(1,nout),
     $                       info)
              if(info.ne.0)then
                write(19,*)
     $            ' WARNING-singular matrix detected in',
     $            ' stage 2 coherence threshold at nsc=',nsc,' nf=',nf
              endif
            endif
          endif
          write(19,*)' stage 2 coherence threshold=',c2threshe
          if(nout.eq.3)
     $       write(19,*)' stage 2 3rd output coherence threshold=',
     $                    c2threshe1
c
c  begin third loop pivoting on output variable
c
          do 770 nn=1,nout
            if(nfl.le.9)then
              cn(1:1)=char(48)
              cn(2:2)=char(48+nfl)
            elseif(nfl.le.99)then
              write(cn(1:2),'(i2)')nfl
            else
              write(cn,'(i3)')nfl
            endif
            write(19,*)' #####################################'
            write(19,*)' output series=',nn
            if((nn.lt.3).or.(nz.gt.0))then
              do 410 i=1,nsect
  410           lwt(i)=lwt1(i)
              do 412 i=1,nsect/nblk
                if(.not.c2flag(i))then
                  do 411 ii=(i-1)*nblk+1,i*nblk
  411               lwt(ii)=.false.
                endif
  412           continue
            else
              do 415 i=1,nsect
  415           lwt(i)=lwt1(i)
              do 417 i=1,nsect/nblk
                if(.not.c2flag1(i))then
                  do 416 ii=(i-1)*nblk+1,i*nblk
  416               lwt(ii)=.false.
                endif
  417           continue
            endif
            nsct=0
            do 418 i=1,nsect
  418         if((wt1(i).gt.0.).and.lwt(i))nsct=nsct+1
            xnsct=nsct
            if((c2threshe.gt.0.).or.(c2threshe1.gt.0.).or.(nrr.eq.1))
     $        write(19,*)nsect-nsct,' sections discarded'
            write(19,*)' initial number of data=',nsct
	    fracthresh2(nn,nfl)=xnsct/xnsect
            if(nsct.eq.0)goto 770
c
c  compute section powers
c
            do 420 i=1,nsect
              pwro(i)=2.*abs(ffts(i,nn,nf))**2
              pwri(i)=0.
              do 419 j=1,ninp
  419           pwri(i)=pwri(i)+abs(ffts(i,nout+j,nf))**2
	      pwri(i)=2.*pwri(i)/ninp
  420         continue
c
c  compute nonrobust transfer function
c
            do 421 i=1,nsect
              wt(i)=wt1(i)
  421       if(.not.lwt(i))wt(i)=0.
            call response(nsect,nout,ninp,nn,wt,ffts(1,1,nf),b,aa,
     $                    bb,info)
            if(info.eq.1)then
              write(19,*)' WARNING-singular matrix detected in',
     $                     ' l2 nonrobust response section '
            endif
            write(19,*)
     $            ' initial solution vector indexed by input variable'
            do 422 i=1,ninp
              hn(nn,i,nfl)=b(i)
  422         write(19,*)i,hn(nn,i,nfl)
c
c  compute residuals
c
            call residual(nsect,nout,ninp,nn,ffts(1,1,nf),
     $                    b,wt,nw,res,oresq)
c
c  compute jackknife estimate of transfer function standard error
c  compute hat matrix diagonal
c
            call hatdiag(nsect,ninp,ffts(1,nout+ninp+1,nf),
     $                   wt,hat,info)
            if(info.ne.0)then
              write(19,*)
     $              ' WARNING-pivot block singular in nonrobust',
     $              ' response call to hatdiag  info=',info
            endif
c
c  compute delete one solutions for transfer functions
c
            call delone2(nsect,nout,ninp,nn,ffts(1,1,nf),wt,aa,
     $                bb,hd1,info)
            if(info.ne.0)then
              write(19,*)
     $              ' WARNING-singular matrix detected in',
     $              ' nonrobust jackknife'
            endif
c
c  form jackknife variance excluding estimates with zero weights
c
            do 430 ii=1,ninp
              var=0.
              do 429 i=1,nsect
                if(wt(i).gt.0.)then
                  var=var+abs((1.-hat(i))*(hn(nn,ii,nfl)-
     $                                     hd1(ii,i)))**2
                endif
  429           continue
  430         varn2(nn,ii,nfl)=xnsct*var/(xnsct-ninp)
c
c  compute nonrobust complex coherence between measured and predicted output
c  variables
c
            call ccoher2(nsect,nout,ninp,nn,ffts(1,1,nf),hn(nn,1,nfl),
     $                  hd1,wt,gd1,gn2(nn,nfl),gn2lo(nn,nfl),
     $                  gn2hi(nn,nfl))
            dfn2(nn,nfl)=2.*dofscal*(nsct-ninp)
c
c output nonrobust diagnostics if requested
c
            if(abs(nlev).ge.1)then
              if(nfl.le.9)then
                cn(1:1)=char(48)
                cn(2:2)=char(48+nfl)
              elseif(nfl.le.99)then
                write(cn(1:2),'(i2)')nfl
              else
                write(cn,'(i3)')nfl
              endif
              call strlen(cn,m1,m2)
              filnam=ofil(l1:l2)//'.'//char(48+nn)//
     $               '.oq2.'//cn(m1:m2)
              call qqout(filnam,deltat/freq(nfl),nsect,nsct,nw,
     $                   ninp,llo1,lhi1,wt,res,hat)
            endif
            if(abs(nlev).eq.3)then
              filnam=ofil(l1:l2)//'.'//char(48+nn)//'.or2.'//
     $               cn(m1:m2)
              call diagout(filnam,deltat/freq(nfl),nsect,ninp,
     $                     res,pwro,pwri,wt,hat)
            endif
c
c begin robust transfer function computation
c
c
c  compute initial robust scale estimate using nonrobust residuals
c
            if(uin.eq.-999.)goto 760
            nr=0
            do 490 i=1,nsect
              xindex(i)=i
              if(wt(i).gt.0.)then
                nr=nr+1
                temp(nr)=res(i)
              endif
  490         continue
            if(nr.eq.0)goto 770
            call mad(nr,temp,scale)
c
c  huber weight regression section
c
c
c  compute number of hat matrix iterations
c
            call ssort(hat,xindex,nsect,2)
            do 495 k=1,nsect
  495         if(hat(k).ne.0.)goto 496
  496       khat=1
            if(ainuin.eq.-999.)then
              ainu=0.
              ainu1=0.
            elseif((ainuin.gt.0.).and.(ainuin.lt.1.))then
              ainu=nsct*qbeta(ainuin,ninp,nsct-ninp)/ninp
	      ainu1=xnsct*hat(nsct+k-1)/ninp
	      khat=max(log(ainu1/ainu)/log(2.)+1.,1.)
            else
              ainu=abs(ainuin)
	      ainu1=xnsct*hat(nsct+k-1)/ninp
	      khat=max(log(ainu1/ainu)/log(2.)+1.,1.)
            endif
            if(ainlin.eq.-999.)then
              ainl=0.
              ainl1=0.
            else
              ainl1=xnsct*hat(k)/ninp
              if((ainlin.gt.0.).and.(ainlin.lt.1.))then
                ainl=nsct*qbeta(ainlin,ninp,nsct-ninp)/ninp
              else
                ainl=abs(ainlin)
              endif
	      khat=max(float(khat),log(ainl/ainl1)/log(2.)+1.)
            endif
            call ssort(xindex,hat,nsect,2)
            write(19,*)' hat matrix iterations=',khat
            do 500 i=1,nsect
              llo(i)=llo1(i)
              lhi(i)=lhi1(i)
              what(i)=0.
  500         if((wt1(i).gt.0.).and.lwt(i))what(i)=1.
            do 560 k=1,khat
c
c  begin hat matrix weight loop
c
              ainu1=max(ainu1/2.,ainu)
              ainl1=min(2.*ainl1,ainl)
              write(19,*)' lower cutoff=',ainl1,' upper cutoff=',ainu1
              do 550 niter=1,10
c
c begin huber regression weight loop
c
                write(19,*)' huber iteration=',niter,' scale=',scale
                if((ainlin.ne.-999.).or.(ainuin.ne.-999.))
     $            call hatwt(nsect,ninp,ainl1,ainu1,llo,lhi,hat,what)
                call huberwt(nsect,scale,lwt,res,w)
                do 510 i=1,nsect
  510             wt(i)=wt1(i)*what(i)*w(i)
c
c  compute robust transfer function
c
                call response(nsect,nout,ninp,nn,wt,ffts(1,1,nf),b,
     $                        aa,bb,info)
                if(info.eq.1)then
                  write(19,*)
     $                  ' WARNING-singular matrix detected in',
     $                  '  huber section'
                  write(19,*)' niter=',niter
                endif
c
c  compute residuals
c
                call residual(nsect,nout,ninp,nn,ffts(1,1,nf),
     $                        b,wt,nw,res,resq)
c
c  compute robust scale estimate
c
                nr=0
                do 540 i=1,nsect
                  if(wt(i).gt.0.)then
                    nr=nr+1
                    temp(nr)=res(i)
                  endif
  540             continue
                if(nr.eq.0)goto 770
                call mad(nr,temp,scale)
                if((ainlin.ne.-999.).or.(ainuin.ne.-999.))then
c
c  compute hat matrix diagonal
c
                  call hatdiag(nsect,ninp,ffts(1,nout+ninp+1,nf),
     $                         wt,hat,info)
                  if(info.ne.0)then
                    write(19,*)
     $                ' WARNING-pivot block singular in huber call',
     $                ' to hatdiag'
                    write(19,*)' info=',info,' niter=',niter
                  endif
                endif
                write(19,*)' normalized residual sum of squares=',
     $                       abs(resq-oresq)/abs(resq)
                if(abs(resq-oresq).lt.2.*eps*abs(resq))
     $             goto 555
  550           oresq=resq
              write(19,*)
     $              ' WARNING-huber iterations did not converge',
     $              ' at hat matrix iteration=',k
  555         oresq=resq
              write(19,*)' number of data=',nw
              write(19,*)
     $              ' huber solution vector indexed by input variable'
              do 560 i=1,ninp
                ob(i)=b(i)
  560           write(19,*)i,cmplx(b(i))
c
c  thomson weight regression section
c
            if(.not.ilev)then
              if((uin.eq.0.).or.(abs(uin).ge.1.))then
                u0=sqrt(2.*log(xnsct/(abs(uin)+0.5)))
              elseif((abs(uin).gt.0.).and.(abs(uin).lt.1.))then
                u0=sqrt(-2.*log(1.-abs(uin)))
              endif
            else
              if((uin.eq.0.).or.(uin.ge.1.))then
                u0=sqrt(2.*log(xnsct/(uin+0.5)))
              elseif((uin.gt.0.).and.(uin.lt.1.))then
                u0=sqrt(-2.*log(1.-uin))
              else
                u0=abs(uin)
              endif
            endif
            if((ainlin.ne.-999.).or.(ainuin.ne.-999.))
     $        call hatwt(nsect,ninp,ainl,ainu,llo,lhi,hat,what)
            call expwt(nsect,u0,scale,lwt,res,w)
            do 565 i=1,nsect
  565         wt(i)=wt1(i)*what(i)*w(i)
            do 600 niter=1,15
c
c  begin iteration on thomson regression weights
c
              write(19,*)
     $              ' thomson iteration=',niter,' scale=',scale
c
c  compute robust transfer function
c
              call response(nsect,nout,ninp,nn,wt,ffts(1,1,nf),b,
     $                      aa,bb,info)
              if(info.eq.1)then
                write(19,*)
     $                ' WARNING-singular matrix detected in thomson',
     $                '  section'
              endif
c
c  compute residuals
c
              call residual(nsect,nout,ninp,nn,ffts(1,1,nf),
     $                      b,wt,nw,res,resq)
              write(19,*)' number of data=',nw
              write(19,*)
     $              ' thomson solution vector indexed by input variable'
              do 570 i=1,ninp
  570           write(19,*)i,cmplx(b(i))
              write(19,*)' normalized residual sum of squares=',
     $                     abs(resq-oresq)/abs(resq)
c
c  compute robust scale estimate
c
c              if(niter.le.2)then
              if(niter.eq.1)then
                nr=0
                do 575 i=1,nsect
                  if(wt(i).gt.0.)then
                    nr=nr+1
                    temp(nr)=res(i)
                  endif
  575             continue
                if(nr.eq.0)goto 770
                call mad(nr,temp,scale)
              endif
c
c  compute hat matrix diagonal
c
              call hatdiag(nsect,ninp,ffts(1,nout+ninp+1,nf),
     $                     wt,hat,info)
              if(info.ne.0)then
                write(19,*)
     $                ' WARNING-pivot block singular in',
     $                ' thomson call to hatdiag'
                write(19,*)' info=',info,' niter=',niter
              endif
              if((ainuin.ne.-999.).or.(ainlin.ne.-999.))
     $          call hatwt(nsect,ninp,ainl,ainu,llo,lhi,hat,what)
	      call expwt(nsect,u0,scale,lwt,res,w)
	      do 580 i=1,nsect
  580           wt(i)=wt1(i)*what(i)*w(i)
c
c  compute jackknife estimate of transfer function standard error
c
c
c  compute delete one solutions for transfer functions
c
              call delone2(nsect,nout,ninp,nn,ffts(1,1,nf),wt,aa,
     $                     bb,hd1,info)
	      if(info.ne.0)then
	        write(19,*)
     $              ' WARNING-singular matrix detected in robust',
     $              ' jackknife niter=',niter
              endif
c
c  form jackknife variance excluding values with zero weights
c
              do 590 ii=1,ninp
	        var=0.
	        nw=0
	        do 585 i=1,nsect
	          if(wt(i).gt.0.)then
	            nw=nw+1
		    var=var+abs((1.-hat(i))*(b(ii)-hd1(ii,i)))**2
                  endif
  585         continue
  590         varr2(nn,ii,nfl)=nw*var/(nw-ninp)
	      cflag1=.true.
	      do 595 i=1,ninp
		sdev=sqrt(varr2(nn,i,nfl))
		if((abs(dreal(ob(i)-b(i))).ge.eps1*sdev).or.
     $             (abs(dimag(ob(i)-b(i))).ge.eps1*sdev))
     $             cflag1=.false.
  595           ob(i)=b(i)
		cflag2=.false.
		if((abs(real(resq-oresq)).lt.eps*real(resq)).and.
     $             (abs(aimag(resq-oresq)).lt.eps*aimag(resq)))
     $             cflag2=.true.
c	      if((niter.gt.1).and.(cflag1.or.cflag2))goto 610
	      if(cflag1.or.cflag2)goto 610
  600         oresq=resq
	    convflag2(nn,nfl)=1
	    write(19,*)' WARNING-thomson iterations did not converge'
  610       if(cflag1)write(19,*)' convergence on response'
	    if(cflag2)write(19,*)' convergence on residuals'
	    do 620 i=1,ninp
  620         hr(nn,i,nfl)=b(i)
c
c  compute complex coherence between measured and predicted output variables
c
            call ccoher2(nsect,nout,ninp,nn,ffts(1,1,nf),hr(nn,1,nfl),
     $                  hd1,wt,gd1,gr2(nn,nfl),gr2lo(nn,nfl),
     $                  gr2hi(nn,nfl))
	    wtsum=0.
	    do 640 i=1,nsect
  640         wtsum=wtsum+wt(i)
	    dfr2(nn,nfl)=2.*dofscal*(wtsum-ninp)
	    fracdat2(nn,nfl)=fracthresh2(nn,nfl)*wtsum/xnsct
	    if((fracdat2(nn,nfl).ne.0.).and.(nlev.lt.0))then
	      write(32+nn)freq(nfl),nsect
	      write(32+nn)(hat(i),wt(i),(hd1(j,i),j=1,ninp),
     $                     i=1,nsect)
	    endif
c
c  output robust diagnostics as required
c
	    if(abs(nlev).ge.1)then
	      filnam=ofil(l1:l2)//'.'//char(48+nn)//
     $               '.fq2.'//cn(m1:m2)
              call qqout(filnam,deltat/freq(nfl),nsect,nsct,nw,
     $                   ninp,llo,lhi,wt,res,hat)
	    endif
	    if(abs(nlev).eq.3)then
	      filnam=ofil(l1:l2)//'.'//char(48+nn)//'.fr2.'//
     $               cn(m1:m2)
              call diagout(filnam,deltat/freq(nfl),nsect,ninp,
     $                     res,pwro,pwri,wt,hat)
	    endif
  760       if(abs(nlev).ge.2)then
	      filnam=ofil(l1:l2)//'.'//char(48+nn)//
     $               '.wt.'//cn(m1:m2)
	      open (unit=40,file=filnam,status='unknown')
	      if(nrr.eq.0)then
		do 764 ii=1,nsect/nblk
		  do 762 i=1,nblk
                    k=(ii-1)*nblk+i
		    write(40,999)deltat*(xnfft/2.+float(k-1)*noff),
     $                           c2e(ii,nn),w(k),what(k)
  762               continue
  764             continue
	      else
		do 768 ii=1,nsect/nblk
		  do 766 i=1,nblk
                    k=(ii-1)*nblk+i
	            write(40,999)deltat*(xnfft/2.+float(k-1)*noff),
     $                           c2e(ii,nn),(c2b(ii,j),j=1,ninp),
     $                           wt1(k),wt(k)
  766               continue
  768             continue
	      endif
	      close (unit=40)
	    endif
  770       continue
	  nfl=nfl+1
  780     continue
	nfft=nfft/nsctinc
  790   continue
c
c  output section
c
      do 902 n=1,nout
        if(nlev.lt.0)close(unit=32+n)
  902   continue
c
c sort output frequencies into ascending order
c
      do 905 i=1,nfl-1
  905   xindex(i)=i
      call ssort(freq,xindex,nfl-1,2)
      do 906 i=1,nfl-1
  906   nfr(i)=xindex(i)
      do 950 n=1,nout
	do 930 j=1,ninp
	  postfix='.'//char(48+n)//'n'//char(48+j)//'.rf'
	  call strlen(postfix,m1,m2)
	  filnam=ofil(l1:l2)//postfix(m1:m2)
	  open (unit=10,file=filnam,status='unknown')
	  do 910 i=1,nfl-1
	    ii=nfr(i)
	    if(fracthresh2(n,ii).ne.0.)then
	      write(10,999)deltat/freq(ii),freq(ii)/deltat,
     $                     real(hn(n,j,ii)),aimag(hn(n,j,ii)),
     $                     sqrt(varn2(n,j,ii)),dfn2(n,ii),
     $                     fracthresh2(n,ii)
	    endif
  910       continue
	  close (unit=10)
	  if(uin.ne.-999.)then
	    postfix='.'//char(48+n)//'r'//char(48+j)//'.rf'
	    filnam=ofil(l1:l2)//postfix(m1:m2)
            open (unit=10,file=filnam,status='unknown')
	    do 915 i=1,nfl-1
	      ii=nfr(i)
	      if(fracdat2(n,ii).ne.0.)then
		write(10,1000)deltat/freq(ii),freq(ii)/deltat,
     $                        real(hr(n,j,ii)),aimag(hr(n,j,ii)),
     $                        sqrt(varr2(n,j,ii)),dfr2(n,ii),
     $                        fracthresh2(n,ii),fracdat2(n,ii),
     $                        convflag2(n,ii)
	      endif
  915         continue
	    close (unit=10)
	  endif
	  if(n.le.2)then
	    postfix='.'//char(48+n)//'n'//char(48+j)//'.rp'
	    filnam=ofil(l1:l2)//postfix(m1:m2)
	    open (unit=10,file=filnam,status='unknown')
	    do 920 i=1,nfl-1
	      ii=nfr(i)
	      if(fracthresh2(n,ii).ne.0.)then
                sdev=sqrt(varn2(n,j,ii))
                if(2.24*sdev/abs(hn(n,j,ii)).lt.1.)then
                  write(10,1000)deltat/freq(ii),freq(ii)/deltat,
     $                   0.2*deltat/freq(ii)*abs(hn(n,j,ii))**2,
     $                   0.896*deltat/freq(ii)*abs(hn(n,j,ii))*
     $                   sdev,atan2(aimag(hn(n,j,ii)),
     $                   real(hn(n,j,ii)))/rad,
     $                   asin(2.24*sdev/abs(hn(n,j,ii)))/rad,
     $                   dfn2(n,ii),fracthresh2(n,ii)
                else
                  write(10,1000)deltat/freq(ii),freq(ii)/deltat,
     $                   0.2*deltat/freq(ii)*abs(hn(n,j,ii))**2,
     $                   0.896*deltat/freq(ii)*abs(hn(n,j,ii))*
     $                   sdev,atan2(aimag(hn(n,j,ii)),
     $                   real(hn(n,j,ii)))/rad,180.0,
     $                   dfn2(n,ii),fracthresh2(n,ii)
                endif
	      endif
  920         continue
	    close (unit=10)
	  endif
	  if((uin.ne.-999.).and.(n.le.2))then
	    postfix='.'//char(48+n)//'r'//char(48+j)//'.rp'
	    filnam=ofil(l1:l2)//postfix(m1:m2)
	    open (unit=10,file=filnam,status='unknown')
	    do 925 i=1,nfl-1
	      ii=nfr(i)
	      if(fracdat2(n,ii).ne.0.)then
                sdev=sqrt(varr2(n,j,ii))
                if(2.24*sdev/abs(hr(n,j,ii)).lt.1.)then
                  write(10,1001)deltat/freq(ii),freq(ii)/deltat,
     $                     0.2*deltat/freq(ii)*abs(hr(n,j,ii))**2,
     $                     0.896*deltat/freq(ii)*abs(hr(n,j,ii))*
     $                     sdev,atan2(aimag(hr(n,j,ii)),
     $                     real(hr(n,j,ii)))/rad,
     $                     asin(2.24*sdev/abs(hr(n,j,ii)))/rad,
     $                     dfr2(n,ii),fracthresh2(n,ii),
     $                     fracdat2(n,ii),convflag2(n,ii)
                else
                  write(10,1001)deltat/freq(ii),freq(ii)/deltat,
     $                     0.2*deltat/freq(ii)*abs(hr(n,j,ii))**2,
     $                     0.896*deltat/freq(ii)*abs(hr(n,j,ii))*
     $                     sdev,atan2(aimag(hr(n,j,ii)),
     $                     real(hr(n,j,ii)))/rad,
     $                     180.,dfr2(n,ii),fracthresh2(n,ii),
     $                     fracdat2(n,ii),convflag2(n,ii)
                endif
	      endif
  925         continue
	      close (unit=10)
	    endif
  930     continue
	  postfix='.'//char(48+n)//'n.2c2'
	  call strlen(postfix,m1,m2)
	  filnam=ofil(l1:l2)//postfix(m1:m2)
	  open (unit=10,file=filnam,status='unknown')
	  do 935 i=1,nfl-1
	    ii=nfr(i)
	    if(fracthresh2(n,ii).ne.0.)then
	      write(10,999)deltat/freq(ii),freq(ii)/deltat,
     $                   abs(gn2(n,ii))**2,phase(gn2(n,ii)),
     $                   1.-.05**(2./(dfn2(n,ii)-2.)),
     $                   gn2lo(n,ii)**2,gn2hi(n,ii)**2,dfn2(n,ii),
     $                   fracthresh2(n,ii)
	    endif
  935       continue
	  close (unit=10)
	  if(uin.ne.-999.)then
            postfix='.'//char(48+n)//'r.2c2'
	    filnam=ofil(l1:l2)//postfix(m1:m2)
	    open (unit=10,file=filnam,status='unknown')
	    do 940 i=1,nfl-1
	      ii=nfr(i)
	      if(fracdat2(n,ii).ne.0.)then
	        write(10,999)deltat/freq(ii),freq(ii)/deltat,
     $                     abs(gr2(n,ii))**2,phase(gr2(n,ii)),
     $                     1.-.05**(2./(dfr2(n,ii)-2.)),
     $                     gr2lo(n,ii)**2,gr2hi(n,ii)**2,dfr2(n,ii),
     $                     fracthresh2(n,ii),fracdat2(n,ii)
	      endif
  940         continue
	    close (unit=10)
	  endif
  950   continue
      if(nrr.eq.1)then
	do 980 n=1,ninp
	  do 955 j=1,nref
	    postfix='.'//char(48+n)//'n'//char(48+j)//'.tf'
	    call strlen(postfix,m1,m2)
	    filnam=ofil(l1:l2)//postfix(m1:m2)
	    open (unit=10,file=filnam,status='unknown')
	    do 955 i=1,nfl-1
	      ii=nfr(i)
	      if(fracthresh1(n,ii).ne.0.)then
	        write(10,999)deltat/freq(ii),freq(ii)/deltat,
     $                       real(tbn(n,j,ii)),aimag(tbn(n,j,ii)),
     $                       sqrt(varn1(n,j,ii)),dfn1(n,ii),
     $                       fracthresh1(n,ii)
	      endif
  955         continue
	    close (unit=10)
	    if(uin.ne.-999.)then
	      do 960 j=1,nref
	        postfix='.'//char(48+n)//'r'//char(48+j)//'.tf'
	        filnam=ofil(l1:l2)//postfix(m1:m2)
                open (unit=10,file=filnam,status='unknown')
	        do 960 i=1,nfl-1
	          ii=nfr(i)
	          if(fracdat1(n,ii).ne.0.)then
		    write(10,1000)deltat/freq(ii),freq(ii)/deltat,
     $                            real(tbr(n,j,ii)),aimag(tbr(n,j,ii)),
     $                            sqrt(varr1(n,j,ii)),dfr1(n,ii),
     $                            fracthresh1(n,ii),fracdat1(n,ii),
     $                            convflag1(n,ii)
	          endif
  960             continue
	      close (unit=10)
	    endif
	    postfix='.'//char(48+n)//'n.1c2'
	    call strlen(postfix,m1,m2)
	    filnam=ofil(l1:l2)//postfix(m1:m2)
	    open (unit=10,file=filnam,status='unknown')
	    do 965 i=1,nfl-1
	      ii=nfr(i)
	      if(fracthresh1(n,ii).ne.0.)then
	        write(10,999)deltat/freq(ii),freq(ii)/deltat,
     $                       abs(gn1(n,ii))**2,phase(gn1(n,ii)),
     $                       1.-.05**(2./(dfn1(n,ii)-2.)),
     $                       gn1lo(n,ii)**2,gn1hi(n,ii)**2,dfn1(n,ii),
     $                       fracthresh1(n,ii)
	      endif
  965         continue
	    close (unit=10)
	    if(uin.ne.-999.)then
              postfix='.'//char(48+n)//'r.1c2'
	      filnam=ofil(l1:l2)//postfix(m1:m2)
	      open (unit=10,file=filnam,status='unknown')
	      do 970 i=1,nfl-1
	        ii=nfr(i)
	        if(fracdat1(n,ii).ne.0.)then
	          write(10,999)deltat/freq(ii),freq(ii)/deltat,
     $                         abs(gr1(n,ii))**2,phase(gr1(n,ii)),
     $                         1.-.05**(2./(dfr1(n,ii)-2.)),
     $                         gr1lo(n,ii)**2,gr1hi(n,ii)**2,dfr1(n,ii),
     $                         fracthresh1(n,ii),fracdat1(n,ii)
	        endif
  970           continue
	      close (unit=10)
            endif
  980     continue
        endif
        if(uin.ne.-999)then
          write(18,'(2a)')'>LATITUDE  = ',cvar(1)
          write(18,'(2a)')'>LONGITUDE = ',cvar(2)
          write(18,'(2a)')'>ELEVATION = ',cvar(3)
          write(18,'(a,g15.7)')'>AZIMUTH   = ',phi(1)
          write(18,'(a)')ofil
          do 985 n=1,nout
	    do 985 j=1,2
              write(18,'(a)')jlabel2(n,j)
	      write(18,'(i2)')nfl-1
              do 985 i=nfl-1,1,-1
                ii=nfr(i)
	        if(fracdat2(n,ii).ne.0.)then
		  write(18,999)deltat/freq(ii),real(hr(n,j,ii)),
     $			       aimag(hr(n,j,ii)),sqrt(varr2(n,j,ii)),
     $                         fracthresh2(n,ii),fracdat2(n,ii)
	        else
	          write(18,999)-999.,-999.,-999.,
     $                         -999.,-999.,-999.
	        endif
 985	        continue
          do 987 n=1,2
    	    do 987 j=1,2
	      write(18,'(a)')jlabel1(n,j)
	      write(18,'(i2)')nfl-1
              do 987 i=nfl-1,1,-1
                ii=nfr(i)
                if(fracdat2(n,ii).ne.0.)then
		  rho=0.2*deltat/freq(ii)*abs(hr(n,j,ii))**2
                  ph=atan2(aimag(hr(n,j,ii)),real(hr(n,j,ii)))/rad
                  sdev=sqrt(varr2(n,j,ii))
		  drho=0.4*deltat/freq(ii)*abs(hr(n,j,ii))*sdev
                  if(sdev/abs(hr(n,j,ii)).lt.1.)then
		    dph=asin(sdev/abs(hr(n,j,ii)))/rad
                    write(18,999)deltat/freq(ii),rho,ph,rho+drho,
     $                           rho-drho,ph+dph,ph-dph,
     $                           fracthresh2(n,ii),fracdat2(n,ii)
                  else
                    write(18,999)deltat/freq(ii),rho,ph,rho+drho,
     $                           rho-drho,ph+180.,ph-180.,
     $                           fracthresh2(n,ii),fracdat2(n,ii)
                  endif
	        else
	          write(18,999)-999.,-999.,-999.,-999.,-999.,
     $                         -999.,-999.,-999.,-999.
	        endif
  987           continue
        close(unit=18)
      endif
  996 format(3(a,i8))
  997 format(a,5i8)
  998 format(3(a,g15.7))
  999 format(1x,12g15.7)
 1000 format(1x,8g15.7,1x,i1)
 1001 format(1x,9g15.7,1x,i1)
      end
<file_sep>      subroutine huberwt(nsect,scale,lwt,res,w)
c
c  birrp
c
c  computes huber weights based on regression residuals
c
c  input variables
c    nsect-number of sections
c    scale-robust estimate of scale
c    lwt-logical vector, .true. if datum is used
c    res-vector of absolute value of residuals
c  output variable
c    w-vector of weights
c
      logical lwt
      dimension lwt(*),res(*),w(*)
      do 10 i=1,nsect
        if(.not.lwt(i))then
          w(i)=0.
        else
          t=res(i)/scale
          if(t.le.1.5)then
            w(i)=1.
          else
            w(i)=1.5/t
          endif
        endif
   10   continue
      return
      end
      subroutine expwt(nsect,u0,scale,lwt,res,w)
c
c  birrp
c
c  computes exponential (thomson) weights based on regression residuals
c
c  input variables
c    nsct-number of sections
c    u0-parameter for exponential weights
c    scale-robust estimate of scale
c    lwt-logical vector, .true. if datum is used
c    res-vector of absolute value of residuals
c  output variable
c    w-vector of weights
      logical lwt
      dimension lwt(*),res(*),w(*)
      small=r1mach(1)
      big=log(-log(small)/.05129329)
c  coefficient sets the 0.95 point to res/scale=u0
      sw=exp(-.05129329*exp(-u0**5))
      do 10 i=1,nsect
        if(.not.lwt(i))then
          w(i)=0.
        else
          t=u0**4*(res(i)/scale-u0)
          if(t.lt.big)then
            w(i)=exp(-.05129329*exp(t))/sw
          else
            w(i)=0.
          endif
        endif
   10   continue
      return
      end
      subroutine hatwt(nsect,ninp,ainl,ainu,llo,lhi,hat,what)
c
c  birrp
c
c  computes leverage weights based on size of hat matrix diagonal relative
c  to its expected value
c
c  input variables
c    nsect-number of sections
c    ninp-number of inputs
c    ainl-lower cutoff
c    ainu-upper cutoff
c    llo-logical vector denoting data deleted at lower end of distribution,
c        changed on return
c    lhi-logical vector denoting data deleted at upper end of distribution,
c        changed on return
c    hat-vector of hat matrix diagonal entries
c  output variables
c    what-vector of weights
c
      logical llo,lhi
      dimension llo(*),lhi(*)
      dimension hat(*),what(*)
      small=r1mach(1)
      big=log(-log(small)/.05129329)
      nw=0
      do 5 i=1,nsect
        if(what(i).ne.0.)nw=nw+1
    5   continue
      xnw=nw
      if(ainu.le.0.)goto 20
      ains=ainu
      if(ains.lt.1.)ains=1./ains
      swhat=exp(-.05129329*exp(-ainu*ains**4))
      do 10 i=1,nsect
        if(what(i).eq.0.)goto 10
        t=ains**4*(xnw*hat(i)/ninp-ainu)
        if(t.lt.big)then
          owhat=what(i)
          what(i)=what(i)*exp(-.05129329*exp(t))/swhat
          if((owhat.ne.0.).and.(what(i).eq.0.))lhi(i)=.true.
        else
          what(i)=0.
          lhi(i)=.true.
        endif
  10    continue
  20  if(ainl.le.0.)return
      ains=ainl
      if(ains.gt.1.)ains=1./ains
      swhat=exp(-.05129329*exp(-ainl/ains**4))
      do 30 i=1,nsect
        if(what(i).eq.0.)goto 30
        t=(xnw*hat(i)/ninp-ainl)/ains**4
        if(t.lt.big)then
          owhat=what(i)
          what(i)=what(i)*(1.-exp(-.05129329*exp(t))/swhat)
          if((owhat.ne.0.).and.(what(i).eq.0.))llo(i)=.true.
        endif
  30    continue
      return
      end
      subroutine mad(nsect,res,scale)
c
c  birrp
c
c  computes median absolute deviation for a Rayleigh variate
c
c  input variables:
c
c  nsect--number of entries in res
c  res--vector of residual magnitudes (overwritten on return)
c
c  output variables:
c
c  scale-mad of entries in res
c
      dimension res(*)
      call ssort(res,res,nsect,1)
      ni = nsect
      do 20 i=1,nsect
        if(res(i).gt.0.)then
          ni=i
          goto 21
        endif
   20   continue
   21 nl=nsect-ni+1
      if(mod(nl,2).eq.0.)then
        xmed=(res(nl/2+ni-1)+res(nl/2+ni))/2.
      else
        xmed=res(nl/2+ni)
      endif
      do 30 i=ni,nsect
   30   res(i)=abs(res(i)-xmed)
      call ssort(res(ni),res(ni),nl,1)
      if(mod(nl,2).eq.0)then
        scale=(res(nl/2+ni-1)+res(nl/2+ni))/.8969
      else
        scale=res(nl/2+ni)/.44845
      endif
      return
      end
      subroutine hatdiag(nsct,ninp,ftsec,wt,hat,info)
c
c  birrp
c
c  computes diagonal of hat matrix
c
c  input variables:
c
c  nsct--number of sections
c  ninp--number of variables
c  ftsec--complex array containing nsct section ffts for ninp variables
c  wt--weight vector
c
c  output variables:
c
c  hat--vector containing hat matrix diagonal
c  info--error flag, 0 for normal, otherwise as returned by zhifa
c
      include 'parameters.h'
      double precision det
      complex ftsec
      double complex a,atemp,zz
      dimension ftsec(nsectm,*),wt(*),hat(*)
      dimension a(nrefm,nrefm),ipvt(nrefm),det(2),zz(nrefm)
      info=0
      do 10 i=1,ninp
        do 10 j=i,ninp
          a(i,j)=0.
          do 10 ii=1,nsct
   10       a(i,j)=a(i,j)+wt(ii)**2*conjg(ftsec(ii,i))*ftsec(ii,j)
      call zhifa(a,nrefm,ninp,ipvt,info)
      job=001
      call zhidi(a,nrefm,ninp,ipvt,det,inert,zz,job)
      do 20 i=1,ninp
        do 20 j=i+1,ninp
   20     a(j,i)=conjg(a(i,j))
      do 30 j=1,nsct
        hat(j)=0.
        do 30 i=1,ninp
          atemp=0.
          do 25 jj=1,ninp
   25       atemp=atemp+a(i,jj)*wt(j)*conjg(ftsec(j,jj))
   30     hat(j)=hat(j)+wt(j)*real(ftsec(j,i)*atemp)
      return
      end
      subroutine residual(nsect,nout,ninp,nn,ftsec,h,wt,nw,res,resq)
c
c  birrp
c
c  returns residuals and residual sum of squares
c
c  input variables
c
c   nsect--number of sections
c   nout--number of output variables
c   ninp--number of input variables
c   nn--index of output variable
c   ftsec--complex nsect by nout+ninp array containing fourier transforms
c   h--double complex vector containing ninp transfer function estimates
c   wt--vector of weights
c
c  returned variables
c
c  nw--number of residuals with nonzero weights
c  res--vector of absolute residuals
c  resq--normalized residual sum of squares
c
      include 'parameters.h'
      complex ftsec,resq
      double complex h,ctmp,resq1
      dimension ftsec(nsectm,*),h(*),wt(*),res(*)
      resq1=0.
      nw=0
      do 20 n=1,nsect
        ctmp=ftsec(n,nn)
        if(wt(n).gt.0.)nw=nw+1
        do 10 i=1,ninp
   10     ctmp=ctmp-h(i)*ftsec(n,nout+i)
        resq1=resq1+wt(n)**2*dcmplx(dreal(ctmp)**2,dimag(ctmp)**2)
   20   res(n)=abs(ctmp)
      resq=resq1/nw
      return
      end
      subroutine delone1(nsect,ninp,nref,nn,ftsec,wt,aa,bb,hd1,info)
c
c  birrp
c
c  computes delete one magnetic transfer transfer functions
c
c  input variables:
c
c  nsect--number of sections
c  ninp-number of local magnetic field time series
c  nref--number of reference time series
c  nn--index of local time series
c  ftsec--complex array of section ffts
c  wt--vector of weights
c  aa-double complex array containing input spectral matrix
c  bb-double complex vector containing input/output spectral matrix
c
c  output variables:
c
c  hd1--complex array of delete one responses
c  info-error flag, 0 for normal return, as returned by zgeco otherwise
c
      include 'parameters.h'
      complex ftsec,hd1
      double complex aa,bb,a,b,zz
      double precision rcond
      dimension ftsec(nsectm,*),aa(nrefm,*),bb(*),
     $          wt(*),hd1(nrefm+1,*)
      dimension a(nrefm,nrefm),b(nrefm),ipvt(nrefm),zz(nrefm)
      info=0
      do 10 ii=1,nsect
        do 5 i=1,nref
          b(i)=bb(i)-wt(ii)**2*conjg(ftsec(ii,ninp+i))*
     $         ftsec(ii,nn)
          do 5 j=1,nref
    5       a(i,j)=aa(i,j)-wt(ii)**2*conjg(ftsec(ii,ninp+i))*
     $             ftsec(ii,ninp+j)
          call zgeco(a,nrefm,nref,ipvt,rcond,zz)
          if(1.d0+rcond.eq.1.d0)info=1
          job=0
          call zgesl(a,nrefm,nref,ipvt,b,job)
          do 10 i=1,nref
  10        hd1(i,ii)=b(i)
      return
      end
      subroutine delone2(nsect,nout,ninp,nn,ftsec,wt,aa,bb,hd1,info)
c
c  birrp
c
c  computes delete one transfer functions
c
c  input variables:
c
c  nsect--number of sections
c  nout-number of output time series
c  ninp--number of input time series
c  nn--index of output time series
c  ftsec--complex array of nsect section ffts
c  wt--vector of weights
c  aa-double complex array containing input spectral matrix
c  bb-double complex vector containing input/output spectral matrix
c
c  output variables:
c
c  hd1--complex array of delete one responses
c  info-error flag, 0 for normal return, as returned by zgeco otherwise
c
      include 'parameters.h'
      complex ftsec,hd1
      double complex aa,bb,a,b,zz
      double precision rcond
      dimension ftsec(nsectm,*),aa(nrefm,*),bb(*),
     $          wt(*),hd1(nrefm+1,*)
      dimension a(ninpm,ninpm),b(ninpm),ipvt(ninpm),zz(ninpm)
      info=0
      do 10 ii=1,nsect
        do 5 i=1,ninp
          b(i)=bb(i)-wt(ii)**2*conjg(ftsec(ii,nout+ninp+i))*
     $         ftsec(ii,nn)
          do 5 j=1,ninp
    5       a(i,j)=aa(i,j)-wt(ii)**2*conjg(ftsec(ii,nout+ninp+i))*
     $             ftsec(ii,nout+j)
           call zgeco(a,ninpm,ninp,ipvt,rcond,zz)
          if(1.d0+rcond.eq.1.d0)info=1
          job=0
          call zgesl(a,ninpm,ninp,ipvt,b,job)
          do 10 i=1,ninp
  10        hd1(i,ii)=b(i)
      return
      end<file_sep>      subroutine response(nsect,nout,ninp,nn,wt,ftsec,b,aa,bb,info)
c
c  birrp
c
c  computes l2 response function
c
c  input variables
c    nsect-number of sections
c    nout-number of output variables
c    ninp-number of input variables
c    nn-index of output variable
c    wt-weight vector of length nsect
c    ftsec-array containing fourier transform estimates
c  output variables
c    b-double complex vector of transfer functions
c    aa-double complex array containing input spectral matrix
c    bb-double complex vector containing input/output cross spectra
c    info-error flag, 0 for normal return and 1 for singular matrix
c
      include 'parameters.h'
      double complex b,aa,bb
      complex ftsec
      double precision rcond
      dimension wt(*),ftsec(nsectm,*)
      dimension b(*),aa(nrefm,*),bb(*)
      double complex a,z
      dimension a(nrefm,nrefm),z(nrefm),ipvt(nrefm)
      info=0
      do 10 i=1,ninp
        b(i)=0.
        do 10 j=1,ninp
   10     a(i,j)=0.
      do 25 k=1,nsect
        if(wt(k).eq.0.)goto 25
        do 20 i=1,ninp
          b(i)=b(i)+wt(k)**2*conjg(ftsec(k,nout+ninp+i))*
     $         ftsec(k,nn)
          do 20 j=1,ninp
   20       a(i,j)=a(i,j)+wt(k)**2*conjg(ftsec(k,nout+ninp+i))*
     $             ftsec(k,nout+j)
   25   continue
      do 30 i=1,ninp
        bb(i)=b(i)
        do 30 j=1,ninp
   30     aa(i,j)=a(i,j)
      call zgeco(a,nrefm,ninp,ipvt,rcond,z)
      if(1.d0+rcond.eq.1.d0)info=1
      job=0
      call zgesl(a,nrefm,ninp,ipvt,b,job)
      return
      end
      subroutine transfer(nsect,ninp,nref,nn,wt,ftsec,b,aa,bb,info)
c
c  birrp
c
c  computes l2 magnetic transfer function
c
c  input variables
c    nsect-number of sections
c    ninp-number of input (local magnetic field) variables
c    nref-number of reference magnetic field variables
c    nn-index of input variable
c    wt-weight vector of length nsect
c    ftsec-array containing fourier transform estimates
c  output variables
c    b-double complex vector of transfer functions
c    aa-double complex array containing input spectral matrix
c    bb-double complex vector containing input/output cross spectra
c    info-error flag, 0 for normal return and 1 for singular matrix
c
      include 'parameters.h'
      double complex b,aa,bb
      complex ftsec
      double precision rcond
      dimension wt(*),ftsec(nsectm,*)
      dimension b(*),aa(nrefm,*),bb(*)
      double complex a,z
      dimension a(nrefm,nrefm),z(nrefm),ipvt(nrefm)
      info=0
      do 10 i=1,nref
        b(i)=0.
        do 10 j=1,nref
   10     a(i,j)=0.
      do 25 k=1,nsect
        if(wt(k).eq.0.)goto 25
        do 20 i=1,nref
          b(i)=b(i)+wt(k)**2*conjg(ftsec(k,ninp+i))*
     $         ftsec(k,nn)
          do 20 j=1,nref
   20       a(i,j)=a(i,j)+wt(k)**2*conjg(ftsec(k,ninp+i))*
     $             ftsec(k,ninp+j)
   25   continue
      do 30 i=1,nref
        bb(i)=b(i)
        do 30 j=1,nref
   30     aa(i,j)=a(i,j)
      call zgeco(a,nrefm,nref,ipvt,rcond,z)
      if(1.d0+rcond.eq.1.d0)info=1
      job=0
      call zgesl(a,nrefm,nref,ipvt,b,job)
      return
      end
<file_sep>      subroutine strlen(string,i1,i2)
      character string*(*)
      do 10 i=len(string),1,-1
        if(string(i:i).ne.' ')then
          i2=i
          goto 11
        endif
   10   continue
   11 do 20 i=1,len(string)
        if(string(i:i).ne.' ')then
          i1=i
          return
        endif
   20   continue
      return
      end
<file_sep>      subroutine rarfilt(npts,nfft,nar,rdata,work,ar,istat)
c
c  birrp
c
c  computes nar term auotoregressive filter (leading 1 suppressed)
c  from robust acvs estimated from median of section averaged power spectrum using
c  tbw 4 data window
c
c  inputs:
c
c  npts  - number of data points in data
c  nfft  - length of section ffts, must be .le. npts
c  nar   - number of filter terms less leading 1, must be .le. nfft/2
c  rdata  - real vector of data
c  work  - real work vector of length at least 18*nfft+14*npts+7*npts/nfft+32
c
c  outputs:
c
c  ar    - vector of nar ar filter terms (leading 1 suppressed)
c  istat - error flag, 0 for normal return, 1 or 2 for error in call to rtpss, 3 or more
c          for ill-conditioned toeplitz matrix
c
      double precision theta
      dimension rdata(*),ar(*)
      double complex work(*)
      call rtpss(nfft,nfft,1,dble(4./float(nfft)),work,
     $           theta,istat,work(2*nfft+1))
      i1=1
      i2=2*nfft+i1
      i3=8*nfft+30+i2
      i4=7*npts/nfft+2+i3
      i5=4*nfft+i4
      call rarfilt1(npts,nfft,nar,rdata,work(i1),work(i2),
     $              work(i3),work(i4),work(i5),ar,istat)
      return
      end
      subroutine rarfilt1(npts,nfft,nar,rdata,dpss,wsave,
     $                    p,fft,ffts,ar,istat)
      implicit double precision (a-h,o-z)
      parameter (narm=100)
      real rdata,ar
      dimension rdata(*),ar(*)
      double complex dpss(*), wsave(*), p(*)
      double complex fft,ffts,t0,t1
      dimension fft(*),ffts(nfft,*)
      dimension r(narm+1),a(narm)
      noff=0.29*nfft+1
      nsect=float(npts-nfft-1)/float(noff)+1
      if(npts-((nsect-1)*noff+nfft+1).ge.nfft)nsect=nsect+1
      k=1
      nn=nsect/2
      do 5 i=1,nfft
    5   wsave(i)=0.d0
      call dcffti(nfft,wsave)
      do 30 n=1,2*nn,2
        do 10 i=1,nfft
          fft(i)=dpss(i)*dcmplx(rdata(k),rdata(k+noff))
   10     k=k+1
        call dcfftf(nfft,fft,wsave)
        ffts(1,n)=dreal(fft(1))
        ffts(1,n+1)=dimag(fft(1))
        do 20 i=1,nfft/2-1
          t0=fft(i+1)
          t1=fft(nfft-i+1)
          ffts(i+1,n)=0.5*(t0+conjg(t1))
          ffts(i+1,n+1)=-dcmplx(0.,0.5)*(t0-conjg(t1))
   20     continue
        ffts(nfft/2+1,n)=dreal(fft(nfft/2+1))
        ffts(nfft/2+1,n+1)=dimag(fft(nfft/2+1))
   30   k=k-nfft+2*noff
      if(mod(nsect,2).ne.0)then
        do 40 i=1,nfft
          fft(i)=dpss(i)*rdata(k)
   40     k=k+1
        call dcfftf(nfft,fft,wsave)
        do 60 i=1,nfft/2+1
          ffts(i,nsect)=fft(i)
   60     continue
       endif
       do 80 i=1,nfft/2+1
         do 70 j=1,nsect
  70       p(j)=abs(ffts(i,j))**2/nfft
         call dsort(p,p,nsect,1)
         if(mod(nsect,2).eq.0)then
           fft(i)=(p(nsect/2)+p(nsect/2+1))/2.
         else
           fft(i)=p(nsect/2+1)
         endif
  80     continue
      do 90 i=1,nfft/2-1
  90    fft(nfft-i+1)=fft(i+1)
      call dcfftb(nfft,fft,wsave)
      do 110 i=1,nar+1
        r(i)=dreal(fft(i))/nar
 110    continue
      call levinson(nar,r(1),r(2),pp,a,istat)
      if(istat.eq.1)istat=istat+3
      do 120 i=1,nar
 120    ar(i)=a(i)
      return
      end
      subroutine levinson(m,to,t,p,a,istat)
c  solves the set of linear simultaneous equations t*a=p
c  by the levinson algorithm. t is m+1 by m+1 toeplitz, a is a column
c  vector with elements 1,a(1)...a(m), and p is a column vector with p
c  as the top element and zeroes elsewhere.
c
c  input parameters
c
c  m  -- autoregressive order
c  to -- double precision scalar corresponding to matrix element t(0)
c  t  -- double precision vector of acvs lags and left column of toeplitz matrix
c
c  output parameters:
c
c  p  -- double precision scalar of top element of rhs (or ar driving noise)
c  a  -- double precision vector of solution for nar ar coefficients
c  istat--status indicator, 0 for normal exit and 1 for ill-conditioned problem
c
c  converted to real form from <NAME>, Digital Spectral Analysis with
c                              Applications,Prentice-Hall, 1987, pp. 104-105
      double precision to,t,p,a,temp,sav
      dimension t(*),a(*)
      p=to
      istat=0
      if(m.eq.0)return
      k=0
  100 k=k+1
      sav=t(k)
      if(k.eq.1)goto 20
      do 10 j=1,k-1
   10   sav=sav+a(j)*t(k-j)
   20 temp=-sav/p
      p=p*(1.d0-temp)*(1.d0+temp)
      if(p.gt.0.)goto 30
      istat=1
      return
   30 a(k)=temp
      if(k.eq.1)goto 50
      khalf=k/2
      do 40 j=1,khalf
        kj=k-j
        sav=a(j)
        a(j)=sav+temp*a(kj)
        if(j.eq.kj)goto 40
        a(kj)=a(kj)+temp*sav
   40   continue
   50 if(k.lt.m)goto 100
      return
      end
      subroutine prewhiten(npts,nar,rdata,ar,pdata)
c
c  birrp
c
c  prewhitens time series in data using ar filter in ar
c  returns npts-nar residuals starting at nar+1 in data
c
c  inputs:
c
c  npts  - number of data points in data, changed to npts-nar on return
c  nar   - number of filter terms less leading 1
c  rdata  - real vector of data
c  ar    - vector of nar ar filter terms (leading 1 is suppressed)
c
c  outputs:
c
c  pdata - real vector of prewhitened data of length npts-nar
c
      dimension rdata(*),ar(*),pdata(*)
      double precision sum
      do 140 i=nar+1,npts
        sum=dble(rdata(i))
        do 130 j=2,nar+1
 130     sum=sum+ar(j-1)*rdata(i-j+1)
 140    pdata(i-nar)=sum
      npts=npts-nar
      return
      end
      subroutine sft(x,n,om,ct,st)
c  calculates fourier transform of real sequence x(i),i=1,...n
c  at angular frequency om normalized so that nyquist=pi. the sine
c  transform is returned in st and the cosine transform in ct.
c  algorithm is that of goertzal with modifications by
c  gentleman, comp.j. 1969
c  transform is not normalized
c  to normalize one-sided ft, divide by sqrt(data length)
c  for positive om, the ft is defined as ct+(0.,1.)st or like slatec
c  cfftf
      implicit double precision (a-h,o-z)
      parameter (pi=3.141592653589793238d0,tp=2.d0*pi)
      dimension x(*)
      np1=n+1
      l=6.d0*om/tp
      s=sin(om)
      a=0.d0
      c=0.d0
      d=0.d0
      e=0.d0
      if(l.eq.0)then
c  recursion for low frequencies (.lt. nyq/3)
        s2=sin(om/2.d0)
        b=-4.d0*s2*s2
        do 10 k=1,n
          c=a
          d=e
          a=x(np1-k)+b*d+c
   10     e=a+d
      elseif(l.eq.1)then
c  regular goertzal algorithm for intermediate frequencies
        b=2.d0*cos(om)
        do 20 k=1,n
          a=x(np1-k)+b*e-d
          d=e
   20     e=a
      else
c  recursion for high frequencies (.gt. 2*nyq/3)
        c2=cos(om/2.d0)
        b=4.d0*c2*c2
        do 30 k=1,n
          c=a
          d=e
          a=x(np1-k)+b*d-c
   30     e=a-d
      endif
      st=-s*d
      ct=a-b*d/2.d0
      return
      end
<file_sep>      subroutine ssort(x,y,n,kflag)
c***begin prologue  ssort
c***date written   761101   (yymmdd)
c***revision date  820801   (yymmdd)
c***category no.  n6a2b1
c***keywords  quicksort,singleton quicksort,sort,sorting
c***author  <NAME>., (snla)
c           <NAME>., (snla)
c***purpose  ssort sorts array x and optionally makes the same
c            interchanges in array y.  the array x may be sorted in
c            increasing order or decreasing order.  a slightly modified
c            quicksort algorithm is used.
c***description
c
c     written by <NAME>
c     modified by <NAME> to use the singleton quicksort
c     algorithm.  date 18 november 1976.
c
c     abstract
c         ssort sorts array x and optionally makes the same
c         interchanges in array y.  the array x may be sorted in
c         increasing order or decreasing order.  a slightly modified
c         quicksort algorithm is used.
c
c     reference
c         singleton, r. c., algorithm 347, an efficient algorithm for
c         sorting with minimal storage, cacm,12(3),1969,185-7.
c
c     description of parameters
c         x - array of values to be sorted   (usually abscissas)
c         y - array to be (optionally) carried along
c         n - number of values in array x to be sorted
c         kflag - control parameter
c             =2  means sort x in increasing order and carry y along.
c             =1  means sort x in increasing order (ignoring y)
c             =-1 means sort x in decreasing order (ignoring y)
c             =-2 means sort x in decreasing order and carry y along.
c***references  singleton,r.c., algorithm 347, an efficient algorithm
c                 for sorting with minimal storage, cacm,12(3),1969,
c                 185-7.
c***routines called  none
c***end prologue  ssort
      parameter (nerr=19)
      include 'parameters.h'
      dimension x(*),y(*),il(21),iu(21)
c***first executable statement  ssort
      nn = n
      if (nn.ge.1) go to 10
      if(inter)
     $  write(6,*)' the number of values to be sorted was not positive'
      write(nerr,*)
     $        ' the number of values to be sorted was not positive'
      return
   10 kk = iabs(kflag)
      if ((kk.eq.1).or.(kk.eq.2)) go to 15
      return
c
c alter array x to get decreasing order if needed
c
   15 if (kflag.ge.1) go to 30
      do 20 i=1,nn
   20 x(i) = -x(i)
   30 go to (100,200),kk
c
c sort x only
c
  100 continue
      m=1
      i=1
      j=nn
      r=.375
  110 if (i .eq. j) go to 155
      if (r .gt. .5898437) go to 120
      r=r+3.90625e-2
      go to 125
  120 r=r-.21875
  125 k=i
c                                  select a central element of the
c                                  array and save it in location t
      ij = i + ifix (float (j-i) * r)
      t=x(ij)
c                                  if first element of array is greater
c                                  than t, interchange with t
      if (x(i) .le. t) go to 130
      x(ij)=x(i)
      x(i)=t
      t=x(ij)
  130 l=j
c                                  if last element of array is less thans
c                                  t, interchange with t
      if (x(j) .ge. t) go to 140
      x(ij)=x(j)
      x(j)=t
      t=x(ij)
c                                  if first element of array is greater
c                                  than t, interchange with t
      if (x(i) .le. t) go to 140
      x(ij)=x(i)
      x(i)=t
      t=x(ij)
      go to 140
  135 tt=x(l)
      x(l)=x(k)
      x(k)=tt
c                                  find an element in the second half ofs
c                                  the array which is smaller than t
  140 l=l-1
      if (x(l) .gt. t) go to 140
c                                  find an element in the first half of
c                                  the array which is greater than t
  145 k=k+1
      if (x(k) .lt. t) go to 145
c                                  interchange these elements
      if (k .le. l) go to 135
c                                  save upper and lower subscripts of
c                                  the array yet to be sorted
      if (l-i .le. j-k) go to 150
      il(m)=i
      iu(m)=l
      i=k
      m=m+1
      go to 160
  150 il(m)=k
      iu(m)=j
      j=l
      m=m+1
      go to 160
c                                  begin again on another portion of
c                                  the unsorted array
  155 m=m-1
      if (m .eq. 0) go to 300
      i=il(m)
      j=iu(m)
  160 if (j-i .ge. 1) go to 125
      if (i .eq. 1) go to 110
      i=i-1
  165 i=i+1
      if (i .eq. j) go to 155
      t=x(i+1)
      if (x(i) .le. t) go to 165
      k=i
  170 x(k+1)=x(k)
      k=k-1
      if (t .lt. x(k)) go to 170
      x(k+1)=t
      go to 165
c
c sort x and carry y along
c
  200 continue
      m=1
      i=1
      j=nn
      r=.375
  210 if (i .eq. j) go to 255
      if (r .gt. .5898437) go to 220
      r=r+3.90625e-2
      go to 225
  220 r=r-.21875
  225 k=i
c                                  select a central element of the
c                                  array and save it in location t
      ij = i + ifix (float (j-i) *r)
      t=x(ij)
      ty= y(ij)
c                                  if first element of array is greater
c                                  than t, interchange with t
      if (x(i) .le. t) go to 230
      x(ij)=x(i)
      x(i)=t
      t=x(ij)
       y(ij)= y(i)
       y(i)=ty
      ty= y(ij)
  230 l=j
c                                  if last element of array is less thans
c                                  t, interchange with t
      if (x(j) .ge. t) go to 240
      x(ij)=x(j)
      x(j)=t
      t=x(ij)
       y(ij)= y(j)
       y(j)=ty
      ty= y(ij)
c                                  if first element of array is greater
c                                  than t, interchange with t
      if (x(i) .le. t) go to 240
      x(ij)=x(i)
      x(i)=t
      t=x(ij)
       y(ij)= y(i)
       y(i)=ty
      ty= y(ij)
      go to 240
  235 tt=x(l)
      x(l)=x(k)
      x(k)=tt
      tty= y(l)
       y(l)= y(k)
       y(k)=tty
c                                  find an element in the second half ofs
c                                  the array which is smaller than t
  240 l=l-1
      if (x(l) .gt. t) go to 240
c                                  find an element in the first half of
c                                  the array which is greater than t
  245 k=k+1
      if (x(k) .lt. t) go to 245
c                                  interchange these elements
      if (k .le. l) go to 235
c                                  save upper and lower subscripts of
c                                  the array yet to be sorted
      if (l-i .le. j-k) go to 250
      il(m)=i
      iu(m)=l
      i=k
      m=m+1
      go to 260
  250 il(m)=k
      iu(m)=j
      j=l
      m=m+1
      go to 260
c                                  begin again on another portion of
c                                  the unsorted array
  255 m=m-1
      if (m .eq. 0) go to 300
      i=il(m)
      j=iu(m)
  260 if (j-i .ge. 1) go to 225
      if (i .eq. 1) go to 210
      i=i-1
  265 i=i+1
      if (i .eq. j) go to 255
      t=x(i+1)
      ty= y(i+1)
      if (x(i) .le. t) go to 265
      k=i
  270 x(k+1)=x(k)
       y(k+1)= y(k)
      k=k-1
      if (t .lt. x(k)) go to 270
      x(k+1)=t
       y(k+1)=ty
      go to 265
c
c clean up
c
  300 if (kflag.ge.1) return
      do 310 i=1,nn
  310 x(i) = -x(i)
      return
      end
      subroutine dsort (dx, dy, n, kflag)
c***begin prologue  dsort
c***purpose  sort an array and optionally make the same interchanges in
c            an auxiliary array.  the array may be sorted in increasing
c            or decreasing order.  a slightly modified quicksort
c            algorithm is used.
c***library   slatec
c***category  n6a2b
c***type      double precision (ssort-s, dsort-d, isort-i)
c***keywords  singleton quicksort, sort, sorting
c***author  <NAME>., (snla)
c           <NAME>., (snla)
c***description
c
c   dsort sorts array dx and optionally makes the same interchanges in
c   array dy.  the array dx may be sorted in increasing order or
c   decreasing order.  a slightly modified quicksort algorithm is used.
c
c   description of parameters
c      dx - array of values to be sorted   (usually abscissas)
c      dy - array to be (optionally) carried along
c      n  - number of values in array dx to be sorted
c      kflag - control parameter
c            =  2  means sort dx in increasing order and carry dy along.
c            =  1  means sort dx in increasing order (ignoring dy)
c            = -1  means sort dx in decreasing order (ignoring dy)
c            = -2  means sort dx in decreasing order and carry dy along.
c
c***references  r. c. singleton, algorithm 347, an efficient algorithm
c                 for sorting with minimal storage, communications of
c                 the acm, 12, 3 (1969), pp. 185-187.
c***end prologue  dsort
      parameter (nerr=19)
      include 'parameters.h'
      double precision dx(*), dy(*)
      double precision r, t, tt, tty, ty
      integer il(21), iu(21)
c***first executable statement  dsort
      nn = n
      if(nn.ge.1)goto 5
      if(inter)
     $  write(6,*)' the number of values to be sorted was not positive'
      write(nerr,*)
     $        ' the number of values to be sorted was not positive'
      return
c
    5 kk = abs(kflag)
      if((kk.eq.1).or.(kk.eq.2))goto 7
      return
c
c     alter array dx to get decreasing order if needed
c
    7 if (kflag .le. -1) then
         do 10 i=1,nn
            dx(i) = -dx(i)
   10    continue
      endif
c
      if (kk .eq. 2) go to 100
c
c     sort dx only
c
      m = 1
      i = 1
      j = nn
      r = 0.375d0
c
   20 if (i .eq. j) go to 60
      if (r .le. 0.5898437d0) then
         r = r+3.90625d-2
      else
         r = r-0.21875d0
      endif
c
   30 k = i
c
c     select a central element of the array and save it in location t
c
      ij = i + int((j-i)*r)
      t = dx(ij)
c
c     if first element of array is greater than t, interchange with t
c
      if (dx(i) .gt. t) then
         dx(ij) = dx(i)
         dx(i) = t
         t = dx(ij)
      endif
      l = j
c
c     if last element of array is less than than t, interchange with t
c
      if (dx(j) .lt. t) then
         dx(ij) = dx(j)
         dx(j) = t
         t = dx(ij)
c
c        if first element of array is greater than t, interchange with t
c
         if (dx(i) .gt. t) then
            dx(ij) = dx(i)
            dx(i) = t
            t = dx(ij)
         endif
      endif
c
c     find an element in the second half of the array which is smaller
c     than t
c
   40 l = l-1
      if (dx(l) .gt. t) go to 40
c
c     find an element in the first half of the array which is greater
c     than t
c
   50 k = k+1
      if (dx(k) .lt. t) go to 50
c
c     interchange these elements
c
      if (k .le. l) then
         tt = dx(l)
         dx(l) = dx(k)
         dx(k) = tt
         go to 40
      endif
c
c     save upper and lower subscripts of the array yet to be sorted
c
      if (l-i .gt. j-k) then
         il(m) = i
         iu(m) = l
         i = k
         m = m+1
      else
         il(m) = k
         iu(m) = j
         j = l
         m = m+1
      endif
      go to 70
c
c     begin again on another portion of the unsorted array
c
   60 m = m-1
      if (m .eq. 0) go to 190
      i = il(m)
      j = iu(m)
c
   70 if (j-i .ge. 1) go to 30
      if (i .eq. 1) go to 20
      i = i-1
c
   80 i = i+1
      if (i .eq. j) go to 60
      t = dx(i+1)
      if (dx(i) .le. t) go to 80
      k = i
c
   90 dx(k+1) = dx(k)
      k = k-1
      if (t .lt. dx(k)) go to 90
      dx(k+1) = t
      go to 80
c
c     sort dx and carry dy along
c
  100 m = 1
      i = 1
      j = nn
      r = 0.375d0
c
  110 if (i .eq. j) go to 150
      if (r .le. 0.5898437d0) then
         r = r+3.90625d-2
      else
         r = r-0.21875d0
      endif
c
  120 k = i
c
c     select a central element of the array and save it in location t
c
      ij = i + int((j-i)*r)
      t = dx(ij)
      ty = dy(ij)
c
c     if first element of array is greater than t, interchange with t
c
      if (dx(i) .gt. t) then
         dx(ij) = dx(i)
         dx(i) = t
         t = dx(ij)
         dy(ij) = dy(i)
         dy(i) = ty
         ty = dy(ij)
      endif
      l = j
c
c     if last element of array is less than t, interchange with t
c
      if (dx(j) .lt. t) then
         dx(ij) = dx(j)
         dx(j) = t
         t = dx(ij)
         dy(ij) = dy(j)
         dy(j) = ty
         ty = dy(ij)
c
c        if first element of array is greater than t, interchange with t
c
         if (dx(i) .gt. t) then
            dx(ij) = dx(i)
            dx(i) = t
            t = dx(ij)
            dy(ij) = dy(i)
            dy(i) = ty
            ty = dy(ij)
         endif
      endif
c
c     find an element in the second half of the array which is smaller
c     than t
c
  130 l = l-1
      if (dx(l) .gt. t) go to 130
c
c     find an element in the first half of the array which is greater
c     than t
c
  140 k = k+1
      if (dx(k) .lt. t) go to 140
c
c     interchange these elements
c
      if (k .le. l) then
         tt = dx(l)
         dx(l) = dx(k)
         dx(k) = tt
         tty = dy(l)
         dy(l) = dy(k)
         dy(k) = tty
         go to 130
      endif
c
c     save upper and lower subscripts of the array yet to be sorted
c
      if (l-i .gt. j-k) then
         il(m) = i
         iu(m) = l
         i = k
         m = m+1
      else
         il(m) = k
         iu(m) = j
         j = l
         m = m+1
      endif
      go to 160
c
c     begin again on another portion of the unsorted array
c
  150 m = m-1
      if (m .eq. 0) go to 190
      i = il(m)
      j = iu(m)
c
  160 if (j-i .ge. 1) go to 120
      if (i .eq. 1) go to 110
      i = i-1
c
  170 i = i+1
      if (i .eq. j) go to 150
      t = dx(i+1)
      ty = dy(i+1)
      if (dx(i) .le. t) go to 170
      k = i
c
  180 dx(k+1) = dx(k)
      dy(k+1) = dy(k)
      k = k-1
      if (t .lt. dx(k)) go to 180
      dx(k+1) = t
      dy(k+1) = ty
      go to 170
c
c     clean up
c
  190 if (kflag .le. -1) then
         do 200 i=1,nn
            dx(i) = -dx(i)
  200    continue
      endif
      return
      end
      subroutine fzero(f,b,c,r,re,ae,iflag,rpar,ipar)
c***begin prologue  fzero
c***date written   700901   (yymmdd)
c***revision date  820801   (yymmdd)
c***category no.  f1b
c***keywords  bisection,nonlinear,roots,zeros
c***author  shampine,l.f.,snla
c           watts,h.a.,snla
c***purpose  fzero searches for a zero of a function f(x) in a given
c            interval (b,c).  it is designed primarily for problems
c            where f(b) and f(c) have opposite signs.
c***description
c
c     based on a method by <NAME>
c     written by <NAME> and <NAME>
c
c            fzero searches for a zero of a function f(x) between
c            the given values b and c until the width of the interval
c            (b,c) has collapsed to within a tolerance specified by
c            the stopping criterion, abs(b-c) .le. 2.*(rw*abs(b)+ae).
c            the method used is an efficient combination of bisection
c            and the secant rule.
c
c     description of arguments
c
c     f,b,c,r,re and ae are input parameters
c     b,c and iflag are output parameters (flagged by an * below)
c
c        f     - name of the real valued external function.  this name
c                must be in an external statement in the calling
c                program.  f must be a function of one real argument.
c
c       *b     - one end of the interval (b,c).  the value returned for
c                b usually is the better approximation to a zero of f.
c
c       *c     - the other end of the interval (b,c)
c
c        r     - a (better) guess of a zero of f which could help in
c                speeding up convergence.  if f(b) and f(r) have
c                opposite signs, a root will be found in the interval
c                (b,r); if not, but f(r) and f(c) have opposite
c                signs, a root will be found in the interval (r,c);
c                otherwise, the interval (b,c) will be searched for a
c                possible root.  when no better guess is known, it is
c                recommended that r be set to b or c; because if r is
c                not interior to the interval (b,c), it will be ignored.
c
c        re    - relative error used for rw in the stopping criterion.
c                if the requested re is less than machine precision,
c                then rw is set to approximately machine precision.
c
c        ae    - absolute error used in the stopping criterion.  if the
c                given interval (b,c) contains the origin, then a
c                nonzero value should be chosen for ae.
c
c       *iflag - a status code.  user must check iflag after each call.
c                control returns to the user from fzero in all cases.
c                xerror does not process diagnostics in these cases.
c
c                1  b is within the requested tolerance of a zero.
c                   the interval (b,c) collapsed to the requested
c                   tolerance, the function changes sign in (b,c), and
c                   f(x) decreased in magnitude as (b,c) collapsed.
c
c                2  f(b) = 0.  however, the interval (b,c) may not have
c                   collapsed to the requested tolerance.
c
c                3  b may be near a singular point of f(x).
c                   the interval (b,c) collapsed to the requested tol-
c                   erance and the function changes sign in (b,c), but
c                   f(x) increased in magnitude as (b,c) collapsed,i.e.
c                     abs(f(b out)) .gt. max(abs(f(b in)),abs(f(c in)))
c
c                4  no change in sign of f(x) was found although the
c                   interval (b,c) collapsed to the requested tolerance.
c                   the user must examine this case and decide whether
c                   b is near a local minimum of f(x), or b is near a
c                   zero of even multiplicity, or neither of these.
c
c                5  too many (.gt. 500) function evaluations used.
c      *ipar     vector of integer parameters to pass to f
c***references  l. f. shampine and <NAME>, *fzero, a root-solving
c                 code*, sc-tm-70-631, september 1970.
c               <NAME>, *finding a zero by means of successive
c                 linear interpolation*, 'constructive aspects of the
c                 fundamental theorem of algebra', edited by <NAME>
c                 <NAME>, 1969.
c***routines called  r1mach
c***end prologue  fzero
c
      dimension rpar(*)
      dimension ipar(*)
c
c     er is two times the computer unit roundoff value which is
c     defined here by the function r1mach.

c***first executable statement  fzero
      er = 2.0 * r1mach(4)
c
c     initialize
c
      z=r
      if(r.le.min(b,c).or.r.ge.max(b,c)) z=c
      rw=max(re,er)
      aw=max(ae,0.)
      ic=0
      t=z
      fz=f(t,rpar,ipar)
      t=b
      fb=f(t,rpar,ipar)
      kount=2
      if(sign(1.0,fz).eq.sign(1.0,fb)) go to 1
      c=z
      fc=fz
      go to 2
    1 if(z.eq.c) go to 2
      t=c
      fc=f(t,rpar,ipar)
      kount=3
      if(sign(1.0,fz).eq.sign(1.0,fc)) go to 2
      b=z
      fb=fz
    2 a=c
      fa=fc
      acbs=abs(b-c)
      fx=max(abs(fb),abs(fc))
c
    3 if (abs(fc) .ge. abs(fb)) go to 4
c     perform interchange
      a=b
      fa=fb
      b=c
      fb=fc
      c=a
      fc=fa
c
    4 cmb=0.5*(c-b)
      acmb=abs(cmb)
      tol=rw*abs(b)+aw
c
c     test stopping criterion and function count
c
      if (acmb .le. tol) go to 10
      if(fb.eq.0.) go to 11
      if(kount.ge.500) go to 14
c
c     calculate new iterate implicitly as b+p/q
c     where we arrange p .ge. 0.
c     the implicit form is used to prevent overflow.
c
      p=(b-a)*fb
      q=fa-fb
      if (p .ge. 0.) go to 5
      p=-p
      q=-q
c
c     update a and check for satisfactory reduction
c     in the size of the bracketing interval.
c     if not, perform bisection.
c
    5 a=b
      fa=fb
      ic=ic+1
      if (ic .lt. 4) go to 6
      if (8.*acmb .ge. acbs) go to 8
      ic=0
      acbs=acmb
c
c     test for too small a change
c
    6 if (p .gt. abs(q)*tol) go to 7
c
c     increment by tolerance
c
      b=b+sign(tol,cmb)
      go to 9
c
c     root ought to be between b and (c+b)/2.
c
    7 if (p .ge. cmb*q) go to 8
c
c     use secant rule
c
      b=b+p/q
      go to 9
c
c     use bisection
c
    8 b=0.5*(c+b)
c
c     have completed computation for new iterate b
c
    9 t=b
      fb=f(t,rpar,ipar)
      kount=kount+1
c
c     decide whether next step is interpolation or extrapolation
c
      if (sign(1.0,fb) .ne. sign(1.0,fc)) go to 3
      c=a
      fc=fa
      go to 3
c
c
c     finished. process results for proper setting of iflag
c
   10 if (sign(1.0,fb) .eq. sign(1.0,fc)) go to 13
      if (abs(fb) .gt. fx) go to 12
      iflag = 1
      return
   11 iflag = 2
      return
   12 iflag = 3
      return
   13 iflag = 4
      return
   14 iflag = 5
      return
      end
      subroutine dpqr79 (ndeg, coeff, root, ierr, work)
c***purpose  find the zeros of a polynomial with real coefficients.
c***library   slatec
c***type      single precision (rpqr79-s, cpqr79-c), converted to double precisi
c***description
c
c   abstract
c       this routine computes all zeros of a polynomial of degree ndeg
c       with real coefficients by computing the eigenvalues of the
c       companion matrix.
c
c   description of parameters
c       the user must dimension all arrays appearing in the call list
c            coeff(ndeg+1), root(ndeg), work(ndeg*(ndeg+2))
c
c    --input--
c      ndeg    degree of polynomial
c
c      coeff   real coefficients in descending order.  i.e.,
c              p(z)= coeff(1)*(z**ndeg) + coeff(ndeg)*z + coeff(ndeg+1)
c
c      work    real work array of dimension at least ndeg*(ndeg+2)
c
c   --output--
c      root    complex vector of roots
c
c      ierr    output error code
c           - normal code
c          0  means the roots were computed.
c           - abnormal codes
c          1  more than 30 qr iterations on some eigenvalue of the
c             companion matrix
c          2  coeff(1)=0.0
c          3  ndeg is invalid (less than or equal to 0)
c
      double precision coeff(*), work(*), scale
      double complex root(*)
      integer ndeg, ierr, k, kh, kwr, kwi, kcol
      ierr = 0
      if (abs(coeff(1)) .eq. 0.0) then
         ierr = 2
         return
      endif
c
      if (ndeg .le. 0) then
         ierr = 3
         return
      endif
c
      if (ndeg .eq. 1) then
         root(1) = cmplx(-coeff(2)/coeff(1),0.0)
         return
      endif
c
      scale = 1.0e0/coeff(1)
      kh = 1
      kwr = kh+ndeg*ndeg
      kwi = kwr+ndeg
      kwend = kwi+ndeg-1
c
      do 10 k=1,kwend
         work(k) = 0.0e0
   10 continue
c
      do 20 k=1,ndeg
         kcol = (k-1)*ndeg+1
         work(kcol) = -coeff(k+1)*scale
         if (k .ne. ndeg) work(kcol+k) = 1.0e0
   20 continue
c
      call hqr (ndeg,ndeg,1,ndeg,work(kh),work(kwr),work(kwi),ierr)
c
      if (ierr .ne. 0) then
         ierr = 1
         return
      endif
c
      do 30 k=1,ndeg
         km1 = k-1
         root(k) = cmplx(work(kwr+km1),work(kwi+km1))
   30 continue
      return
      end
      subroutine hqr (nm, n, low, igh, h, wr, wi, ierr)
c***purpose  compute the eigenvalues of a real upper hessenberg matrix
c            using the qr method.
c***library   slatec (eispack)
c
c     this subroutine is a translation of the algol procedure hqr,
c     num. math. 14, 219-231(1970) by martin, peters, and wilkinson.
c     handbook for auto. comp., vol.ii-linear algebra, 359-371(1971).
c
c     this subroutine finds the eigenvalues of a real
c     upper hessenberg matrix by the qr method.
c
c     on input
c
c        nm must be set to the row dimension of the two-dimensional
c          array parameter, h, as declared in the calling program
c          dimension statement.  nm is an integer variable.
c
c        n is the order of the matrix h.  n is an integer variable.
c          n must be less than or equal to nm.
c
c        low and igh are two integer variables determined by the
c          balancing subroutine  balanc.  if  balanc  has not been
c          used, set low=1 and igh equal to the order of the matrix, n.
c
c        h contains the upper hessenberg matrix.  information about
c          the transformations used in the reduction to hessenberg
c          form by  elmhes  or  orthes, if performed, is stored
c          in the remaining triangle under the hessenberg matrix.
c          h is a two-dimensional real array, dimensioned h(nm,n).
c
c     on output
c
c        h has been destroyed.  therefore, it must be saved before
c          calling  hqr  if subsequent calculation and back
c          transformation of eigenvectors is to be performed.
c
c        wr and wi contain the real and imaginary parts, respectively,
c          of the eigenvalues.  the eigenvalues are unordered except
c          that complex conjugate pairs of values appear consecutively
c          with the eigenvalue having the positive imaginary part first.
c          if an error exit is made, the eigenvalues should be correct
c          for indices ierr+1, ierr+2, ..., n.  wr and wi are one-
c          dimensional real arrays, dimensioned wr(n) and wi(n).
c
c        ierr is an integer flag set to
c          zero       for normal return,
c          j          if the j-th eigenvalue has not been
c                     determined after a total of 30*n iterations.
c                     the eigenvalues should be correct for indices
c                     ierr+1, ierr+2, ..., n.
c
c     ------------------------------------------------------------------
c
c
      integer i,j,k,l,m,n,en,ll,mm,na,nm,igh,itn,its,low,mp2,enm2,ierr
      double precision h(nm,*),wr(*),wi(*)
      double precision p,q,r,s,t,w,x,y,zz,norm,s1,s2
      logical notlas
c
c***first executable statement  hqr
      ierr = 0
      norm = 0.0e0
      k = 1
c     .......... store roots isolated by balanc
c                and compute matrix norm ..........
      do 50 i = 1, n
c
         do 40 j = k, n
   40    norm = norm + abs(h(i,j))
c
         k = i
         if (i .ge. low .and. i .le. igh) go to 50
         wr(i) = h(i,i)
         wi(i) = 0.0e0
   50 continue
c
      en = igh
      t = 0.0e0
      itn = 30*n
c     .......... search for next eigenvalues ..........
   60 if (en .lt. low) go to 1001
      its = 0
      na = en - 1
      enm2 = na - 1
c     .......... look for single small sub-diagonal element
c                for l=en step -1 until low do -- ..........
   70 do 80 ll = low, en
         l = en + low - ll
         if (l .eq. low) go to 100
         s = abs(h(l-1,l-1)) + abs(h(l,l))
         if (s .eq. 0.0e0) s = norm
         s2 = s + abs(h(l,l-1))
         if (s2 .eq. s) go to 100
   80 continue
c     .......... form shift ..........
  100 x = h(en,en)
      if (l .eq. en) go to 270
      y = h(na,na)
      w = h(en,na) * h(na,en)
      if (l .eq. na) go to 280
      if (itn .eq. 0) go to 1000
      if (its .ne. 10 .and. its .ne. 20) go to 130
c     .......... form exceptional shift ..........
      t = t + x
c
      do 120 i = low, en
  120 h(i,i) = h(i,i) - x
c
      s = abs(h(en,na)) + abs(h(na,enm2))
      x = 0.75e0 * s
      y = x
      w = -0.4375e0 * s * s
  130 its = its + 1
      itn = itn - 1
c     .......... look for two consecutive small
c                sub-diagonal elements.
c                for m=en-2 step -1 until l do -- ..........
      do 140 mm = l, enm2
         m = enm2 + l - mm
         zz = h(m,m)
         r = x - zz
         s = y - zz
         p = (r * s - w) / h(m+1,m) + h(m,m+1)
         q = h(m+1,m+1) - zz - r - s
         r = h(m+2,m+1)
         s = abs(p) + abs(q) + abs(r)
         p = p / s
         q = q / s
         r = r / s
         if (m .eq. l) go to 150
         s1 = abs(p) * (abs(h(m-1,m-1)) + abs(zz) + abs(h(m+1,m+1)))
         s2 = s1 + abs(h(m,m-1)) * (abs(q) + abs(r))
         if (s2 .eq. s1) go to 150
  140 continue
c
  150 mp2 = m + 2
c
      do 160 i = mp2, en
         h(i,i-2) = 0.0e0
         if (i .eq. mp2) go to 160
         h(i,i-3) = 0.0e0
  160 continue
c     .......... double qr step involving rows l to en and
c                columns m to en ..........
      do 260 k = m, na
         notlas = k .ne. na
         if (k .eq. m) go to 170
         p = h(k,k-1)
         q = h(k+1,k-1)
         r = 0.0e0
         if (notlas) r = h(k+2,k-1)
         x = abs(p) + abs(q) + abs(r)
         if (x .eq. 0.0e0) go to 260
         p = p / x
         q = q / x
         r = r / x
  170    s = sign(sqrt(p*p+q*q+r*r),p)
         if (k .eq. m) go to 180
         h(k,k-1) = -s * x
         go to 190
  180    if (l .ne. m) h(k,k-1) = -h(k,k-1)
  190    p = p + s
         x = p / s
         y = q / s
         zz = r / s
         q = q / p
         r = r / p
c     .......... row modification ..........
         do 210 j = k, en
            p = h(k,j) + q * h(k+1,j)
            if (.not. notlas) go to 200
            p = p + r * h(k+2,j)
            h(k+2,j) = h(k+2,j) - p * zz
  200       h(k+1,j) = h(k+1,j) - p * y
            h(k,j) = h(k,j) - p * x
  210    continue
c
         j = min(en,k+3)
c     .......... column modification ..........
         do 230 i = l, j
            p = x * h(i,k) + y * h(i,k+1)
            if (.not. notlas) go to 220
            p = p + zz * h(i,k+2)
            h(i,k+2) = h(i,k+2) - p * r
  220       h(i,k+1) = h(i,k+1) - p * q
            h(i,k) = h(i,k) - p
  230    continue
c
  260 continue
c
      go to 70
c     .......... one root found ..........
  270 wr(en) = x + t
      wi(en) = 0.0e0
      en = na
      go to 60
c     .......... two roots found ..........
  280 p = (y - x) / 2.0e0
      q = p * p + w
      zz = sqrt(abs(q))
      x = x + t
      if (q .lt. 0.0e0) go to 320
c     .......... real pair ..........
      zz = p + sign(zz,p)
      wr(na) = x + zz
      wr(en) = wr(na)
      if (zz .ne. 0.0e0) wr(en) = x - w / zz
      wi(na) = 0.0e0
      wi(en) = 0.0e0
      go to 330
c     .......... complex pair ..........
  320 wr(na) = x + p
      wr(en) = x + p
      wi(na) = zz
      wi(en) = -zz
  330 en = enm2
      go to 60
c     .......... set error -- no convergence to an
c                eigenvalue after 30*n iterations ..........
 1000 ierr = en
 1001 return
      end
      function qbeta(pr,p,q)
      integer p,q,ipar(2)
      dimension rpar(1)
      external fbeta
      data re/1.e-6/,ae/1.e-30/
      xq=q
      if(p.eq.1)then
        qbeta=1.-(1.-pr)**(1./xq)
        return
      else
        xp=p
        ipar(1)=p
        ipar(2)=q
        rpar(1)=pr
        b=0.
        r=2.*xp/(xp+xq)
        c=5.*r
        call fzero(fbeta,b,c,r,re,ae,iflag,rpar,ipar)
        qbeta=b
        return
      endif
      end
      function fbeta(x,rpar,ipar)
      integer p,q
      double precision xx,xp,xq,xnum,xden,scale,sum,term
      dimension rpar(1),ipar(2)
      p=ipar(1)
      q=ipar(2)
      xx=x
      xp=p
      xq=q
      xnum=xq+xp-1.d0
      do 10 i=2,p
   10   xnum=xnum*(xq+xp-i)
      xden=xp-1.d0
      do 11 i=p-2,2,-1
   11   xden=xden*i
      scale=xnum/xden
      sum=0.d0
      do 30 i=1,p
        xnum=1.d0
        do 20 j=1,i-1
   20     xnum=xnum*(xp-j)
        xden=xq
        do 25 j=1,i-1
   25     xden=xden*(xq+j)
        term=xnum/xden*xx**(p-i)*(1.d0-xx)**(q+i-1)
   30   sum=sum+term
      fbeta=1.d0-scale*sum-rpar(1)
      return
      end
      function betai (x, pin, qin)
c august 1980 version.  <NAME>, c3, los alamos scientific lab.
c based on bosten and battiste, remark on algorithm 179, comm. acm,
c v 17, p 153, (1974).
c
c             input arguments --
c x      upper limit of integration.  x must be in (0,1) inclusive.
c p      first beta distribution parameter.  p must be gt 0.0.
c q      second beta distribution parameter.  q must be gt 0.0.
c betai  the incomplete beta function ratio is the probability that a
c        random variable from a beta distribution having parameters
c        p and q will be less than or equal to x.
c
      external albeta, alog, r1mach
      data eps, alneps, sml, alnsml / 4*0.0 /
c
      if (eps.ne.0.) go to 10
      eps = r1mach(3)
      alneps = alog(eps)
      sml = r1mach(1)
      alnsml = alog(sml)
c
 10   continue
c      if (x.lt.0. .or. x.gt.1.0) call seteru (
c     1  35hbetai   x is not in the range (0,1), 35, 1, 2)
c      if (pin.le.0. .or. qin.le.0.) call seteru (
c     1  29hbetai   a and/or b is le zero, 29, 2, 2)
c
      y = x
      p = pin
      q = qin
      if (q.le.p .and. x.lt.0.8) go to 20
      if (x.lt.0.2) go to 20
      y = 1.0 - y
      p = qin
      q = pin
c
 20   if ((p+q)*y/(p+1.).lt.eps) go to 80
c
c evaluate the infinite sum first.
c term will equal y**p/beta(ps,p) * (1.-ps)i * y**i / fac(i)
c
      ps = q - aint(q)
      if (ps.eq.0.) ps = 1.0
      xb = p*alog(y) -  albeta(ps, p) - alog(p)
      betai = 0.0
      if (xb.lt.alnsml) go to 40
c
      betai = exp (xb)
      term = betai*p
      if (ps.eq.1.0) go to 40
c
      n = amax1 (alneps/alog(y), 4.0)
      do 30 i=1,n
        term = term*(float(i)-ps)*y/float(i)
        betai = betai + term/(p+float(i))
 30   continue
c
c now evaluate the finite sum, maybe.
c
 40   if (q.le.1.0) go to 70
c
      xb = p*alog(y) + q*alog(1.0-y) - albeta(p,q) - alog(q)
      ib = amax1 (xb/alnsml, 0.0)
      term = exp (xb - float(ib)*alnsml)
      c = 1.0/(1.0-y)
      p1 = q*c/(p+q-1.)
c
      finsum = 0.0
      n = q
      if (q.eq.float(n)) n = n - 1
      do 50 i=1,n
        if (p1.le.1.0 .and. term/eps.le.finsum) go to 60
        term = (q-float(i-1))*c*term/(p+q-float(i))
c
        if (term.gt.1.0) ib = ib - 1
        if (term.gt.1.0) term = term*sml
c
        if (ib.eq.0) finsum = finsum + term
 50   continue
c
 60   betai = betai + finsum
 70   if (y.ne.x .or. p.ne.pin) betai = 1.0 - betai
      betai = amax1 (amin1 (betai, 1.0), 0.0)
      return
c
 80   betai = 0.0
      xb = p*alog(amax1(y,sml)) - alog(p) - albeta(p,q)
      if (xb.gt.alnsml .and. y.ne.0.) betai = exp (xb)
      if (y.ne.x .or. p.ne.pin) betai = 1.0 - betai
      return
c
      end
      function albeta (a, b)
c july 1977 edition.   <NAME>, c3, los alamos scientific lab.
      external alngam, alnrel, alog, gamma, r9lgmc
      data sq2pil / 0.9189385332 0467274 e0 /
c
      p = amin1 (a, b)
      q = amax1 (a, b)
c
c      if (p.le.0.0) call seteru (
c     1  38halbeta  both arguments must be gt zero, 38, 1, 2)
      if (p.ge.10.0) go to 30
      if (q.ge.10.0) go to 20
c
c p and q are small.
c
      albeta = alog(gamma(p) * (gamma(q)/gamma(p+q)) )
      return
c
c p is small, but q is big.
c
 20   corr = r9lgmc(q) - r9lgmc(p+q)
      albeta = alngam(p) + corr + p - p*alog(p+q) +
     1  (q-0.5)*alnrel(-p/(p+q))
      return
c
c p and q are big.
c
 30   corr = r9lgmc(p) + r9lgmc(q) - r9lgmc(p+q)
      albeta = -0.5*alog(q) + sq2pil + corr + (p-0.5)*alog(p/(p+q))
     1  + q*alnrel(-p/(p+q))
      return
c
      end
      function alog (x)
c june 1977 edition.   <NAME>, c3, los alamos scientific lab.
      dimension alncs(6), center(4), alncen(5)
      external csevl, inits, r1mach
c
c series for aln        on the interval  0.          to  3.46021d-03
c                                        with weighted error   1.50e-16
c                                         log weighted error  15.82
c                               significant figures required  15.65
c                                    decimal places required  16.21
c
      data aln cs( 1) /   1.3347199877 973882e0 /
      data aln cs( 2) /    .0006937562 83284112e0 /
      data aln cs( 3) /    .0000004293 40390204e0 /
      data aln cs( 4) /    .0000000002 89338477e0 /
      data aln cs( 5) /    .0000000000 00205125e0 /
      data aln cs( 6) /    .0000000000 00000150e0 /
c
      data center(1) / 1.0 /
      data center(2) / 1.25 /
      data center(3) / 1.50 /
      data center(4) / 1.75 /
c
      data alncen(  1) / 0.0e0                                         /
      data alncen(  2) / +.2231435513 14209755 e+0                     /
      data alncen(  3) / +.4054651081 08164381 e+0                     /
      data alncen(  4) / +.5596157879 35422686 e+0                     /
      data alncen(  5) / +.6931471805 59945309 e+0                     /
c
c aln2 = alog(2.0) - 0.625
      data aln2 / 0.0681471805 59945309e0 /
      data nterms / 0 /
c
      if (nterms.eq.0) nterms = inits (alncs, 6, 28.9*r1mach(3))
c
c      if (x.le.0.) call seteru (
c     1  29halog    x is zero or negative, 29, 1, 2)
c
      call r9upak (x, y, n)
c
      xn = n - 1
      y = 2.0*y
      ntrval = 4.0*y - 2.5
      if (ntrval.eq.5) t = ((y-1.0)-1.0) / (y+2.0)
      if (ntrval.lt.5) t = (y-center(ntrval))/(y+center(ntrval))
      t2 = t*t
c
      alog = 0.625*xn + (aln2*xn + alncen(ntrval) + 2.0*t +
     1  t*t2*csevl(578.0*t2-1.0, alncs, nterms) )
c
      return
      end
      function alngam (x)
c august 1980 edition.   <NAME>, c3, los alamos scientific lab.
c
      external alog, gamma, r1mach, r9lgmc
      data sq2pil / 0.9189385332 0467274e0/
c sq2pil = alog(sqrt(2.*pi)),  sqpi2l = alog (sqrt(pi/2.))
      data sqpi2l / 0.2257913526 4472743e0/
      data pi     / 3.1415926535 8979324e0/
c
      data xmax, dxrel / 0., 0. /
c
      if (xmax.ne.0.) go to 10
      xmax = r1mach(2)/alog(r1mach(2))
      dxrel = sqrt (r1mach(4))
c
 10   y = abs(x)
      if (y.gt.10.0) go to 20
c
c alog (abs (gamma(x))) for  abs(x) .le. 10.0
c
      alngam = alog (abs (gamma(x)))
      return
c
c alog (abs (gamma(x))) for abs(x) .gt. 10.0
c
 20   continue
c      if (y.gt.xmax) call seteru (
c     1  38halngam  abs(x) so big alngam overflows, 38, 2, 2)
c
      if (x.gt.0.) alngam = sq2pil + (x-0.5)*alog(x) - x + r9lgmc(y)
      if (x.gt.0.) return
c
      sinpiy = abs (sin(pi*y))
c      if (sinpiy.eq.0.) call seteru (31halngam  x is a negative integer,
c     1  31, 3, 2)
c
      alngam = sqpi2l + (x-0.5)*alog(y) - x - alog(sinpiy) - r9lgmc(y)
c
c      if (abs((x-aint(x-0.5))*alngam/x).lt.dxrel) call seteru (
c     1'alngam  answer lt half precision because x too near negative ',
c     2   68, 1, 1)
      return
c
      end
      function alnrel (x)
c april 1977 version.  <NAME>, c3, los alamos scientific lab.
      dimension alnrcs(23)
      external alog, csevl, inits, r1mach
c
c series for alnr       on the interval -3.75000d-01 to  3.75000d-01
c                                        with weighted error   1.93e-17
c                                         log weighted error  16.72
c                               significant figures required  16.44
c                                    decimal places required  17.40
c
      data alnrcs( 1) /   1.0378693562 743770e0 /
      data alnrcs( 2) /   -.1336430150 4908918e0 /
      data alnrcs( 3) /    .0194082491 35520563e0 /
      data alnrcs( 4) /   -.0030107551 12753577e0 /
      data alnrcs( 5) /    .0004869461 47971548e0 /
      data alnrcs( 6) /   -.0000810548 81893175e0 /
      data alnrcs( 7) /    .0000137788 47799559e0 /
      data alnrcs( 8) /   -.0000023802 21089435e0 /
      data alnrcs( 9) /    .0000004164 04162138e0 /
      data alnrcs(10) /   -.0000000735 95828378e0 /
      data alnrcs(11) /    .0000000131 17611876e0 /
      data alnrcs(12) /   -.0000000023 54670931e0 /
      data alnrcs(13) /    .0000000004 25227732e0 /
      data alnrcs(14) /   -.0000000000 77190894e0 /
      data alnrcs(15) /    .0000000000 14075746e0 /
      data alnrcs(16) /   -.0000000000 02576907e0 /
      data alnrcs(17) /    .0000000000 00473424e0 /
      data alnrcs(18) /   -.0000000000 00087249e0 /
      data alnrcs(19) /    .0000000000 00016124e0 /
      data alnrcs(20) /   -.0000000000 00002987e0 /
      data alnrcs(21) /    .0000000000 00000554e0 /
      data alnrcs(22) /   -.0000000000 00000103e0 /
      data alnrcs(23) /    .0000000000 00000019e0 /
c
      data nlnrel, xmin /0, 0./
c
      if (nlnrel.ne.0) go to 10
      nlnrel = inits (alnrcs, 23, 0.1*r1mach(3))
      xmin = -1.0 + sqrt(r1mach(4))
c
 10   continue
c      if (x.le.(-1.0)) call seteru (
c     1  18halnrel  x is le -1, 18, 2, 2)
c      if (x.lt.xmin) call seteru (
c     1  54halnrel  answer lt half precision because x too near -1, 54,
c     2  1, 1)
c
      if (abs(x).le.0.375) alnrel = x*(1. -
     1  x*csevl (x/.375, alnrcs, nlnrel))
      if (abs(x).gt.0.375) alnrel = alog (1.0+x)
c
      return
      end
      function gamma (x)
c jan 1984 edition.   <NAME>, c3, los alamos scientific lab.
      dimension gcs(23)
      external alog, csevl, inits, r1mach, r9lgmc
c
      data gcs   ( 1) / .0085711955 90989331e0/
      data gcs   ( 2) / .0044153813 24841007e0/
      data gcs   ( 3) / .0568504368 1599363e0/
      data gcs   ( 4) /-.0042198353 96418561e0/
      data gcs   ( 5) / .0013268081 81212460e0/
      data gcs   ( 6) /-.0001893024 529798880e0/
      data gcs   ( 7) / .0000360692 532744124e0/
      data gcs   ( 8) /-.0000060567 619044608e0/
      data gcs   ( 9) / .0000010558 295463022e0/
      data gcs   (10) /-.0000001811 967365542e0/
      data gcs   (11) / .0000000311 772496471e0/
      data gcs   (12) /-.0000000053 542196390e0/
      data gcs   (13) / .0000000009 193275519e0/
      data gcs   (14) /-.0000000001 577941280e0/
      data gcs   (15) / .0000000000 270798062e0/
      data gcs   (16) /-.0000000000 046468186e0/
      data gcs   (17) / .0000000000 007973350e0/
      data gcs   (18) /-.0000000000 001368078e0/
      data gcs   (19) / .0000000000 000234731e0/
      data gcs   (20) /-.0000000000 000040274e0/
      data gcs   (21) / .0000000000 000006910e0/
      data gcs   (22) /-.0000000000 000001185e0/
      data gcs   (23) / .0000000000 000000203e0/
c
      data pi /3.14159 26535 89793 24e0/
c sq2pil is alog (sqrt (2.*pi) )
      data sq2pil /0.91893 85332 04672 74e0/
      data ngcs, xmin, xmax, xsml, dxrel /0, 4*0.0 /
c
      if (ngcs.ne.0) go to 10
c
c ---------------------------------------------------------------------
c initialize.  find legal bounds for x, and determine the number of
c terms in the series required to attain an accuracy ten times better
c than machine precision.
c
      ngcs = inits (gcs, 23, 0.1*r1mach(3))
c
      call r9gaml (xmin, xmax)
      xsml = exp (amax1 (alog (r1mach(1)), -alog(r1mach(2))) + 0.01)
      dxrel = sqrt (r1mach(4))
c
c ---------------------------------------------------------------------
c finish initialization.  start evaluating gamma(x).
c
 10   y = abs(x)
      if (y.gt.10.0) go to 50
c
c compute gamma(x) for abs(x) .le. 10.0.  reduce interval and
c find gamma(1+y) for 0. .le. y .lt. 1. first of all.
c
      n = x
      if (x.lt.0.) n = n - 1
      y = x - float(n)
      n = n - 1
      gamma = 0.9375 + csevl(2.*y-1., gcs, ngcs)
      if (n.eq.0) return
c
      if (n.gt.0) go to 30
c
c compute gamma(x) for x .lt. 1.
c
      n = -n
c      if (x.eq.0.) call seteru (14hgamma   x is 0, 14, 4, 2)
c      if (x.lt.0. .and. x+float(n-2).eq.0.) call seteru (
c     1  31hgamma   x is a negative integer, 31, 4, 2)
c      if (x.lt.(-0.5) .and. abs((x-aint(x-0.5))/x).lt.dxrel) call
c     1  seteru (68hgamma   answer lt half precision because x too near n
c     2egative integer, 68, 1, 1)
c      if (y.lt.xsml) call seteru (
c     1  54hgamma   x is so close to 0.0 that the result overflows,
c     2  54, 5, 2)
c
      do 20 i=1,n
        gamma = gamma / (x+float(i-1))
 20   continue
      return
c
c gamma(x) for x .ge. 2.
c
 30   do 40 i=1,n
        gamma = (y+float(i))*gamma
 40   continue
      return
c
c compute gamma(x) for abs(x) .gt. 10.0.  recall y = abs(x).
c
 50   continue
c      if (x.gt.xmax) call seteru (32hgamma   x so big gamma overflows,
c     1  32, 3, 2)
c
      gamma = 0.
c      if (x.lt.xmin) call seteru (35hgamma   x so small gamma underflows
c     1  , 35, 2, 0)
      if (x.lt.xmin) return
c
      gamma = exp((y-0.5)*alog(y) - y + sq2pil + r9lgmc(y) )
      if (x.gt.0.) return
c
c      if (abs((x-aint(x-0.5))/x).lt.dxrel) call seteru (
c     1  61hgamma   answer lt half precision, x too near negative integer
c     2  , 61, 1, 1)
c
      sinpiy = sin (pi*y)
c      if (sinpiy.eq.0.) call seteru (
c     1  31hgamma   x is a negative integer, 31, 4, 2)
c
      gamma = -pi / (y*sinpiy*gamma)
c
      return
      end
      function r9lgmc (x)
c august 1977 edition.  <NAME>, c3, los alamos scientific lab.
c
c compute the log gamma correction factor for x .ge. 10.0 so that
c  alog (gamma(x)) = alog(sqrt(2*pi)) + (x-.5)*alog(x) - x + r9lgmc(x)
c
      dimension algmcs(6)
      external alog, csevl, inits, r1mach
c
c series for algm       on the interval  0.          to  1.00000d-02
c                                        with weighted error   3.40e-16
c                                         log weighted error  15.47
c                               significant figures required  14.39
c                                    decimal places required  15.86
c
      data algmcs( 1) /    .1666389480 45186e0 /
      data algmcs( 2) /   -.0000138494 817606e0 /
      data algmcs( 3) /    .0000000098 108256e0 /
      data algmcs( 4) /   -.0000000000 180912e0 /
      data algmcs( 5) /    .0000000000 000622e0 /
      data algmcs( 6) /   -.0000000000 000003e0 /
c
      data nalgm, xbig, xmax / 0, 2*0.0 /
c
      if (nalgm.ne.0) go to 10
      nalgm = inits (algmcs, 6, r1mach(3))
      xbig = 1.0/sqrt(r1mach(3))
      xmax = exp (amin1(alog(r1mach(2)/12.0), -alog(12.0*r1mach(1))) )
c
 10   continue
c      if (x.lt.10.0) call seteru (23hr9lgmc  x must be ge 10, 23, 1, 2)
      if (x.ge.xmax) go to 20
c
      r9lgmc = 1.0/(12.0*x)
      if (x.lt.xbig) r9lgmc = csevl (2.0*(10./x)**2-1., algmcs, nalgm)/x
      return
c
 20   r9lgmc = 0.0
c      call seteru (34hr9lgmc  x so big r9lgmc underflows, 34, 2, 0)
      return
c
      end
      function csevl (x, cs, n)
c april 1977 version.  <NAME>, c3, los alamos scientific lab.
c
c evaluate the n-term chebyshev series cs at x.  adapted from
c <NAME>, algorithm 446, c.a.c.m., 16, 254 (1973).  also see fox
c and parker, chebyshev polys in numerical analysis, oxford press, p.56.
c
c             input arguments --
c x      value at which the series is to be evaluated.
c cs     array of n terms of a chebyshev series.  in eval-
c        uating cs, only half the first coef is summed.
c n      number of terms in array cs.
c
      dimension cs(n)
c
c      if (n.lt.1) call seteru (28hcsevl   number of terms le 0, 28, 2,2)
c      if (n.gt.1000) call seteru (31hcsevl   number of terms gt 1000,
c     1  31, 3, 2)
c      if (x.lt.(-1.1) .or. x.gt.1.1) call seteru (
c     1  25hcsevl   x outside (-1,+1), 25, 1, 1)
c
      b1 = 0.
      b0 = 0.
      twox = 2.*x
      do 10 i=1,n
        b2 = b1
        b1 = b0
        ni = n + 1 - i
        b0 = twox*b1 - b2 + cs(ni)
 10   continue
c
      csevl = 0.5 * (b0-b2)
c
      return
      end
      function inits (os, nos, eta)
c april 1977 version.  <NAME>, c3, los alamos scientific lab.
c
c initialize the orthogonal series so that inits is the number of terms
c needed to insure the error is no larger than eta.  ordinarily, eta
c will be chosen to be one-tenth machine precision.
c
c             input arguments --
c os     array of nos coefficients in an orthogonal series.
c nos    number of coefficients in os.
c eta    requested accuracy of series.
c
      dimension os(nos)
c
c      if (nos.lt.1) call seteru (
c     1  35hinits   number of coefficients lt 1, 35, 2, 2)
c
      err = 0.
      do 10 ii=1,nos
        i = nos + 1 - ii
        err = err + abs(os(i))
        if (err.gt.eta) go to 20
 10   continue
c
 20   continue
c      if (i.eq.nos) call seteru (28hinits   eta may be too small, 28,
c     1  1, 2)
      inits = i
c
      return
      end
      subroutine r9gaml (xmin, xmax)
c april 1977 version.  <NAME>, c3, los alamos scientific lab.
c
c calculate the minimum and maximum legal bounds for x in gamma(x).
c xmin and xmax are not the only bounds, but they are the only non-
c trivial ones to calculate.
c
c             output arguments --
c xmin   minimum legal value of x in gamma(x).  any smaller value of
c        x might result in underflow.
c xmax   maximum legal value of x in gamma(x).  any larger value will
c        cause overflow.
c
      external alog, r1mach
c
      alnsml = alog(r1mach(1))
      xmin = -alnsml
      do 10 i=1,10
        xold = xmin
        xln = alog(xmin)
        xmin = xmin - xmin*((xmin+0.5)*xln - xmin - 0.2258 + alnsml)
     1    / (xmin*xln + 0.5)
        if (abs(xmin-xold).lt.0.005) go to 20
 10   continue
c      call seteru (27hr9gaml  unable to find xmin, 27, 1, 2)
c
 20   xmin = -xmin + 0.01
c
      alnbig = alog(r1mach(2))
      xmax = alnbig
      do 30 i=1,10
        xold = xmax
        xln = alog(xmax)
        xmax = xmax - xmax*((xmax-0.5)*xln - xmax + 0.9189 - alnbig)
     1    / (xmax*xln - 0.5)
        if (abs(xmax-xold).lt.0.005) go to 40
 30   continue
c      call seteru (27hr9gaml  unable to find xmax, 27, 2, 2)
c
 40   xmax = xmax - 0.01
      xmin = amax1 (xmin, -xmax+1.)
c
      return
      end
      subroutine r9upak (x, y, n)
c august 1980 portable edition.  <NAME>, los alamos scientific lab
c
c unpack floating point number x so that x = y * 2.0**n, where
c 0.5 .le. abs(y) .lt. 1.0 .
c
      absx = abs(x)
      n = 0
      y = 0.0
      if (x.eq.0.0) return
c
 10   if (absx.ge.0.5) go to 20
      n = n - 1
      absx = absx*2.0
      go to 10
c
 20   if (absx.lt.1.0) go to 30
      n = n + 1
      absx = absx*0.5
      go to 20
c
 30   y = sign (absx, x)
      return
c
      end
      subroutine tautsp(tau,gtau,ntau,gamma,s,break,coef,l,k,iflag)
c  constructs cubic spline interpolant to given data
c       tau(i),gtau(i),i=1,...ntau
c  if gamma.gt.0 additional knots are introduced where needed to
c  make the interpolant more flexible locally. this avoids extraneous
c  inflection points typical of cubic spline interpolation at knots to
c  rapidly changing data.
c
c  taken from <NAME>, a practical guide to splines, pp 310-314
c  modified to remove error print statement, a.chave igpp mar 1982
c
c  parameters
c
c      input
c  tau     sequence of data points, monotonically increasing
c  gtau    corresponding sequence of function values
c  ntau    number of data points, must be .ge.4
c  gamma   indicates whether additional flexibility is required
c          =0., no additional knots
c          =(0.,3.), under certain conditions on the given data at
c                  points i-1,...i+2 a knot is added in the i-th
c                  interval, i=2,...ntau-2. see description below.
c                  the interpolant gets rounded with increasing gamma.
c                  a value of 2.5 is typical.
c          =(3.,6.), same, except that knots might also be added in
c                  intervals in which an inflection point would be
c                  permitted. a value of 5.5 is typical.
c      output
c  break,coef,l,k give the pp-representation of the interpolant
c      for break(i).le.x.le.break(i+1) the interpolant has the form
c      f(x)=coef(1,i)+dx(coef(2,i)+(dx/2)(coef(3,i)+(dx/3)coef(4,i)))
c      with dx=x-break(i) and i=1,...l
c  iflag=0, ok
c       =1, input was incorrect
c      workspace
c  s      is of size (ntau,6). the individual columns of this array
c         contain
c         s(.,1)=dtau=tau(.+1)-tau(.)
c         s(.,2)=diag=diagonal in linear system
c         s(.,3)=u=upper diagonal in linear system
c         s(.,4)=r=right side for linear system(initially)
c         s(.,5)=z=indicator of additional knots
c         s(.,6)=1/hsecnd(1,x) with x=z or 1-z, see below
c
c  *****method*****
c  on the i-th interval, (tau(i),tau(i+1)), the interpolant is of the
c  form
c    f(u(x))=a+b*u+c*h(u,z)+d*h(1-u,1-z)
c  with u(x)=(x-tau(i))/dtau(i), where
c    z(i)=addg(i+1)/(addg(i)+addg(i+1))
c    (=.5 in the case where the denominator vanishes)
c    addg(j)=abs(ddg(j)),  ddg(j)=dg(j+1)-dg(j),
c    dg(j)=divdif(j)=(gtau(j+1)-gtau(j))/dtau(j)
c  and
c    h(u,z)=alpha*u**3+(1-alpha)*(max(((u-zeta)/(1-zeta)),0)**3
c  with
c    alpha(z)=(1-gamma/3)/zeta
c    zeta(z)=1-gamma*min((1-z),1/3)
c  for 1/3.le.z.le.2/3 f is a cubic polynomial on the interval i.
c  otherwise it has one additional knot at
c    tau(i)+zeta*dtau(i)
c  as z approaches 1, h(.,z) has an increasingly sharp bend near 1,
c  allowing f to turn rapidly near the additional knot.
c  in terms of f(j)=gtau(j) and fsecnd(j)=2 derivative of f at tau(j),
c  the coefficients for f(u(x)) are given as
c    a=f(i)-d
c    b=(f(i+1)-f(i))-(c-d)
c    c=fsecnd(i+1)*dtau(i)**2/hsecnd(1,z)
c    d=fsecnd(i)*dtau(i)**2/hsecnd(1,1-z)
c  hence can be computed once fsecnd(i),i=1,...ntau is fixed.
c  f is automatically continuous and has a continuous second
c  derivative, except when z=0 or 1 for some i. we determine
c  fsecnd(.) from the requirement that the first derivative of
c  f be continuous. in addition we require that the third derivative
c  be continuous across tau(2) and across tau(ntau-1). this leads to
c  a strictly diagonally dominant tridiagonal linear system for the
c  fsecnd(i) which we solve by gauss elimination without pivoting.
c
      real break(*),coef(4,*),gamma,gtau(*),s(ntau,6),tau(*),
     $       alpha,c,d,del,denom,divdif,entry,entry3,factor,factr2,gam,
     $       onemzt,ratio,sixth,temp,x,z,zeta,zt2
      integer n
      alph(x)=min(1.,onemg3/x)
c  there must be at least 4 interpolation points
      if(ntau.lt.4)then
        iflag=1
        return
      endif
      ntaum1=ntau-1
      do 6 i=1,ntaum1
        s(i,1)=tau(i+1)-tau(i)
        if(s(i,1).le.0.)then
c  data out of order-error return
          iflag=1
          return
        endif
   6    s(i+1,4)=(gtau(i+1)-gtau(i))/s(i,1)
      do 7 i=2,ntaum1
   7    s(i,4)=s(i+1,4)-s(i,4)
c
c  construct system of equations for second derivatives at tau. at each
c  interior data point there is one continuity equation, at the first
c  and the last interior data point there is an additional one for a
c  total of ntau equations in ntau unknowns.
c
      i=2
      s(2,2)=s(1,1)/3.
      sixth=1./6.
      method=2
      gam=gamma
      if(gam.le.0.)method=1
      if(gam.le.3.)goto 9
      method=3
      gam=gam-3.
    9 onemg3=1.-gam/3.
c  loop over i
   10 continue
c  construct z(i) and zeta(i)
      z=.5
      goto (19,11,12)method
   11 if(s(i,4)*s(i+1,4).lt.0.)goto 19
   12 temp=abs(s(i+1,4))
      denom=abs(s(i,4))+temp
      if(denom.eq.0.)goto 19
      z=temp/denom
      if(abs(z-.5).le.sixth)z=.5
   19 s(i,5)=z
c  set up the part of the i-th equation which depends on the
c  i-th interval
      if(z-.5)21,22,23
   21 zeta=gam*z
      onemzt=1.-zeta
      zt2=zeta*zeta
      alpha=alph(onemzt)
      factor=zeta/(alpha*(zt2-1.)+1.)
      s(i,6)=zeta*factor/6.
      s(i,2)=s(i,2)+s(i,1)*((1.-alpha*onemzt)*factor/2.-
     $       s(i,6))
c  if z=0 and the previous z=1, then d(i)=0, since then
c  u(i-1)=l(i+1)=0 and its value doesn't matter. reset d(i)=1
c  to insure nonzero pivot in elimination.
      if(s(i,2).le.0.)s(i,2)=1.
      s(i,3)=s(i,1)/6.
      goto 25
   22 s(i,2)=s(i,2)+s(i,1)/3.
      s(i,3)=s(i,1)/6.
      goto 25
   23 onemzt=gam*(1.-z)
      zeta=1.-onemzt
      alpha=alph(zeta)
      factor=onemzt/(1.-alpha*zeta*(1.+onemzt))
      s(i,6)=onemzt*factor/6.
      s(i,2)=s(i,2)+s(i,1)/3.
      s(i,3)=s(i,6)*s(i,1)
   25 if(i.gt.2)goto 30
      s(1,5)=.5
c  the first two equations enforce continuity of the first and third
c  derivatives across tau(2)
      s(1,2)=s(1,1)/6.
      s(1,3)=s(2,2)
      entry3=s(2,3)
      if(z-.5)26,27,28
   26 factr2=zeta*(alpha*(zt2-1.)+1.)/(alpha*(zeta*zt2-1.)+1.)
      ratio=factr2*s(2,1)/s(1,2)
      s(2,2)=factr2*s(2,1)+s(1,1)
      s(2,3)=-factr2*s(1,1)
      goto 29
   27 ratio=s(2,1)/s(1,2)
      s(2,2)=s(2,1)+s(1,1)
      s(2,3)=-s(1,1)
      goto 29
   28 ratio=s(2,1)/s(1,2)
      s(2,2)=s(2,1)+s(1,1)
      s(2,3)=-s(1,1)*6.*alpha*s(2,6)
c  at this point the first two equations read
c    diag(1)*x1+u(1)*x2+entry3*x3=r(2)
c    -ratio*diag(1)*x1+diag(2)*x2+u(2)*x3=0
c  eliminate first unknown from second equation
   29 s(2,2)=ratio*s(1,3)+s(2,2)
      s(2,3)=ratio*entry3+s(2,3)
      s(1,4)=s(2,4)
      s(2,4)=ratio*s(1,4)
      goto 35
   30 continue
c  the i-th equation enforces continuity of the first derivative across
c  tau(i). it has been set up in statements 35 to 40 and 21 to 25 and
c  reads
c     -ratio*diag(i-1)*xi-1+diag(i)*xi+u(i)*xi+1=r(i)
c  eliminate (i-1)st unknown from this equation
      s(i,2)=ratio*s(i-1,3)+s(i,2)
      s(i,4)=ratio*s(i-1,4)+s(i,4)
c
c  set up the part of the next equation which depends on the i-th
c  interval
   35 if(z-.5)36,37,38
   36 ratio=-s(i,6)*s(i,1)/s(i,2)
      s(i+1,2)=s(i,1)/3.
      goto 40
   37 ratio=-(s(i,1)/6.)/s(i,2)
      s(i+1,2)=s(i,1)/3.
      goto 40
   38 ratio=-(s(i,1)/6.)/s(i,2)
      s(i+1,2)=s(i,1)*((1.-zeta*alpha)*factor/2.-s(i,6))
c end of i loop
   40 i=i+1
      if(i.lt.ntaum1)goto 10
      s(i,5)=.5
c
c  last two equations
c  the last two equations enforce continuity of the first and third
c  derivatives across tau(ntau-1)
      entry=ratio*s(i-1,3)+s(i,2)+s(i,1)/3.
      s(i+1,2)=s(i,1)/6.
      s(i+1,4)=ratio*s(i-1,4)+s(i,4)
      if(z-.5)41,42,43
   41 ratio=s(i,1)*6.*s(i-1,6)*alpha/s(i-1,2)
      s(i,2)=ratio*s(i-1,3)+s(i,1)+s(i-1,1)
      s(i,3)=-s(i-1,1)
      goto 45
   42 ratio=s(i,1)/s(i-1,2)
      s(i,2)=ratio*s(i-1,3)+s(i,1)+s(i-1,1)
      s(i,3)=-s(i-1,1)
      goto 45
   43 factr2=onemzt*(alpha*(onemzt**2-1.)+1.)/
     $       (alpha*(onemzt**3-1.)+1.)
      ratio=factr2*s(i,1)/s(i-1,2)
      s(i,2)=ratio*s(i-1,3)+factr2*s(i-1,1)+s(i,1)
      s(i,3)=-factr2*s(i-1,1)
c  at this point the last two equations read
c    diag(i)*xi+u(i)*xi+1=r(i)
c    -ratio*diag(i)*xi+diag(i+1)*xi+1=r(i)
c  eliminate xi from the last equation
   45 s(i,4)=ratio*s(i-1,4)
      ratio=-entry/s(i,2)
      s(i+1,2)=ratio*s(i,3)+s(i+1,2)
      s(i+1,4)=ratio*s(i,4)+s(i+1,4)
c
c back substitution
c
      s(ntau,4)=s(ntau,4)/s(ntau,2)
   50 s(i,4)=(s(i,4)-s(i,3)*s(i+1,4))/s(i,2)
      i=i-1
      if(i.gt.1)goto 50
      s(1,4)=(s(1,4)-s(1,3)*s(2,4)-entry3*s(3,4))/s(1,2)
c
c  construct polynomial pieces
c
      break(1)=tau(1)
      l=1
      do 70 i=1,ntaum1
        coef(1,l)=gtau(i)
        coef(3,l)=s(i,4)
        divdif=(gtau(i+1)-gtau(i))/s(i,1)
        z=s(i,5)
        if(z-.5)61,62,63
   61   if(z.eq.0.)goto 65
        zeta=gam*z
        onemzt=1.-zeta
        c=s(i+1,4)/6.
        d=s(i,4)*s(i,6)
        l=l+1
        del=zeta*s(i,1)
        break(l)=tau(i)+del
        zt2=zeta*zeta
        alpha=alph(onemzt)
        factor=onemzt**2*alpha
        coef(1,l)=gtau(i)+divdif*del+s(i,1)**2*(d*onemzt*
     $            (factor-1.)+c*zeta*(zt2-1.))
        coef(2,l)=divdif+s(i,1)*(d*(1.-3.*factor)+c*(3.*
     $            zt2-1.))
        coef(3,l)=6.*(d*alpha*onemzt+c*zeta)
        coef(4,l)=6.*(c-d*alpha)/s(i,1)
        coef(4,l-1)=coef(4,l)-6.*d*(1.-alpha)/(del*zt2)
        coef(2,l-1)=coef(2,l)-del*(coef(3,l)-del/2.*
     $              coef(4,l-1))
        goto 68
   62   coef(2,l)=divdif-s(i,1)*(2.*s(i,4)+s(i+1,4))/6.
        coef(4,l)=(s(i+1,4)-s(i,4))/s(i,1)
        goto 68
   63   onemzt=gam*(1.-z)
        if(onemzt.eq.0.)goto 65
        zeta=1.-onemzt
        alpha=alph(zeta)
        c=s(i+1,4)*s(i,6)
        d=s(i,4)/6.
        del=zeta*s(i,1)
        break(l+1)=tau(i)+del
        coef(2,l)=divdif-s(i,1)*(2.*d+c)
        coef(4,l)=6.*(c*alpha-d)/s(i,1)
        l=l+1
        coef(4,l)=coef(4,l-1)+6.*(1.-alpha)*c/(s(i,1)*onemzt**3)
        coef(3,l)=coef(3,l-1)+del*coef(4,l-1)
        coef(2,l)=coef(2,l-1)+del*(coef(3,l-1)+del/2.*coef(4,l-1))
        coef(1,l)=coef(1,l-1)+del*(coef(2,l-1)+del/2.*(coef(3,l-1)
     $            +del/3.*coef(4,l-1)))
        goto 68
   65   coef(2,l)=divdif
        coef(3,l)=0.
        coef(4,l)=0.
   68   l=l+1
   70   break(l)=tau(i+1)
      l=l-1
      k=4
      iflag=0
      return
      end
      real function ppvalu(break,coef,l,k,x,jderiv)
c calculates value at x of the jderiv-th derivative of pp fct
c from pp-representation
c
c  break,coef,l,k are as output by tautsp
c  x is the value of x at which the function is to be evaluated
c  jderiv is an integer .ge.0 giving the derviative to be evaluated
      real break(l),coef(k,l),x,fmmjdr,h
      ppvalu=0.
      fmmjdr=k-jderiv
c  derivatives of order .ge. k are zero
      if(fmmjdr.le.0.)return
c  find index i of largest breakpoint to the left of x
      call interv(break,l,x,i,ndummy)
c  evaluate jderiv-th derivative of i-th polynomial piece at x
      h=x-break(i)
      do 10 m=k,jderiv+1,-1
        ppvalu=(ppvalu/fmmjdr)*h+coef(m,i)
   10   fmmjdr=fmmjdr-1.
      return
      end
      subroutine interv(xt,lxt,x,left,mflag)
c computes left=max(i,1.le.i.le..lxt .and. xt(i).le.x)
      real x,xt(*)
      data ilo/1/
      save ilo
      ihi=ilo+1
      if(ihi.lt.lxt)goto 20
      if(x.ge.xt(lxt))goto 110
      if(lxt.le.1)goto 90
      ilo=lxt-1
      ihi=lxt
   20 if(x.ge.xt(ihi))goto 40
      if(x.ge.xt(ilo))goto 100
      istep=1
   31 ihi=ilo
      ilo=ihi-istep
      if(ilo.le.1)goto 35
      if(x.ge.xt(ilo))goto 50
      istep=istep*2
      goto 31
   35 ilo=1
      if(x.lt.xt(1))goto 90
      goto 50
   40 istep=1
   41 ilo=ihi
      ihi=ilo+istep
      if(ihi.ge.lxt)goto 45
      if(x.lt.xt(ihi))goto 50
      istep=istep*2
      goto 41
   45 if(x.ge.xt(lxt))goto 110
      ihi=lxt
   50 middle=(ilo+ihi)/2
      if(middle.eq.ilo)goto 100
      if(x.lt.xt(middle))goto 53
      ilo=middle
      goto 50
   53 ihi=middle
      goto 50
   90 mflag=-1
      left=1
      return
  100 mflag=0
      left=ilo
      return
  110 mflag=1
      left=lxt
      return
      end

      real function xmedian(x,n)
      double precision sum
      real b,c
      dimension x(n)
      external fmedian
      sum=0.d0
      do 10 i=1,n
        sum=sum+x(i)
        b=min(b,x(i))
        c=max(c,x(i))
  10    continue
      r=sum/n
      call fzero(fmedian,b,c,r,1.e-6,1.e-32,iflag,x,[n])
      xmedian=b
      return
      end

      real function fmedian(xmed,x,n)
      double precision sum
      dimension x(n)
      sum=0.d0
      do 10 i=1,n
        sum=sum+(x(i)-xmed)/abs(x(i)-xmed)
  10    continue
      fmedian=sum
      return
      end

<file_sep>c  birrp adjustable parameters
c  compile time logical switch, .true. for stand-alone interactive version,
c  .false. for non-interactive use
        logical inter
        parameter (inter=.true.)
c
c  npcsm = maximum number of data pieces
c  nptsm = maximum number of data
c  nptssm = maximum fft section length
c  noutm = maximum number of output time series
c  ninpm = maximum number of input time series
c  nrefm = maximum number of reference time series, must be .ge. ninpm
c  nrsitem = maximum number of reference sites
c  nsectm = maximum number of data sections
c
        parameter (npcsm=2,nptsm=9230000,nptssm=64001)
        parameter (noutm=2,ninpm=2,nrefm=4,nrsitem=2)
        parameter (nsectm=75000)

<file_sep>      subroutine rtpss(nndim,ndata,nefn,w,efn,theta,ierr,work)
c
c  computes discrete prolate spheroidal sequences using the symmetric
c  tridiagonal form given in d.slepian, bell syst. tech. j. 57 (1978),
c  p. 1376, equation 14. there is a further reduction into even and
c  odd symmetric functions to minimize the size of the eigenvalue
c  problem, see eispack sections 2.1.17 and 2.2.8.
c  adapted by <NAME>, lanl, jan 1986 from code written by
c  <NAME>, at&t bell labs.
c  argument list:
c    nndim-leading dimension of efn
c    ndata-number of data points (e.g., time) to return in efn,
c          this corresponds to n in slepian
c    nefn-number of dpss to compute, lowest order ones are returned
c         first
c    w-the bandwidth (=time-bandwidth product/ndata)
c    efn-array to contain the dpss, first dimension corresponds to
c        time and second to the order of the sequence
c    theta-vector of length nefn containing the differential eigenvalues
c    ierr-error flag, 0 for normal return, 1 for error in tridib,
c         2 for error in tinvit
c    work-work space of dimension at least 9*ndata/2+3*nefn/2+
c         ndata*nefn/4+11
c
c  calls rtpss1
c
      implicit double precision (a-h,o-z)
      dimension efn(nndim,*),theta(*),work(*)
      logical flag
      parameter (pi=3.141592653589793d0)
      ierr = 0
      ndim   = nndim
      tw     = 2.*w
      ctpw   = cos(pi*tw)
      nodefn = nefn/2
      nevefn = nefn - nodefn
      m      = ndata/2
      mdim   = ndata - m
c  allocate storage in work
      lefnh  = 1
      levh   = mdim*nevefn + lefnh
      lfv1   = nevefn + levh
      lfv2   = mdim + lfv1
      lfv3   = mdim + lfv2
      lw     = mdim + lfv3

c  compute even eigenfunctions
      sym=1.
      flag=.false.
      call rtpss1(efn,ndim,ndata,mdim,mdim,nevefn,ctpw,theta,flag,
     $             sym,work(lefnh),work(levh),work(lfv1),work(lfv2),
     $             work(lfv3),ierr,work(lw))
c  compute odd eigenfunctions
      sym=-1.
      flag=m.ne.mdim
      if(nodefn.gt.0)call rtpss1(efn(1,2),ndim,ndata,m,mdim,nodefn,
     $                            ctpw,theta(2),flag,sym,work(lefnh),
     $                            work(levh),work(lfv1),work(lfv2),
     $                            work(lfv3),ierr,work(lw))
      return
      end
      subroutine rtpss1(efn,nndim,ndata,mm,mdim,nnhefn,ctpw,theta,
     $                  flag,sym,efnh,evh,fv1,fv2,fv3,ierr,work)
c
c  reduced band matrix dpss core routine
c
c  calls tdmev,upefrr,efnnr
c
      implicit double precision (a-h,o-z)
      dimension efn(nndim,nnhefn),efnh(mdim,nnhefn),theta(nnhefn),
     $          evh(nnhefn),fv1(mdim),fv2(mdim),fv3(mdim),work(*)
      logical flag,neven,noedge
      parameter (sr2=1.4142135623731d0)
      nhefn=nnhefn
      neven=mod(ndata,2).eq.0
      noedge=neven.or.(sym.lt.0.)
      cent=dble(ndata-1)/2.
c
c  perform symmetry reduction to half size
c
      do 600 nf=1,mm
        n=nf-1
c
c  main diagonal, diagonal of eigenfunction matrix
c
        fv1(nf)=ctpw*(cent-dble(n))**2
c
c  sub diagonal
c
        fv2(nf)=dble(n*(ndata-n))/2.
  600   fv3(nf)=fv2(nf)*fv2(nf)
      if(neven)fv1(mm)=ctpw*(cent-dble(mdim-1))**2+
     $         sym*dble(mdim*(ndata-mdim))/2.
      if(noedge)goto 700
      fv2(mm)=sr2*fv2(mm)
      fv3(mm)=2.*fv3(mm)
  700 call tdmev(fv1,fv2,fv3,mm,mdim,evh,efnh,nhefn,ierr,work)
      if(noedge)goto 740
      do 720 k=1,nhefn
  720   efnh(mm,k)=sr2*efnh(mm,k)
  740 do 760 k=1,nhefn
        kr=nhefn-k+1
        k2=2*k-1
        theta(k2)=evh(kr)
        call upefrr(efnh(1,kr),ndata,mm,sym,efn(1,k2),flag)
        call efnnr(efn(1,k2),ndata,mm,ndata,flag)
  760   continue
      return
      end

      subroutine efnnr(efn,ndata,m,ndmax,flag)
c
c  eigenfunction normalization
c
      implicit double precision (a-h,o-z)
      dimension efn(ndmax)
      logical flag
      sn=0.
      do 200 n=1,ndata
  200   sn=sn+efn(n)*efn(n)
      sn=1./sqrt(sn)
      if((flag.and.(efn(m+2).lt.0.)).or.
     $   ((.not.flag).and.(efn(m+1).lt.0.)))sn=-sn
      do 300 n=1,ndmax
  300   efn(n)=sn*efn(n)
      return
      end

      subroutine tdmev(fv1,fv2,fv3,n,ndim,ev,efn,m,kerr,work)
c
c  driver to find larger eigenvalues of a real symmetric
c  tridiagonal matrix
c
c  calls tridib,tinvit from eispack
c
      implicit double precision (a-h,o-z)
      dimension fv1(ndim),fv2(ndim),fv3(ndim),efn(ndim,m),ev(m),
     $   work(*)
      nndim=ndim
      mm=m
      nn=n
      nv4=1
      nv5=nn+nv4
      nv6=nn+nv5
      nv7=nn+nv6
      nv8=nn+nv7
      iv1=nn+nv8
c
c  compute the m largest eigenfunctions efn and associated
c  eigenvalues of the symmetric tridiagonal matrix
c  input is in fv1,fv2,fv3 in usual eispack form, see 2.1.17
c
      eps1=0.
      m11=n-m+1
      call tridib(nn,eps1,fv1,fv2,fv3,evlb,evub,m11,mm,ev,
     $            work(iv1),ierr,work(nv4),work(nv5))
      if(ierr.ne.0)kerr=1
      call tinvit(nndim,nn,fv1,fv2,fv3,mm,ev,work(iv1),efn,ierr,
     $            work(nv4),work(nv5),work(nv6),work(nv7),work(nv8))
      if(ierr.ne.0)kerr=2
      return
      end
      subroutine upefrr(pefn,ndata,m,sym,spefn,flag)
c
c  unpack eigenfunction, real-to-real
c
      implicit double precision (a-h,o-z)
      dimension pefn(m),spefn(ndata)
      logical flag
      nr=ndata
      do 100 n=1,m
        spefn(n)=pefn(n)
        spefn(nr)=sym*pefn(n)
  100   nr=nr-1
      if(flag)spefn(m+1)=0.
      return
      end

      subroutine tridib(n,eps1,d,e,e2,lb,ub,m11,m,w,ind,ierr,rv4,rv5)
c
      integer i,j,k,l,m,n,p,q,r,s,ii,m1,m2,m11,m22,tag,ierr,isturm
      double precision d(n),e(n),e2(n),w(m),rv4(n),rv5(n)
      double precision u,v,lb,t1,t2,ub,xu,x0,x1,eps1,tst1,tst2,epslon
      double precision ind(m)
c
c     this subroutine is a translation of the algol procedure bisect,
c     num. math. 9, 386-393(1967) by barth, martin, and wilkinson.
c     handbook for auto. comp., vol.ii-linear algebra, 249-256(1971).
c
c     this subroutine finds those eigenvalues of a tridiagonal
c     symmetric matrix between specified boundary indices,
c     using bisection.
c
c     on input
c
c        n is the order of the matrix.
c
c        eps1 is an absolute error tolerance for the computed
c          eigenvalues.  if the input eps1 is non-positive,
c          it is reset for each submatrix to a default value,
c          namely, minus the product of the relative machine
c          precision and the 1-norm of the submatrix.
c
c        d contains the diagonal elements of the input matrix.
c
c        e contains the subdiagonal elements of the input matrix
c          in its last n-1 positions.  e(1) is arbitrary.
c
c        e2 contains the squares of the corresponding elements of e.
c          e2(1) is arbitrary.
c
c        m11 specifies the lower boundary index for the desired
c          eigenvalues.
c
c        m specifies the number of eigenvalues desired.  the upper
c          boundary index m22 is then obtained as m22=m11+m-1.
c
c     on output
c
c        eps1 is unaltered unless it has been reset to its
c          (last) default value.
c
c        d and e are unaltered.
c
c        elements of e2, corresponding to elements of e regarded
c          as negligible, have been replaced by zero causing the
c          matrix to split into a direct sum of submatrices.
c          e2(1) is also set to zero.
c
c        lb and ub define an interval containing exactly the desired
c          eigenvalues.
c
c        w contains, in its first m positions, the eigenvalues
c          between indices m11 and m22 in ascending order.
c
c        ind contains in its first m positions the submatrix indices
c          associated with the corresponding eigenvalues in w --
c          1 for eigenvalues belonging to the first submatrix from
c          the top, 2 for those belonging to the second submatrix, etc..
c
c        ierr is set to
c          zero       for normal return,
c          3*n+1      if multiple eigenvalues at index m11 make
c                     unique selection impossible,
c          3*n+2      if multiple eigenvalues at index m22 make
c                     unique selection impossible.
c
c        rv4 and rv5 are temporary storage arrays.
c
c     note that subroutine tql1, imtql1, or tqlrat is generally faster
c     than tridib, if more than n/4 eigenvalues are to be found.
c
c     questions and comments should be directed to <NAME>,
c     mathematics and computer science div, argonne national laboratory
c
c     this version dated august 1983.
c
c     ------------------------------------------------------------------
c
      ierr = 0
      tag = 0
      xu = d(1)
      x0 = d(1)
      u = 0.0d0
c     .......... look for small sub-diagonal entries and determine an
c                interval containing all the eigenvalues ..........
      do 40 i = 1, n
         x1 = u
         u = 0.0d0
         if (i .ne. n) u = dabs(e(i+1))
         xu = dmin1(d(i)-(x1+u),xu)
         x0 = dmax1(d(i)+(x1+u),x0)
         if (i .eq. 1) go to 20
         tst1 = dabs(d(i)) + dabs(d(i-1))
         tst2 = tst1 + dabs(e(i))
         if (tst2 .gt. tst1) go to 40
   20    e2(i) = 0.0d0
   40 continue
c
      x1 = n
      x1 = x1 * epslon(dmax1(dabs(xu),dabs(x0)))
      xu = xu - x1
      t1 = xu
      x0 = x0 + x1
      t2 = x0
c     .......... determine an interval containing exactly
c                the desired eigenvalues ..........
      p = 1
      q = n
      m1 = m11 - 1
      if (m1 .eq. 0) go to 75
      isturm = 1
   50 v = x1
      x1 = xu + (x0 - xu) * 0.5d0
      if (x1 .eq. v) go to 980
      go to 320
   60 if (s - m1) 65, 73, 70
   65 xu = x1
      go to 50
   70 x0 = x1
      go to 50
   73 xu = x1
      t1 = x1
   75 m22 = m1 + m
      if (m22 .eq. n) go to 90
      x0 = t2
      isturm = 2
      go to 50
   80 if (s - m22) 65, 85, 70
   85 t2 = x1
   90 q = 0
      r = 0
c     .......... establish and process next submatrix, refining
c                interval by the gerschgorin bounds ..........
  100 if (r .eq. m) go to 1001
      tag = tag + 1
      p = q + 1
      xu = d(p)
      x0 = d(p)
      u = 0.0d0
c
      do 120 q = p, n
         x1 = u
         u = 0.0d0
         v = 0.0d0
         if (q .eq. n) go to 110
         u = dabs(e(q+1))
         v = e2(q+1)
  110    xu = dmin1(d(q)-(x1+u),xu)
         x0 = dmax1(d(q)+(x1+u),x0)
         if (v .eq. 0.0d0) go to 140
  120 continue
c
  140 x1 = epslon(dmax1(dabs(xu),dabs(x0)))
      if (eps1 .le. 0.0d0) eps1 = -x1
      if (p .ne. q) go to 180
c     .......... check for isolated root within interval ..........
      if (t1 .gt. d(p) .or. d(p) .ge. t2) go to 940
      m1 = p
      m2 = p
      rv5(p) = d(p)
      go to 900
  180 x1 = x1 * (q - p + 1)
      lb = dmax1(t1,xu-x1)
      ub = dmin1(t2,x0+x1)
      x1 = lb
      isturm = 3
      go to 320
  200 m1 = s + 1
      x1 = ub
      isturm = 4
      go to 320
  220 m2 = s
      if (m1 .gt. m2) go to 940
c     .......... find roots by bisection ..........
      x0 = ub
      isturm = 5
c
      do 240 i = m1, m2
         rv5(i) = ub
         rv4(i) = lb
  240 continue
c     .......... loop for k-th eigenvalue
c                for k=m2 step -1 until m1 do --
c                (-do- not used to legalize -computed go to-) ..........
      k = m2
  250    xu = lb
c     .......... for i=k step -1 until m1 do -- ..........
         do 260 ii = m1, k
            i = m1 + k - ii
            if (xu .ge. rv4(i)) go to 260
            xu = rv4(i)
            go to 280
  260    continue
c
  280    if (x0 .gt. rv5(k)) x0 = rv5(k)
c     .......... next bisection step ..........
  300    x1 = (xu + x0) * 0.5d0
         if ((x0 - xu) .le. dabs(eps1)) go to 420
         tst1 = 2.0d0 * (dabs(xu) + dabs(x0))
         tst2 = tst1 + (x0 - xu)
         if (tst2 .eq. tst1) go to 420
c     .......... in-line procedure for sturm sequence ..........
  320    s = p - 1
         u = 1.0d0
c
         do 340 i = p, q
            if (u .ne. 0.0d0) go to 325
            v = dabs(e(i)) / epslon(1.0d0)
            if (e2(i) .eq. 0.0d0) v = 0.0d0
            go to 330
  325       v = e2(i) / u
  330       u = d(i) - x1 - v
            if (u .lt. 0.0d0) s = s + 1
  340    continue
c
         go to (60,80,200,220,360), isturm
c     .......... refine intervals ..........
  360    if (s .ge. k) go to 400
         xu = x1
         if (s .ge. m1) go to 380
         rv4(m1) = x1
         go to 300
  380    rv4(s+1) = x1
         if (rv5(s) .gt. x1) rv5(s) = x1
         go to 300
  400    x0 = x1
         go to 300
c     .......... k-th eigenvalue found ..........
  420    rv5(k) = x1
      k = k - 1
      if (k .ge. m1) go to 250
c     .......... order eigenvalues tagged with their
c                submatrix associations ..........
  900 s = r
      r = r + m2 - m1 + 1
      j = 1
      k = m1
c
      do 920 l = 1, r
         if (j .gt. s) go to 910
         if (k .gt. m2) go to 940
         if (rv5(k) .ge. w(l)) go to 915
c
         do 905 ii = j, s
            i = l + s - ii
            w(i+1) = w(i)
            ind(i+1) = ind(i)
  905    continue
c
  910    w(l) = rv5(k)
         ind(l) = tag
         k = k + 1
         go to 920
  915    j = j + 1
  920 continue
c
  940 if (q .lt. n) go to 100
      go to 1001
c     .......... set error -- interval cannot be found containing
c                exactly the desired eigenvalues ..........
  980 ierr = 3 * n + isturm
 1001 lb = t1
      ub = t2
      return
      end
      subroutine tinvit(nm,n,d,e,e2,m,w,ind,z,
     x                  ierr,rv1,rv2,rv3,rv4,rv6)
c
      integer i,j,m,n,p,q,r,s,ii,ip,jj,nm,its,tag,ierr,group
      double precision d(n),e(n),e2(n),w(m),z(nm,m),
     x       rv1(n),rv2(n),rv3(n),rv4(n),rv6(n)
      double precision u,v,uk,xu,x0,x1,eps2,eps3,eps4,norm,order,epslon,
     x       pythag
      double precision ind(m)
c
c     this subroutine is a translation of the inverse iteration tech-
c     nique in the algol procedure tristurm by peters and wilkinson.
c     handbook for auto. comp., vol.ii-linear algebra, 418-439(1971).
c
c     this subroutine finds those eigenvectors of a tridiagonal
c     symmetric matrix corresponding to specified eigenvalues,
c     using inverse iteration.
c
c     on input
c
c        nm must be set to the row dimension of two-dimensional
c          array parameters as declared in the calling program
c          dimension statement.
c
c        n is the order of the matrix.
c
c        d contains the diagonal elements of the input matrix.
c
c        e contains the subdiagonal elements of the input matrix
c          in its last n-1 positions.  e(1) is arbitrary.
c
c        e2 contains the squares of the corresponding elements of e,
c          with zeros corresponding to negligible elements of e.
c          e(i) is considered negligible if it is not larger than
c          the product of the relative machine precision and the sum
c          of the magnitudes of d(i) and d(i-1).  e2(1) must contain
c          0.0d0 if the eigenvalues are in ascending order, or 2.0d0
c          if the eigenvalues are in descending order.  if  bisect,
c          tridib, or  imtqlv  has been used to find the eigenvalues,
c          their output e2 array is exactly what is expected here.
c
c        m is the number of specified eigenvalues.
c
c        w contains the m eigenvalues in ascending or descending order.
c
c        ind contains in its first m positions the submatrix indices
c          associated with the corresponding eigenvalues in w --
c          1 for eigenvalues belonging to the first submatrix from
c          the top, 2 for those belonging to the second submatrix, etc.
c
c     on output
c
c        all input arrays are unaltered.
c
c        z contains the associated set of orthonormal eigenvectors.
c          any vector which fails to converge is set to zero.
c
c        ierr is set to
c          zero       for normal return,
c          -r         if the eigenvector corresponding to the r-th
c                     eigenvalue fails to converge in 5 iterations.
c
c        rv1, rv2, rv3, rv4, and rv6 are temporary storage arrays.
c
c     calls pythag for  dsqrt(a*a + b*b) .
c
c     questions and comments should be directed to <NAME>,
c     mathematics and computer science div, argonne national laboratory
c
c     this version dated august 1983.
c
c     ------------------------------------------------------------------
c
      ierr = 0
      if (m .eq. 0) go to 1001
      tag = 0
      order = 1.0d0 - e2(1)
      q = 0
c     .......... establish and process next submatrix ..........
  100 p = q + 1
c
      do 120 q = p, n
         if (q .eq. n) go to 140
         if (e2(q+1) .eq. 0.0d0) go to 140
  120 continue
c     .......... find vectors by inverse iteration ..........
  140 tag = tag + 1
      s = 0
c
      do 920 r = 1, m
         if (ind(r) .ne. tag) go to 920
         its = 1
         x1 = w(r)
         if (s .ne. 0) go to 510
c     .......... check for isolated root ..........
         xu = 1.0d0
         if (p .ne. q) go to 490
         rv6(p) = 1.0d0
         go to 870
  490    norm = dabs(d(p))
         ip = p + 1
c
         do 500 i = ip, q
  500    norm = dmax1(norm, dabs(d(i))+dabs(e(i)))
c     .......... eps2 is the criterion for grouping,
c                eps3 replaces zero pivots and equal
c                roots are modified by eps3,
c                eps4 is taken very small to avoid overflow ..........
         eps2 = 1.0d-3 * norm
         eps3 = epslon(norm)
         uk = q - p + 1
         eps4 = uk * eps3
         uk = eps4 / dsqrt(uk)
         s = p
  505    group = 0
         go to 520
c     .......... look for close or coincident roots ..........
  510    if (dabs(x1-x0) .ge. eps2) go to 505
         group = group + 1
         if (order * (x1 - x0) .le. 0.0d0) x1 = x0 + order * eps3
c     .......... elimination with interchanges and
c                initialization of vector ..........
  520    v = 0.0d0
c
         do 580 i = p, q
            rv6(i) = uk
            if (i .eq. p) go to 560
            if (dabs(e(i)) .lt. dabs(u)) go to 540
c     .......... warning -- a divide check may occur here if
c                e2 array has not been specified correctly ..........
            xu = u / e(i)
            rv4(i) = xu
            rv1(i-1) = e(i)
            rv2(i-1) = d(i) - x1
            rv3(i-1) = 0.0d0
            if (i .ne. q) rv3(i-1) = e(i+1)
            u = v - xu * rv2(i-1)
            v = -xu * rv3(i-1)
            go to 580
  540       xu = e(i) / u
            rv4(i) = xu
            rv1(i-1) = u
            rv2(i-1) = v
            rv3(i-1) = 0.0d0
  560       u = d(i) - x1 - xu * v
            if (i .ne. q) v = e(i+1)
  580    continue
c
         if (u .eq. 0.0d0) u = eps3
         rv1(q) = u
         rv2(q) = 0.0d0
         rv3(q) = 0.0d0
c     .......... back substitution
c                for i=q step -1 until p do -- ..........
  600    do 620 ii = p, q
            i = p + q - ii
            rv6(i) = (rv6(i) - u * rv2(i) - v * rv3(i)) / rv1(i)
            v = u
            u = rv6(i)
  620    continue
c     .......... orthogonalize with respect to previous
c                members of group ..........
         if (group .eq. 0) go to 700
         j = r
c
         do 680 jj = 1, group
  630       j = j - 1
            if (ind(j) .ne. tag) go to 630
            xu = 0.0d0
c
            do 640 i = p, q
  640       xu = xu + rv6(i) * z(i,j)
c
            do 660 i = p, q
  660       rv6(i) = rv6(i) - xu * z(i,j)
c
  680    continue
c
  700    norm = 0.0d0
c
         do 720 i = p, q
  720    norm = norm + dabs(rv6(i))
c
         if (norm .ge. 1.0d0) go to 840
c     .......... forward substitution ..........
         if (its .eq. 5) go to 830
         if (norm .ne. 0.0d0) go to 740
         rv6(s) = eps4
         s = s + 1
         if (s .gt. q) s = p
         go to 780
  740    xu = eps4 / norm
c
         do 760 i = p, q
  760    rv6(i) = rv6(i) * xu
c     .......... elimination operations on next vector
c                iterate ..........
  780    do 820 i = ip, q
            u = rv6(i)
c     .......... if rv1(i-1) .eq. e(i), a row interchange
c                was performed earlier in the
c                triangularization process ..........
            if (rv1(i-1) .ne. e(i)) go to 800
            u = rv6(i-1)
            rv6(i-1) = rv6(i)
  800       rv6(i) = u - rv4(i) * rv6(i-1)
  820    continue
c
         its = its + 1
         go to 600
c     .......... set error -- non-converged eigenvector ..........
  830    ierr = -r
         xu = 0.0d0
         go to 870
c     .......... normalize so that sum of squares is
c                1 and expand to full order ..........
  840    u = 0.0d0
c
         do 860 i = p, q
  860    u = pythag(u,rv6(i))
c
         xu = 1.0d0 / u
c
  870    do 880 i = 1, n
  880    z(i,r) = 0.0d0
c
         do 900 i = p, q
  900    z(i,r) = rv6(i) * xu
c
         x0 = x1
  920 continue
c
      if (q .lt. n) go to 100
 1001 return
      end
      double precision function pythag(a,b)
      double precision a,b
c
c     finds dsqrt(a**2+b**2) without overflow or destructive underflow
c
      double precision p,r,s,t,u
      p = dmax1(dabs(a),dabs(b))
      if (p .eq. 0.0d0) go to 20
      r = (dmin1(dabs(a),dabs(b))/p)**2
   10 continue
         t = 4.0d0 + r
         if (t .eq. 4.0d0) go to 20
         s = r/t
         u = 1.0d0 + 2.0d0*s
         p = u*p
         r = (s/u)**2 * r
      go to 10
   20 pythag = p
      return
      end
      double precision function epslon (x)
      double precision x
c
c     estimate unit roundoff in quantities of size x.
c
      double precision a,b,c,eps
c
c**** warning:  rumor has it that some machines (including the ibm pc?)
c****   have compilers that defeat the following scheme.
c     this program should function properly on all systems
c     satisfying the following two assumptions,
c        1.  the base used in representing floating point
c            numbers is not a power of three.
c        2.  the quantity  a  in statement 10 is represented to
c            the accuracy used in floating point variables
c            that are stored in memory.
c     the statement number 10 and the go to 10 are intended to
c     force optimizing compilers to generate code satisfying
c     assumption 2.
c     under these assumptions, it should be true that,
c            a  is not exactly equal to four-thirds,
c            b  has a zero for its last bit or digit,
c            c  is not exactly equal to one,
c            eps  measures the separation of 1.0 from
c                 the next larger floating point number.
c     the developers of eispack would appreciate being informed
c     about any systems where these assumptions do not hold.
c
c     this version dated 4/6/83.
c
      a = 4.0d0/3.0d0
   10 b = a - 1.0d0
      c = b + b + b
      eps = dabs(c-1.0d0)
      if (eps .eq. 0.0d0) go to 10
      epslon = eps*dabs(x)
      return
      end
<file_sep>      subroutine input(filnam,frm,nblock,nskip,npts,rdata)
      character*(*) filnam,frm
      parameter (nrecl=30000)
      dimension rdata(*),recrd(nrecl)
      if(((frm.eq.'U').or.(frm.eq.'u')).and.(nblock.eq.0))goto 100
      if((frm.eq.'F').or.(frm.eq.'f'))goto 200
      open (unit=10,file=filnam,status='old',form='unformatted')
      nrecs=nskip/nblock
      nlefs=nskip-nblock*nrecs
      do 10 i=1,nrecs
   10   read(10,end=11)(recrd(j),j=1,nblock)
      goto 12
   11 npts=0
      return
   12 k=1
      if(nlefs.eq.0)goto 30
      read(10,end=300)(recrd(i),i=1,nblock)
      do 20 i=nlefs+1,min(nblock,npts+nlefs)
        rdata(k)=recrd(i)
   20   k=k+1
   30 continue
      nread=npts-k+1
      nrec=nread/nblock
      nleft=nread-nblock*nrec
      do 40 j=1,nrec
        read(10,end=300)(recrd(i),i=1,nblock)
        do 35 i=1,nblock
          rdata(k)=recrd(i)
   35     k=k+1
   40 continue
      if(nleft.eq.0)goto 300
      read(10,end=300)(recrd(i),i=1,nblock)
      do 50 i=1,nleft
        rdata(k)=recrd(i)
   50   k=k+1
      goto 300
  100 continue
      open (unit=10,file=filnam,status='old',form='unformatted')
      do 110 i=1,nskip
  110   read(10,end=111)
      goto 112
  111 npts=0
      return
  112 continue
      do 120 k=1,npts
  120   read(10,end=300)rdata(k)
      goto 300
  200 continue
      open (unit=10,file=filnam,status='old')
      do 210 i=1,nskip
  210   read(10,*,end=211)
      goto 212
  211 npts=0
      return
  212 continue
      do 220 k=1,npts
  220   read(10,*,end=300)rdata(k)
  300 npts=k-1
      close (unit=10)
      return
      end
      subroutine binput(filnam,imode,nskip,nread,nar,ncomp,nser,
     $           iindex,datum,rdata,ar,cvar)
c imode=1 means no header except possibly ar filter coefficients
c imode=2 means ascii ts format so that data read begins after
c '>INFO_END' is detected and cvar is returned with
c latitude, longitude, and elevation (if present)
      include 'parameters.h'
      parameter (narm=100)
      character*(*) filnam,cvar(3)
      character line*80
      dimension rdata(nptsm,*),datum(*),iindex(*),
     $          ar(narm+1,*)
      open (unit=10,file=filnam,status='old')
      if(nar.lt.0)then
        do 10 n=1,10000
          read(10,'(a)')line
          if(line(1:10).eq.'#AR_FILTER')then
            do 6 j=1,nser
              ar(1,iindex(j))=1.
              do 5 jj=1,-nar/5
    5         read(10,'(1x,5g15.7)')(ar((jj-1)*5+i,
     $                               iindex(j)),i=1,5)
              nl=-nar-5*(-nar/5)
              if(nl.ne.0)then
                read(10,'(1x,5g15.7)')
     $              (ar(5*(-nar/5)+i,iindex(j)),i=1,nl)
              endif
    6       continue
            goto 11
          endif
   10     continue
      endif
   11 if(imode.eq.1)goto 50
      do 15 i=1,3
   15   cvar(i)=' '
      do 20 i=1,10000
        read(10,'(a)',end=90)line
   20   if(line(1:1).eq.'>')goto 22
   22 do 30 i=1,10000
        if(line(2:9).eq.'INFO_END')goto 50
        if(line(2:9).eq.'LATITUDE')then
          i1=index(line,':')
          i2=index(line,'=')
          if(i1.ne.0)then
            call strlen(line(i1+1:80),j1,j2)
            cvar(1)=line(i1+j1-1:i1+j2+1)
          elseif(i2.ne.0)then
            call strlen(line(i2+1:80),j1,j2)
            cvar(1)=line(i2+j1-1:i2+j2+1)
          endif
        elseif(line(2:10).eq.'LONGITUDE')then
          i1=index(line,':')
          i2=index(line,'=')
          if(i1.ne.0)then
            call strlen(line(i1+1:80),j1,j2)
            cvar(2)=line(i1+j1-1:i1+j2+1)
          elseif(i2.ne.0)then
            call strlen(line(i2+1:80),j1,j2)
            cvar(2)=line(i2+j1-1:i2+j2+1)
          endif
        elseif(line(2:10).eq.'ELEVATION')then
          i1=index(line,':')
          i2=index(line,'=')
          if(i1.ne.0)then
            call strlen(line(i1+1:80),j1,j2)
            cvar(3)=line(i1+j1-1:i1+j2+1)
          elseif(i2.ne.0)then
            call strlen(line(i2+1:80),j1,j2)
            cvar(3)=line(i2+j1-1:i2+j2+1)
          endif
        endif
   30   read(10,'(a)')line
      nread=0
      return
   50 do 70 i=1,nskip
   70   read(10,*,end=90)
      do 80 i=1,nread
        read(10,*,end=81)(datum(j),j=1,ncomp)
        do 80 j=1,nser
   80     rdata(i,j)=datum(iindex(j))
      close (unit=10)
      return
   81 nread=i-1
      close (unit=10)
      return
   90 nread=0
      close (unit=10)
      return
      end
      integer function i1mach(i)
      integer i
c
c    i1mach( 1) = the standard input unit.
c    i1mach( 2) = the standard output unit.
c    i1mach( 3) = the standard punch unit.
c    i1mach( 4) = the standard error message unit.
c    i1mach( 5) = the number of bits per integer storage unit.
c    i1mach( 6) = the number of characters per character storage unit.
c    integers have form sign ( x(s-1)*a**(s-1) + ... + x(1)*a + x(0) )
c    i1mach( 7) = a, the base.
c    i1mach( 8) = s, the number of base-a digits.
c    i1mach( 9) = a**s - 1, the largest magnitude.
c    floats have form  sign (b**e)*( (x(1)/b) + ... + (x(t)/b**t) )
c               where  emin .le. e .le. emax.
c    i1mach(10) = b, the base.
c  single-precision
c    i1mach(11) = t, the number of base-b digits.
c    i1mach(12) = emin, the smallest exponent e.
c    i1mach(13) = emax, the largest exponent e.
c  double-precision
c    i1mach(14) = t, the number of base-b digits.
c    i1mach(15) = emin, the smallest exponent e.
c    i1mach(16) = emax, the largest exponent e.
c
      integer imach(16), output, sc, small(2)
      save imach, sc
      real rmach
      equivalence (imach(4),output), (rmach,small(1))
      integer i3, j, k, t3e(3)
      data t3e(1) / 9777664 /
      data t3e(2) / 5323660 /
      data t3e(3) / 46980 /
c  this version adapts automatically to most current machines,
c  including auto-double compilers.
c  to compile on older machines, add a c in column 1
c  on the next line
      data sc/0/
c  and remove the c from column 1 in one of the sections below.
c  constants for even older machines can be obtained by
c          mail <EMAIL>
c          send old1mach from blas
c  please send corrections to dmg or <EMAIL>.
c
c     machine constants for the honeywell dps 8/70 series.
c
c      data imach( 1) /    5 /
c      data imach( 2) /    6 /
c      data imach( 3) /   43 /
c      data imach( 4) /    6 /
c      data imach( 5) /   36 /
c      data imach( 6) /    4 /
c      data imach( 7) /    2 /
c      data imach( 8) /   35 /
c      data imach( 9) / o377777777777 /
c      data imach(10) /    2 /
c      data imach(11) /   27 /
c      data imach(12) / -127 /
c      data imach(13) /  127 /
c      data imach(14) /   63 /
c      data imach(15) / -127 /
c      data imach(16) /  127 /, sc/987/
c
c     machine constants for pdp-11 fortrans supporting
c     32-bit integer arithmetic.
c
c      data imach( 1) /    5 /
c      data imach( 2) /    6 /
c      data imach( 3) /    7 /
c      data imach( 4) /    6 /
c      data imach( 5) /   32 /
c      data imach( 6) /    4 /
c      data imach( 7) /    2 /
c      data imach( 8) /   31 /
c      data imach( 9) / 2147483647 /
c      data imach(10) /    2 /
c      data imach(11) /   24 /
c      data imach(12) / -127 /
c      data imach(13) /  127 /
c      data imach(14) /   56 /
c      data imach(15) / -127 /
c      data imach(16) /  127 /, sc/987/
c
c     machine constants for the univac 1100 series.
c
c     note that the punch unit, i1mach(3), has been set to 7
c     which is appropriate for the univac-for system.
c     if you have the univac-ftn system, set it to 1.
c
c      data imach( 1) /    5 /
c      data imach( 2) /    6 /
c      data imach( 3) /    7 /
c      data imach( 4) /    6 /
c      data imach( 5) /   36 /
c      data imach( 6) /    6 /
c      data imach( 7) /    2 /
c      data imach( 8) /   35 /
c      data imach( 9) / o377777777777 /
c      data imach(10) /    2 /
c      data imach(11) /   27 /
c      data imach(12) / -128 /
c      data imach(13) /  127 /
c      data imach(14) /   60 /
c      data imach(15) /-1024 /
c      data imach(16) / 1023 /, sc/987/
c
      if (sc .ne. 987) then
*        *** check for autodouble ***
         small(2) = 0
         rmach = 1e13
         if (small(2) .ne. 0) then
*           *** autodoubled ***
            if (      (small(1) .eq. 1117925532
     *           .and. small(2) .eq. -448790528)
     *       .or.     (small(2) .eq. 1117925532
     *           .and. small(1) .eq. -448790528)) then
*               *** ieee ***
               imach(10) = 2
               imach(14) = 53
               imach(15) = -1021
               imach(16) = 1024
            else if ( small(1) .eq. -2065213935
     *          .and. small(2) .eq. 10752) then
*               *** vax with d_floating ***
               imach(10) = 2
               imach(14) = 56
               imach(15) = -127
               imach(16) = 127
            else if ( small(1) .eq. 1267827943
     *          .and. small(2) .eq. 704643072) then
*               *** ibm mainframe ***
               imach(10) = 16
               imach(14) = 14
               imach(15) = -64
               imach(16) = 63
            else
               write(*,9010)
               stop 777
               end if
            imach(11) = imach(14)
            imach(12) = imach(15)
            imach(13) = imach(16)
         else
            rmach = 1234567.
            if (small(1) .eq. 1234613304) then
*               *** ieee ***
               imach(10) = 2
               imach(11) = 24
               imach(12) = -125
               imach(13) = 128
               imach(14) = 53
               imach(15) = -1021
               imach(16) = 1024
               sc = 987
            else if (small(1) .eq. -1271379306) then
*               *** vax ***
               imach(10) = 2
               imach(11) = 24
               imach(12) = -127
               imach(13) = 127
               imach(14) = 56
               imach(15) = -127
               imach(16) = 127
               sc = 987
            else if (small(1) .eq. 1175639687) then
*               *** ibm mainframe ***
               imach(10) = 16
               imach(11) = 6
               imach(12) = -64
               imach(13) = 63
               imach(14) = 14
               imach(15) = -64
               imach(16) = 63
               sc = 987
            else if (small(1) .eq. 1251390520) then
*              *** convex c-1 ***
               imach(10) = 2
               imach(11) = 24
               imach(12) = -128
               imach(13) = 127
               imach(14) = 53
               imach(15) = -1024
               imach(16) = 1023
            else
               do 10 i3 = 1, 3
                  j = small(1) / 10000000
                  k = small(1) - 10000000*j
                  if (k .ne. t3e(i3)) go to 20
                  small(1) = j
 10               continue
*              *** cray t3e ***
               imach( 1) = 5
               imach( 2) = 6
               imach( 3) = 0
               imach( 4) = 0
               imach( 5) = 64
               imach( 6) = 8
               imach( 7) = 2
               imach( 8) = 63
               call i1mcr1(imach(9), k, 32767, 16777215, 16777215)
               imach(10) = 2
               imach(11) = 53
               imach(12) = -1021
               imach(13) = 1024
               imach(14) = 53
               imach(15) = -1021
               imach(16) = 1024
               go to 35
 20            call i1mcr1(j, k, 16405, 9876536, 0)
               if (small(1) .ne. j) then
                  write(*,9020)
                  stop 777
                  end if
*              *** cray 1, xmp, 2, and 3 ***
               imach(1) = 5
               imach(2) = 6
               imach(3) = 102
               imach(4) = 6
               imach(5) = 46
               imach(6) = 8
               imach(7) = 2
               imach(8) = 45
               call i1mcr1(imach(9), k, 0, 4194303, 16777215)
               imach(10) = 2
               imach(11) = 47
               imach(12) = -8188
               imach(13) = 8189
               imach(14) = 94
               imach(15) = -8141
               imach(16) = 8189
               go to 35
               end if
            end if
         imach( 1) = 5
         imach( 2) = 6
         imach( 3) = 7
         imach( 4) = 6
         imach( 5) = 32
         imach( 6) = 4
         imach( 7) = 2
         imach( 8) = 31
         imach( 9) = 2147483647
 35      sc = 987
         end if
 9010 format(/' adjust autodoubled i1mach by uncommenting data'/
     * ' statements appropriate for your machine and setting'/
     * ' imach(i) = imach(i+3) for i = 11, 12, and 13.')
 9020 format(/' adjust i1mach by uncommenting data statements'/
     * ' appropriate for your machine.')
      if (i .lt. 1  .or.  i .gt. 16) go to 40
      i1mach = imach(i)
      return
 40   write(*,*) 'i1mach(i): i =',i,' is out of bounds.'
      stop
      end
      subroutine i1mcr1(a, a1, b, c, d)
**** special computation for old cray machines ****
      integer a, a1, b, c, d
      a1 = 16777216*b + c
      a = 16777216*a1 + d
      end
      real function r1mach(i)
      integer i
c
c  single-precision machine constants
c  r1mach(1) = b**(emin-1), the smallest positive magnitude.
c  r1mach(2) = b**emax*(1 - b**(-t)), the largest magnitude.
c  r1mach(3) = b**(-t), the smallest relative spacing.
c  r1mach(4) = b**(1-t), the largest relative spacing.
c  r1mach(5) = log10(b)
c
      integer small(2)
      integer large(2)
      integer right(2)
      integer diver(2)
      integer log10(2)
c     needs to be (2) for autodouble, harris slash 6, ...
      integer sc
      save small, large, right, diver, log10, sc
      real rmach(5)
      equivalence (rmach(1),small(1))
      equivalence (rmach(2),large(1))
      equivalence (rmach(3),right(1))
      equivalence (rmach(4),diver(1))
      equivalence (rmach(5),log10(1))
      integer j, k, l, t3e(3)
      data t3e(1) / 9777664 /
      data t3e(2) / 5323660 /
      data t3e(3) / 46980 /
c  this version adapts automatically to most current machines,
c  including auto-double compilers.
c  to compile on older machines, add a c in column 1
c  on the next line
      data sc/0/
c  and remove the c from column 1 in one of the sections below.
c  constants for even older machines can be obtained by
c          mail <EMAIL>
c          send old1mach from blas
c  please send corrections to dmg or <EMAIL>.
c
c     machine constants for the honeywell dps 8/70 series.
c      data rmach(1) / o402400000000 /
c      data rmach(2) / o376777777777 /
c      data rmach(3) / o714400000000 /
c      data rmach(4) / o716400000000 /
c      data rmach(5) / o776464202324 /, sc/987/
c
c     machine constants for pdp-11 fortrans supporting
c     32-bit integers (expressed in integer and octal).
c      data small(1) /    8388608 /
c      data large(1) / 2147483647 /
c      data right(1) /  880803840 /
c      data diver(1) /  889192448 /
c      data log10(1) / 1067065499 /, sc/987/
c      data rmach(1) / o00040000000 /
c      data rmach(2) / o17777777777 /
c      data rmach(3) / o06440000000 /
c      data rmach(4) / o06500000000 /
c      data rmach(5) / o07746420233 /, sc/987/
c
c     machine constants for the univac 1100 series.
c      data rmach(1) / o000400000000 /
c      data rmach(2) / o377777777777 /
c      data rmach(3) / o146400000000 /
c      data rmach(4) / o147400000000 /
c      data rmach(5) / o177464202324 /, sc/987/
c
      if (sc .ne. 987) then
*        *** check for autodouble ***
         small(2) = 0
         rmach(1) = 1e13
         if (small(2) .ne. 0) then
*           *** autodoubled ***
            if (      small(1) .eq. 1117925532
     *          .and. small(2) .eq. -448790528) then
*              *** ieee big endian ***
               small(1) = 1048576
               small(2) = 0
               large(1) = 2146435071
               large(2) = -1
               right(1) = 1017118720
               right(2) = 0
               diver(1) = 1018167296
               diver(2) = 0
               log10(1) = 1070810131
               log10(2) = 1352628735
            else if ( small(2) .eq. 1117925532
     *          .and. small(1) .eq. -448790528) then
*              *** ieee little endian ***
               small(2) = 1048576
               small(1) = 0
               large(2) = 2146435071
               large(1) = -1
               right(2) = 1017118720
               right(1) = 0
               diver(2) = 1018167296
               diver(1) = 0
               log10(2) = 1070810131
               log10(1) = 1352628735
            else if ( small(1) .eq. -2065213935
     *          .and. small(2) .eq. 10752) then
*              *** vax with d_floating ***
               small(1) = 128
               small(2) = 0
               large(1) = -32769
               large(2) = -1
               right(1) = 9344
               right(2) = 0
               diver(1) = 9472
               diver(2) = 0
               log10(1) = 546979738
               log10(2) = -805796613
            else if ( small(1) .eq. 1267827943
     *          .and. small(2) .eq. 704643072) then
*              *** ibm mainframe ***
               small(1) = 1048576
               small(2) = 0
               large(1) = 2147483647
               large(2) = -1
               right(1) = 856686592
               right(2) = 0
               diver(1) = 873463808
               diver(2) = 0
               log10(1) = 1091781651
               log10(2) = 1352628735
            else
               write(*,9010)
               stop 777
               end if
         else
            rmach(1) = 1234567.
            if (small(1) .eq. 1234613304) then
*              *** ieee ***
               small(1) = 8388608
               large(1) = 2139095039
               right(1) = 864026624
               diver(1) = 872415232
               log10(1) = 1050288283
            else if (small(1) .eq. -1271379306) then
*              *** vax ***
               small(1) = 128
               large(1) = -32769
               right(1) = 13440
               diver(1) = 13568
               log10(1) = 547045274
            else if (small(1) .eq. 1175639687) then
*              *** ibm mainframe ***
               small(1) = 1048576
               large(1) = 2147483647
               right(1) = 990904320
               diver(1) = 1007681536
               log10(1) = 1091781651
            else if (small(1) .eq. 1251390520) then
*              *** convex c-1 ***
               small(1) = 8388608
               large(1) = 2147483647
               right(1) = 880803840
               diver(1) = 889192448
               log10(1) = 1067065499
            else
               do 10 l = 1, 3
                  j = small(1) / 10000000
                  k = small(1) - 10000000*j
                  if (k .ne. t3e(l)) go to 20
                  small(1) = j
 10               continue
*              *** cray t3e ***
               call i1mcra(small(1), k, 16, 0, 0)
               call i1mcra(large(1), k, 32751, 16777215, 16777215)
               call i1mcra(right(1), k, 15520, 0, 0)
               call i1mcra(diver(1), k, 15536, 0, 0)
               call i1mcra(log10(1), k, 16339, 4461392, 10451455)
               go to 30
 20            call i1mcra(j, k, 16405, 9876536, 0)
               if (small(1) .ne. j) then
                  write(*,9020)
                  stop 777
                  end if
*              *** cray 1, xmp, 2, and 3 ***
               call i1mcra(small(1), k, 8195, 8388608, 1)
               call i1mcra(large(1), k, 24574, 16777215, 16777214)
               call i1mcra(right(1), k, 16338, 8388608, 0)
               call i1mcra(diver(1), k, 16339, 8388608, 0)
               call i1mcra(log10(1), k, 16383, 10100890, 8715216)
               end if
            end if
 30      sc = 987
         end if
*     sanity check
      if (rmach(4) .ge. 1.0) stop 776
      if (i .lt. 1 .or. i .gt. 5) then
         write(*,*) 'r1mach(i): i =',i,' is out of bounds.'
         stop
         end if
      r1mach = rmach(i)
      return
 9010 format(/' adjust autodoubled r1mach by getting data'/
     *' appropriate for your machine from d1mach.')
 9020 format(/' adjust r1mach by uncommenting data statements'/
     *' appropriate for your machine.')
      end

      subroutine i1mcra(a, a1, b, c, d)
**** special computation for cray machines ****
      integer a, a1, b, c, d
      a1 = 16777216*b + c
      a = 16777216*a1 + d
      end

      double precision function d1mach(i)
      integer i
c
c  double-precision machine constants
c  d1mach( 1) = b**(emin-1), the smallest positive magnitude.
c  d1mach( 2) = b**emax*(1 - b**(-t)), the largest magnitude.
c  d1mach( 3) = b**(-t), the smallest relative spacing.
c  d1mach( 4) = b**(1-t), the largest relative spacing.
c  d1mach( 5) = log10(b)
c
      integer small(2)
      integer large(2)
      integer right(2)
      integer diver(2)
      integer log10(2)
      integer sc, cray1(38), j
      common /d9mach/ cray1
      save small, large, right, diver, log10, sc
      double precision dmach(5)
      equivalence (dmach(1),small(1))
      equivalence (dmach(2),large(1))
      equivalence (dmach(3),right(1))
      equivalence (dmach(4),diver(1))
      equivalence (dmach(5),log10(1))
c  this version adapts automatically to most current machines.
c  r1mach can handle auto-double compiling, but this version of
c  d1mach does not, because we do not have quad constants for
c  many machines yet.
c  to compile on older machines, add a c in column 1
c  on the next line
      data sc/0/
c  and remove the c from column 1 in one of the sections below.
c  constants for even older machines can be obtained by
c          mail <EMAIL>
c          send old1mach from blas
c  please send corrections to dmg or <EMAIL>.
c
c     machine constants for the honeywell dps 8/70 series.
c      data small(1),small(2) / o402400000000, o000000000000 /
c      data large(1),large(2) / o376777777777, o777777777777 /
c      data right(1),right(2) / o604400000000, o000000000000 /
c      data diver(1),diver(2) / o606400000000, o000000000000 /
c      data log10(1),log10(2) / o776464202324, o117571775714 /, sc/987/
c
c     machine constants for pdp-11 fortrans supporting
c     32-bit integers.
c      data small(1),small(2) /    8388608,           0 /
c      data large(1),large(2) / 2147483647,          -1 /
c      data right(1),right(2) /  612368384,           0 /
c      data diver(1),diver(2) /  620756992,           0 /
c      data log10(1),log10(2) / 1067065498, -2063872008 /, sc/987/
c
c     machine constants for the univac 1100 series.
c      data small(1),small(2) / o000040000000, o000000000000 /
c      data large(1),large(2) / o377777777777, o777777777777 /
c      data right(1),right(2) / o170540000000, o000000000000 /
c      data diver(1),diver(2) / o170640000000, o000000000000 /
c      data log10(1),log10(2) / o177746420232, o411757177572 /, sc/987/
c
c     on first call, if no data uncommented, test machine types.
      if (sc .ne. 987) then
         dmach(1) = 1.d13
         if (      small(1) .eq. 1117925532
     *       .and. small(2) .eq. -448790528) then
*           *** ieee big endian ***
            small(1) = 1048576
            small(2) = 0
            large(1) = 2146435071
            large(2) = -1
            right(1) = 1017118720
            right(2) = 0
            diver(1) = 1018167296
            diver(2) = 0
            log10(1) = 1070810131
            log10(2) = 1352628735
         else if ( small(2) .eq. 1117925532
     *       .and. small(1) .eq. -448790528) then
*           *** ieee little endian ***
            small(2) = 1048576
            small(1) = 0
            large(2) = 2146435071
            large(1) = -1
            right(2) = 1017118720
            right(1) = 0
            diver(2) = 1018167296
            diver(1) = 0
            log10(2) = 1070810131
            log10(1) = 1352628735
         else if ( small(1) .eq. -2065213935
     *       .and. small(2) .eq. 10752) then
*               *** vax with d_floating ***
            small(1) = 128
            small(2) = 0
            large(1) = -32769
            large(2) = -1
            right(1) = 9344
            right(2) = 0
            diver(1) = 9472
            diver(2) = 0
            log10(1) = 546979738
            log10(2) = -805796613
         else if ( small(1) .eq. 1267827943
     *       .and. small(2) .eq. 704643072) then
*               *** ibm mainframe ***
            small(1) = 1048576
            small(2) = 0
            large(1) = 2147483647
            large(2) = -1
            right(1) = 856686592
            right(2) = 0
            diver(1) = 873463808
            diver(2) = 0
            log10(1) = 1091781651
            log10(2) = 1352628735
         else if ( small(1) .eq. 1120022684
     *       .and. small(2) .eq. -448790528) then
*           *** convex c-1 ***
            small(1) = 1048576
            small(2) = 0
            large(1) = 2147483647
            large(2) = -1
            right(1) = 1019215872
            right(2) = 0
            diver(1) = 1020264448
            diver(2) = 0
            log10(1) = 1072907283
            log10(2) = 1352628735
         else if ( small(1) .eq. 815547074
     *       .and. small(2) .eq. 58688) then
*           *** vax g-floating ***
            small(1) = 16
            small(2) = 0
            large(1) = -32769
            large(2) = -1
            right(1) = 15552
            right(2) = 0
            diver(1) = 15568
            diver(2) = 0
            log10(1) = 1142112243
            log10(2) = 2046775455
         else
            dmach(2) = 1.d27 + 1
            dmach(3) = 1.d27
            large(2) = large(2) - right(2)
            if (large(2) .eq. 64 .and. small(2) .eq. 0) then
               cray1(1) = 67291416
               do 10 j = 1, 20
                  cray1(j+1) = cray1(j) + cray1(j)
 10               continue
               cray1(22) = cray1(21) + 321322
               do 20 j = 22, 37
                  cray1(j+1) = cray1(j) + cray1(j)
 20               continue
               if (cray1(38) .eq. small(1)) then
*                  *** cray ***
                  call i1mcry(small(1), j, 8285, 8388608, 0)
                  small(2) = 0
                  call i1mcry(large(1), j, 24574, 16777215, 16777215)
                  call i1mcry(large(2), j, 0, 16777215, 16777214)
                  call i1mcry(right(1), j, 16291, 8388608, 0)
                  right(2) = 0
                  call i1mcry(diver(1), j, 16292, 8388608, 0)
                  diver(2) = 0
                  call i1mcry(log10(1), j, 16383, 10100890, 8715215)
                  call i1mcry(log10(2), j, 0, 16226447, 9001388)
               else
                  write(*,9000)
                  stop 779
                  end if
            else
               write(*,9000)
               stop 779
               end if
            end if
         sc = 987
         end if
*    sanity check
      if (dmach(4) .ge. 1.0d0) stop 778
      if (i .lt. 1 .or. i .gt. 5) then
         write(*,*) 'd1mach(i): i =',i,' is out of bounds.'
         stop
         end if
      d1mach = dmach(i)
      return
 9000 format(/' adjust d1mach by uncommenting data statements'/
     *' appropriate for your machine.')
      end
      subroutine i1mcry(a, a1, b, c, d)
**** special computation for old cray machines ****
      integer a, a1, b, c, d
      a1 = 16777216*b + c
      a = 16777216*a1 + d
      end
      function phase(z)
      parameter(pi=3.1415926535,deg=180./pi)
      complex z
      z1=real(z)
      z2=aimag(z)
      if((z1.ne.0.).and.(z2.ne.0.))then
        phase=deg*atan2(z2,z1)
      else
        phase=0.
      endif
      return
      end
      logical function compare(x1,x2,n)
c  compares two floating point numbers and returns .true.
c  if their mantissas are the same to n significant figures
      compare=.false.
      j=int(log10(x1))
      if(j.ne.int(log10(x2)))return
      ix1=int(10.**(-j+n)*x1)
      ix2=int(10.**(-j+n)*x2)
      if(ix1.ne.ix2)return
      compare=.true.
      return
      end
      subroutine jfinit(ilev,nout,ninp,nref,nr3,nr2,nrr,
     $                  tbw,deltat,nfft,nsctinc,nsctmax,nf1,nfinc,
     $                  nfsect,mfft,uin,ainlin,ainuin,c2threshb,
     $                  c2threshe,nz,c2threshe1,perlo,perhi,nprej,
     $                  frej,npcs,nar,imode,jmode)
      logical ilev
      dimension frej(nprej)
      if(.not.ilev)then
        write(18,10)'#BIRRP Version 5 basic mode output'
      else
        write(18,10)'#BIRRP Version 5 advanced mode output'
      endif
      write(18,11)'#outputs=',nout,' inputs=',ninp,' references=',nref
      if(ilev)then
        write(18,11)'# nr3=',nr3,' nr2=',nr2,' nrr=',nrr
      endif
      write(18,12)'#tbw=',tbw,' deltat=',deltat
      write(18,11)'#nfft=',nfft,' nsctinc=',nsctinc,
     $           ' nsctmax=',nsctmax
      write(18,11)'#nf1=',nf1,' nfinc=',nfinc,' nfsect=',nfsect
      if(ilev)then
        write(18,12)'#mfft=',mfft
        write(18,12)'#uin=',uin,' ainuin=',ainuin
        write(18,12)'#c2threshb=',c2threshb,' c2threshe=',c2threshe
        write(18,12)'#perlo=',perlo,' perhi=',perhi
        write(18,11)'#nprej=',nprej
        write(18,10)'#periods'
        do 1 i=1,nprej
   1      write(18,13)'#',deltat/frej(i)
      else
        write(18,12)'#uin=',uin,' ainlin=',ainlin,' ainuin=',ainuin
        write(18,12)'#c2threshe=',c2threshe
      endif
      write(18,11)'#nz=',nz
      write(18,12)'#c2threshe1=',c2threshe1
      write(18,11)'# npcs=',npcs,' nar=',nar
      write(18,11)'#imode=',imode,' jmode=',jmode
   10 format(a)
   11 format(3(a,i8))
   12 format(3(a,g15.7))
   13 format(1x,g15.7)
      return
      end
      integer function tdiff( time1, time2 )
c
c     T D I F F     derives the time difference in seconds
c                   between two times given in format yyyy-mm-dd hh:mm:ss
c
c    Note that this is an INTEGER*4 function to cope with large
c    time differences (up to 68 years)
c
      character*19 time1, time2
      integer year1, month1, day1, hour1, min1, sec1
      integer year2, month2, day2, hour2, min2, sec2
      integer year, ddiff, hdiff, mdiff, sdiff, dayyr
      call date( 0, time1, year1, month1, day1, hour1, min1, sec1 )
      call date( 0, time2, year2, month2, day2, hour2, min2, sec2 )
      ddiff = dayyr(year2,month2,day2 ) + (year2-year1)*365 -
     &        dayyr(year1,month1,day1)
      if(((mod(year1,4).eq.0.and.mod(year1,100).ne.0)
     &    .or.(mod(year1,400).eq.0)).and.(day1.le.59))ddiff=ddiff+1
      hdiff = hour2 - hour1
      mdiff = min2  - min1
      sdiff = sec2 - sec1
      do 1 year = year1+1, year2-1
        if( (mod(year,4).eq.0  .and. mod(year,100).ne.0)
     &                .or. (mod(year,400).eq.0) ) then
          ddiff = ddiff + 1
        endif
    1 continue
      tdiff = ddiff*24*60*60  +  hdiff*60*60  + mdiff*60 + sdiff
      return
      end
      integer function dayyr(year,month,day)
      integer year, month, day, leap, i
      integer daytab(2,12)
      data daytab/31,31, 28,29, 31,31, 30,30, 31,31, 30,30,
     &              31,31, 31,31, 30,30, 31,31, 30,30, 31,31/

      if((mod(year,4).eq.0 .and.mod(year,100).ne.0)
     &              .or.(mod(year,400).eq.0)) then
        leap = 2
      else
        leap = 1
      endif
      dayyr = day
      do 1 i = 1, month-1
        dayyr = dayyr + daytab(leap,i)
   1  continue
      return
      end
      subroutine date( conv, cdate, year, month, day, hour, min, sec )
      character cdate*19
      integer conv, year, month, day, hour, min, sec
c
c     converts from date string format to integer format
c
c     conv = 1:  convert from 6 integers to character*19 string
c          = 0:  convert from character*19 string to 6 integers
      if( conv.eq.1) then
        cdate = '0000-00-00 00:00:00'
        write( cdate( 1: 4), '(i4.4)' ) year
        write( cdate( 6: 7), '(i2.2)' ) month
        write( cdate( 9:10), '(i2.2)' ) day
        write( cdate(12:13), '(i2.2)' ) hour
        write( cdate(15:16), '(i2.2)' ) min
        write( cdate(18:19), '(i2.2)' ) sec
      else
        read( cdate( 1: 4), '(i4.4)' ) year
        read( cdate( 6: 7), '(i2.2)' ) month
        read( cdate( 9:10), '(i2.2)' ) day
        read( cdate(12:13), '(i2.2)' ) hour
        read( cdate(15:16), '(i2.2)' ) min
        read( cdate(18:19), '(i2.2)' ) sec
      endif
      return
      end

<file_sep>        complex function filter(freq,fpar,nfil)
c filter routine for phoenix bc87 data
c adapted for metronix(MM)
        logical compare
        dimension fpar(*),freq1(26),rl(26),aim(26)
        filter=1.
	pi = 3.14159265358979323846264338327950
	factor = 1e0 / ( 4e0 * pi * 1e-7 )
        write(*,*)'I am in a filter routine'
        k=1
        do 5 i=1,nfil,3
          freq1(k)=fpar(i)
          rl(k)=fpar(i+1)*cos(fpar(i+2))
          write(*,*)rl(k)
          aim(k)=fpar(i+1)*sin(fpar(i+2))
    5     k=k+1
        do 10 i=1,k-1
          if(compare(freq1(i),freq,4))then
            filter=cmplx(rl(i),aim(i)) * factor
            return
          endif
   10     continue
        return
        end
<file_sep>*deck cffti
      subroutine cffti (n,wsave)
c***begin prologue  cffti
c***revision date  811015   (yymmdd)
c***category no.  d6
c***keywords fft,fast fourier transform,fourier transform,complex
c***date written  february 1978
c***author  <NAME>. (ncar)
c***purpose
c   initialize for cfftf and cfftb
c***description
c     *****************************************************************
c
c     subroutine cffti(n,wsave)
c
c     *****************************************************************
c
c     subroutine cffti initializes the array wsave which is used in
c     both cfftf and cfftb. the prime factorization of n together with
c     a tabulation of the trigonometric functions are computed and
c     stored in wsave.
c
c     input parameter
c
c     n       the length of the sequence to be transformed
c
c     output parameter
c
c     wsave   a work array which must be dimensioned at least 4*n+15
c             the same work array can be used for both cfftf and cfftb
c             as long as n remains unchanged. different wsave arrays
c             are required for different values of n. the contents of
c             wsave must not be changed between calls of cfftf or cfftb
c
c***references
c***routines called  cffti1
c***end prologue  cffti
      dimension wsave(*)
c     dimension wsave(4*n+15)
c***first executable statement  cffti
      if (n .eq. 1) return
      iw1 = n+n+1
      iw2 = iw1+n+n
      call cffti1 (n,wsave(iw1),wsave(iw2))
      return
      end
*deck cffti1
      subroutine cffti1 (n,wa,ifac)
c***begin prologue  cffti1
c***refer to cffti
c***routines called  (none)
c***end prologue  cffti1
      real ifac(*)
      dimension wa(*),ntryh(4)
c     dimension wa(2*n),ifac(15),ntryh(4)
      data ntryh(1),ntryh(2),ntryh(3),ntryh(4)/3,4,2,5/
c***first executable statement  cffti1
      nl = n
      nf = 0
      j = 0
  101 j = j+1
      if (j-4) 102,102,103
  102 ntry = ntryh(j)
      go to 104
  103 ntry = ntry+2
  104 nq = nl/ntry
      nr = nl-ntry*nq
      if (nr) 101,105,101
  105 nf = nf+1
      ifac(nf+2) = ntry
      nl = nq
      if (ntry .ne. 2) go to 107
      if (nf .eq. 1) go to 107
      do 106 i=2,nf
         ib = nf-i+2
         ifac(ib+2) = ifac(ib+1)
  106 continue
      ifac(3) = 2
  107 if (nl .ne. 1) go to 104
      ifac(1) = n
      ifac(2) = nf
      tpi = 6.28318530717959
      argh = tpi/float(n)
      i = 2
      l1 = 1
      do 110 k1=1,nf
         ip = ifac(k1+2)
         ld = 0
         l2 = l1*ip
         ido = n/l2
         idot = ido+ido+2
         ipm = ip-1
         wldc = 1.
         wlds = 0.
         arg = float(l1)*argh
         dl1c = cos(arg)
         dl1s = sin(arg)
         do 109 j=1,ipm
            i1 = i
            wa(i-1) = 1.
            wa(i) = 0.
            ld = ld+l1
            wldch = wldc
            wldc = dl1c*wldc-dl1s*wlds
            wlds = dl1s*wldch+dl1c*wlds
            dc = wldc
            ds = wlds
            do 108 ii=4,idot,2
               i = i+2
               wa(i-1) = dc*wa(i-3)-ds*wa(i-2)
               wa(i) = ds*wa(i-3)+dc*wa(i-2)
  108       continue
            if (ip .le. 5) go to 109
            wa(i1-1) = wa(i-1)
            wa(i1) = wa(i)
  109    continue
         l1 = l2
  110 continue
      return
      end
*deck cfftf
      subroutine cfftf (n,c,wsave)
c***begin prologue  cfftf
c***revision date  811015   (yymmdd)
c***category no.  d6
c***keywords fft,fast fourier transform,complex
c***date written  february 1978
c***author  swarztrauber p.n. (ncar)
c***purpose
c  forward fft of a complex periodic sequence
c***description
c     *****************************************************************
c
c     subroutine cfftf(n,c,wsave)
c
c     *****************************************************************
c
c     subroutine cfftf computes the forward complex discrete fourier
c     transform (the fourier analysis). equivalently , cfftf computes
c     the fourier coefficients of a complex periodic sequence.
c     the transform is defined below at output parameter c.
c
c     the transform is not normalized. to obtain a normalized transform
c     the output must be divided by n. otherwise a call of cfftf
c     followed by a call of cfftb will multiply the sequence by n.
c
c     the array wsave which is used by subroutine cfftf must be
c     initialized by calling subroutine cffti(n,wsave).
c
c     input parameters
c
c
c     n      the length of the complex sequence c. the method is
c            more efficient when n is the product of small primes. n
c
c     c      a complex array of length n which contains the sequence
c
c     wsave   a real work array which must be dimensioned at least 4n+15
c             in the program that calls cfftf. the wsave array must be
c             initialized by calling subroutine cffti(n,wsave) and a
c             different wsave array must be used for each different
c             value of n. this initialization does not have to be
c             repeated so long as n remains unchanged thus subsequent
c             transforms can be obtained faster than the first.
c             the same wsave array can be used by cfftf and cfftb.
c
c     output parameters
c
c     c      for j=1,...,n
c
c                c(j)=the sum from k=1,...,n of
c
c                      c(k)*exp(-i*j*k*2*pi/n)
c
c                            where i=sqrt(-1)
c
c     wsave   contains initialization calculations which must not be
c             destroyed between calls of subroutine cfftf or cfftb
c
c***references
c***routines called  cfftf1
c***end prologue  cfftf
      dimension       c(*)       ,wsave(*)
c      dimension       c(2*n)       ,wsave(4*n+15)
c***first executable statement  cfftf
      if (n .eq. 1) return
      iw1 = n+n+1
      iw2 = iw1+n+n
      call cfftf1 (n,c,wsave,wsave(iw1),wsave(iw2))
      return
      end
*deck cfftf1
      subroutine cfftf1 (n,c,ch,wa,ifac)
c***begin prologue  cfftf1
c***refer to cfftf
c***routines called  passf,passf5,passf3,passf2,passf4
c***end prologue  cfftf1
      real ifac(*)
      dimension       ch(*)      ,c(*)       ,wa(*)
c     dimension       ch(2*n)      ,c(2*n)       ,wa(2*n)      ,ifac(15)
c***first executable statement  cfftf1
      nf = ifac(2)
      na = 0
      l1 = 1
      iw = 1
      do 116 k1=1,nf
         ip = ifac(k1+2)
         l2 = ip*l1
         ido = n/l2
         idot = ido+ido
         idl1 = idot*l1
         if (ip .ne. 4) go to 103
         ix2 = iw+idot
         ix3 = ix2+idot
         if (na .ne. 0) go to 101
         call passf4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
         go to 102
  101    call passf4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
  102    na = 1-na
         go to 115
  103    if (ip .ne. 2) go to 106
         if (na .ne. 0) go to 104
         call passf2 (idot,l1,c,ch,wa(iw))
         go to 105
  104    call passf2 (idot,l1,ch,c,wa(iw))
  105    na = 1-na
         go to 115
  106    if (ip .ne. 3) go to 109
         ix2 = iw+idot
         if (na .ne. 0) go to 107
         call passf3 (idot,l1,c,ch,wa(iw),wa(ix2))
         go to 108
  107    call passf3 (idot,l1,ch,c,wa(iw),wa(ix2))
  108    na = 1-na
         go to 115
  109    if (ip .ne. 5) go to 112
         ix2 = iw+idot
         ix3 = ix2+idot
         ix4 = ix3+idot
         if (na .ne. 0) go to 110
         call passf5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
         go to 111
  110    call passf5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
  111    na = 1-na
         go to 115
  112    if (na .ne. 0) go to 113
         call passf (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
         go to 114
  113    call passf (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
  114    if (nac .ne. 0) na = 1-na
  115    l1 = l2
         iw = iw+(ip-1)*idot
  116 continue
      if (na .eq. 0) return
      n2 = n+n
      do 117 i=1,n2
         c(i) = ch(i)
  117 continue
      return
      end
*deck cfftb
      subroutine cfftb (n,c,wsave)
c***begin prologue  cfftb
c***revision date  811015   (yymmdd)
c***category no.  d6
c***keywords fft,fast fourier transform,inverse,inverse fft,complex
c***date written  february 1978
c***author  <NAME>.n. (ncar)
c***purpose
c inverse fft of a complex periodic sequence
c***description
c     *****************************************************************
c
c     subroutine cfftb(n,c,wsave)
c
c     *****************************************************************
c
c     subroutine cfftb computes the backward complex discrete fourier
c     transform (the fourier synthesis). equivalently , cfftb computes
c     a complex periodic sequence from its fourier coefficients.
c     the transform is defined below at output parameter c.
c
c     a call of cfftf followed by a call of cfftb will multiply the
c     sequence by n.
c
c     the array wsave which is used by subroutine cfftb must be
c     initialized by calling subroutine cffti(n,wsave).
c
c     input parameters
c
c
c     n      the length of the complex sequence c. the method is
c            more efficient when n is the product of small primes.
c
c     c      a complex array of length n which contains the sequence
c
c     wsave   a real work array which must be dimensioned at least 4n+15
c             in the program that calls cfftb. the wsave array must be
c             initialized by calling subroutine cffti(n,wsave) and a
c             different wsave array must be used for each different
c             value of n. this initialization does not have to be
c             repeated so long as n remains unchanged thus subsequent
c             transforms can be obtained faster than the first.
c             the same wsave array can be used by cfftf and cfftb.
c
c     output parameters
c
c     c      for j=1,...,n
c
c                c(j)=the sum from k=1,...,n of
c
c                      c(k)*exp(i*j*k*2*pi/n)
c
c                            where i=sqrt(-1)
c
c     wsave   contains initialization calculations which must not be
c             destroyed between calls of subroutine cfftf or cfftb
c***references
c***routines called  cfftb1
c***end prologue  cfftb
      dimension       c(*)       ,wsave(*)
c      dimension       c(2*n)       ,wsave(4*n+15)
c***first executable statement  cfftb
      if (n .eq. 1) return
      iw1 = n+n+1
      iw2 = iw1+n+n
      call cfftb1 (n,c,wsave,wsave(iw1),wsave(iw2))
      return
      end
*deck cfftb1
      subroutine cfftb1 (n,c,ch,wa,ifac)
c***begin prologue  cfftb1
c***refer to cfftb
c***routines called  passb,passb5,passb3,passb2,passb4
c***end prologue  cfftb1
      real ifac(*)
      dimension       ch(*)      ,c(*)       ,wa(*)
c      dimension       ch(2*n)      ,c(2*n)       ,wa(2*n)      ,ifac(15)
c***first executable statement  cfftb1
      nf = ifac(2)
      na = 0
      l1 = 1
      iw = 1
      do 116 k1=1,nf
         ip = ifac(k1+2)
         l2 = ip*l1
         ido = n/l2
         idot = ido+ido
         idl1 = idot*l1
         if (ip .ne. 4) go to 103
         ix2 = iw+idot
         ix3 = ix2+idot
         if (na .ne. 0) go to 101
         call passb4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
         go to 102
  101    call passb4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
  102    na = 1-na
         go to 115
  103    if (ip .ne. 2) go to 106
         if (na .ne. 0) go to 104
         call passb2 (idot,l1,c,ch,wa(iw))
         go to 105
  104    call passb2 (idot,l1,ch,c,wa(iw))
  105    na = 1-na
         go to 115
  106    if (ip .ne. 3) go to 109
         ix2 = iw+idot
         if (na .ne. 0) go to 107
         call passb3 (idot,l1,c,ch,wa(iw),wa(ix2))
         go to 108
  107    call passb3 (idot,l1,ch,c,wa(iw),wa(ix2))
  108    na = 1-na
         go to 115
  109    if (ip .ne. 5) go to 112
         ix2 = iw+idot
         ix3 = ix2+idot
         ix4 = ix3+idot
         if (na .ne. 0) go to 110
         call passb5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
         go to 111
  110    call passb5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
  111    na = 1-na
         go to 115
  112    if (na .ne. 0) go to 113
         call passb (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
         go to 114
  113    call passb (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
  114    if (nac .ne. 0) na = 1-na
  115    l1 = l2
         iw = iw+(ip-1)*idot
  116 continue
      if (na .eq. 0) return
      n2 = n+n
      do 117 i=1,n2
         c(i) = ch(i)
  117 continue
      return
      end
*deck passb
      subroutine passb (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
c***begin prologue  passb
c***refer to cfftb
c***routines called  (none)
c***end prologue  passb
      dimension       ch(ido,l1,ip)          ,cc(ido,ip,l1)          ,
     1                c1(ido,l1,ip)          ,wa(*)      ,c2(idl1,ip),
     2                ch2(idl1,ip)
c***first executable statement  passb
      idot = ido/2
      ipp2 = ip+2
      ipph = (ip+1)/2
      idp = ip*ido
c
      if (ido .lt. l1) go to 106
      do 103 j=2,ipph
         jc = ipp2-j
         do 102 k=1,l1
            do 101 i=1,ido
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  101       continue
  102    continue
  103 continue
      do 105 k=1,l1
         do 104 i=1,ido
            ch(i,k,1) = cc(i,1,k)
  104    continue
  105 continue
      go to 112
  106 do 109 j=2,ipph
         jc = ipp2-j
         do 108 i=1,ido
            do 107 k=1,l1
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  107       continue
  108    continue
  109 continue
      do 111 i=1,ido
         do 110 k=1,l1
            ch(i,k,1) = cc(i,1,k)
  110    continue
  111 continue
  112 idl = 2-ido
      inc = 0
      do 116 l=2,ipph
         lc = ipp2-l
         idl = idl+ido
         do 113 ik=1,idl1
            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
            c2(ik,lc) = wa(idl)*ch2(ik,ip)
  113    continue
         idlj = idl
         inc = inc+ido
         do 115 j=3,ipph
            jc = ipp2-j
            idlj = idlj+inc
            if (idlj .gt. idp) idlj = idlj-idp
            war = wa(idlj-1)
            wai = wa(idlj)
            do 114 ik=1,idl1
               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
               c2(ik,lc) = c2(ik,lc)+wai*ch2(ik,jc)
  114       continue
  115    continue
  116 continue
      do 118 j=2,ipph
         do 117 ik=1,idl1
            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
  117    continue
  118 continue
      do 120 j=2,ipph
         jc = ipp2-j
         do 119 ik=2,idl1,2
            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
  119    continue
  120 continue
      nac = 1
      if (ido .eq. 2) return
      nac = 0
      do 121 ik=1,idl1
         c2(ik,1) = ch2(ik,1)
  121 continue
      do 123 j=2,ip
         do 122 k=1,l1
            c1(1,k,j) = ch(1,k,j)
            c1(2,k,j) = ch(2,k,j)
  122    continue
  123 continue
      if (idot .gt. l1) go to 127
      idij = 0
      do 126 j=2,ip
         idij = idij+2
         do 125 i=4,ido,2
            idij = idij+2
            do 124 k=1,l1
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
  124       continue
  125    continue
  126 continue
      return
  127 idj = 2-ido
      do 130 j=2,ip
         idj = idj+ido
         do 129 k=1,l1
            idij = idj
            do 128 i=4,ido,2
               idij = idij+2
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
  128       continue
  129    continue
  130 continue
      return
      end
*deck passb2
      subroutine passb2 (ido,l1,cc,ch,wa1)
c***begin prologue  passb2
c***refer to cfftb
c***routines called  (none)
c***end prologue  passb2
      dimension       cc(ido,2,l1)           ,ch(ido,l1,2)           ,
     1                wa1(*)
c***first executable statement  passb2
      if (ido .gt. 2) go to 102
      do 101 k=1,l1
         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
            ti2 = cc(i,1,k)-cc(i,2,k)
            ch(i,k,2) = wa1(i-1)*ti2+wa1(i)*tr2
            ch(i-1,k,2) = wa1(i-1)*tr2-wa1(i)*ti2
  103    continue
  104 continue
      return
      end
*deck passb3
      subroutine passb3 (ido,l1,cc,ch,wa1,wa2)
c***begin prologue  passb3
c***refer to cfftb
c***routines called  (none)
c***end prologue  passb3
      dimension       cc(ido,3,l1)           ,ch(ido,l1,3)           ,
     1                wa1(*)     ,wa2(*)
      data taur,taui /-.5,.866025403784439/
c***first executable statement  passb3
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         tr2 = cc(1,2,k)+cc(1,3,k)
         cr2 = cc(1,1,k)+taur*tr2
         ch(1,k,1) = cc(1,1,k)+tr2
         ti2 = cc(2,2,k)+cc(2,3,k)
         ci2 = cc(2,1,k)+taur*ti2
         ch(2,k,1) = cc(2,1,k)+ti2
         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
         ch(1,k,2) = cr2-ci3
         ch(1,k,3) = cr2+ci3
         ch(2,k,2) = ci2+cr3
         ch(2,k,3) = ci2-cr3
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
            cr2 = cc(i-1,1,k)+taur*tr2
            ch(i-1,k,1) = cc(i-1,1,k)+tr2
            ti2 = cc(i,2,k)+cc(i,3,k)
            ci2 = cc(i,1,k)+taur*ti2
            ch(i,k,1) = cc(i,1,k)+ti2
            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
            dr2 = cr2-ci3
            dr3 = cr2+ci3
            di2 = ci2+cr3
            di3 = ci2-cr3
            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
  103    continue
  104 continue
      return
      end
*deck passb4
      subroutine passb4 (ido,l1,cc,ch,wa1,wa2,wa3)
c***begin prologue  passb4
c***refer to cfftb
c***routines called (none)
c***end prologue  passb4
      dimension       cc(ido,4,l1)           ,ch(ido,l1,4)           ,
     1                wa1(*)     ,wa2(*)     ,wa3(*)
c***first executable statement  passb4
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti1 = cc(2,1,k)-cc(2,3,k)
         ti2 = cc(2,1,k)+cc(2,3,k)
         tr4 = cc(2,4,k)-cc(2,2,k)
         ti3 = cc(2,2,k)+cc(2,4,k)
         tr1 = cc(1,1,k)-cc(1,3,k)
         tr2 = cc(1,1,k)+cc(1,3,k)
         ti4 = cc(1,2,k)-cc(1,4,k)
         tr3 = cc(1,2,k)+cc(1,4,k)
         ch(1,k,1) = tr2+tr3
         ch(1,k,3) = tr2-tr3
         ch(2,k,1) = ti2+ti3
         ch(2,k,3) = ti2-ti3
         ch(1,k,2) = tr1+tr4
         ch(1,k,4) = tr1-tr4
         ch(2,k,2) = ti1+ti4
         ch(2,k,4) = ti1-ti4
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti1 = cc(i,1,k)-cc(i,3,k)
            ti2 = cc(i,1,k)+cc(i,3,k)
            ti3 = cc(i,2,k)+cc(i,4,k)
            tr4 = cc(i,4,k)-cc(i,2,k)
            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
            ti4 = cc(i-1,2,k)-cc(i-1,4,k)
            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
            ch(i-1,k,1) = tr2+tr3
            cr3 = tr2-tr3
            ch(i,k,1) = ti2+ti3
            ci3 = ti2-ti3
            cr2 = tr1+tr4
            cr4 = tr1-tr4
            ci2 = ti1+ti4
            ci4 = ti1-ti4
            ch(i-1,k,2) = wa1(i-1)*cr2-wa1(i)*ci2
            ch(i,k,2) = wa1(i-1)*ci2+wa1(i)*cr2
            ch(i-1,k,3) = wa2(i-1)*cr3-wa2(i)*ci3
            ch(i,k,3) = wa2(i-1)*ci3+wa2(i)*cr3
            ch(i-1,k,4) = wa3(i-1)*cr4-wa3(i)*ci4
            ch(i,k,4) = wa3(i-1)*ci4+wa3(i)*cr4
  103    continue
  104 continue
      return
      end
*deck passb5
      subroutine passb5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
c***begin prologue  passb5
c***refer to cfftb
c***routines called  (none)
c***end prologue  passb5
      dimension       cc(ido,5,l1)           ,ch(ido,l1,5)           ,
     1                wa1(*)     ,wa2(*)     ,wa3(*)     ,wa4(*)
      data tr11,ti11,tr12,ti12 /.309016994374947,.951056516295154,
     1-.809016994374947,.587785252292473/
c***first executable statement  passb5
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti5 = cc(2,2,k)-cc(2,5,k)
         ti2 = cc(2,2,k)+cc(2,5,k)
         ti4 = cc(2,3,k)-cc(2,4,k)
         ti3 = cc(2,3,k)+cc(2,4,k)
         tr5 = cc(1,2,k)-cc(1,5,k)
         tr2 = cc(1,2,k)+cc(1,5,k)
         tr4 = cc(1,3,k)-cc(1,4,k)
         tr3 = cc(1,3,k)+cc(1,4,k)
         ch(1,k,1) = cc(1,1,k)+tr2+tr3
         ch(2,k,1) = cc(2,1,k)+ti2+ti3
         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
         cr5 = ti11*tr5+ti12*tr4
         ci5 = ti11*ti5+ti12*ti4
         cr4 = ti12*tr5-ti11*tr4
         ci4 = ti12*ti5-ti11*ti4
         ch(1,k,2) = cr2-ci5
         ch(1,k,5) = cr2+ci5
         ch(2,k,2) = ci2+cr5
         ch(2,k,3) = ci3+cr4
         ch(1,k,3) = cr3-ci4
         ch(1,k,4) = cr3+ci4
         ch(2,k,4) = ci3-cr4
         ch(2,k,5) = ci2-cr5
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti5 = cc(i,2,k)-cc(i,5,k)
            ti2 = cc(i,2,k)+cc(i,5,k)
            ti4 = cc(i,3,k)-cc(i,4,k)
            ti3 = cc(i,3,k)+cc(i,4,k)
            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
            ch(i,k,1) = cc(i,1,k)+ti2+ti3
            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
            cr5 = ti11*tr5+ti12*tr4
            ci5 = ti11*ti5+ti12*ti4
            cr4 = ti12*tr5-ti11*tr4
            ci4 = ti12*ti5-ti11*ti4
            dr3 = cr3-ci4
            dr4 = cr3+ci4
            di3 = ci3+cr4
            di4 = ci3-cr4
            dr5 = cr2+ci5
            dr2 = cr2-ci5
            di5 = ci2-cr5
            di2 = ci2+cr5
            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
            ch(i-1,k,4) = wa3(i-1)*dr4-wa3(i)*di4
            ch(i,k,4) = wa3(i-1)*di4+wa3(i)*dr4
            ch(i-1,k,5) = wa4(i-1)*dr5-wa4(i)*di5
            ch(i,k,5) = wa4(i-1)*di5+wa4(i)*dr5
  103    continue
  104 continue
      return
      end
*deck passf
      subroutine passf (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
c***begin prologue  passf
c***refer to cfftf
c***routines called  (none)
c***end prologue  passf
      dimension       ch(ido,l1,ip)          ,cc(ido,ip,l1)          ,
     1                c1(ido,l1,ip)          ,wa(*)      ,c2(idl1,ip),
     2                ch2(idl1,ip)
c***first executable statement  passf
      idot = ido/2
      ipp2 = ip+2
      ipph = (ip+1)/2
      idp = ip*ido
c
      if (ido .lt. l1) go to 106
      do 103 j=2,ipph
         jc = ipp2-j
         do 102 k=1,l1
            do 101 i=1,ido
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  101       continue
  102    continue
  103 continue
      do 105 k=1,l1
         do 104 i=1,ido
            ch(i,k,1) = cc(i,1,k)
  104    continue
  105 continue
      go to 112
  106 do 109 j=2,ipph
         jc = ipp2-j
         do 108 i=1,ido
            do 107 k=1,l1
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  107       continue
  108    continue
  109 continue
      do 111 i=1,ido
         do 110 k=1,l1
            ch(i,k,1) = cc(i,1,k)
  110    continue
  111 continue
  112 idl = 2-ido
      inc = 0
      do 116 l=2,ipph
         lc = ipp2-l
         idl = idl+ido
         do 113 ik=1,idl1
            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
            c2(ik,lc) = -wa(idl)*ch2(ik,ip)
  113    continue
         idlj = idl
         inc = inc+ido
         do 115 j=3,ipph
            jc = ipp2-j
            idlj = idlj+inc
            if (idlj .gt. idp) idlj = idlj-idp
            war = wa(idlj-1)
            wai = wa(idlj)
            do 114 ik=1,idl1
               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
               c2(ik,lc) = c2(ik,lc)-wai*ch2(ik,jc)
  114       continue
  115    continue
  116 continue
      do 118 j=2,ipph
         do 117 ik=1,idl1
            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
  117    continue
  118 continue
      do 120 j=2,ipph
         jc = ipp2-j
         do 119 ik=2,idl1,2
            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
  119    continue
  120 continue
      nac = 1
      if (ido .eq. 2) return
      nac = 0
      do 121 ik=1,idl1
         c2(ik,1) = ch2(ik,1)
  121 continue
      do 123 j=2,ip
         do 122 k=1,l1
            c1(1,k,j) = ch(1,k,j)
            c1(2,k,j) = ch(2,k,j)
  122    continue
  123 continue
      if (idot .gt. l1) go to 127
      idij = 0
      do 126 j=2,ip
         idij = idij+2
         do 125 i=4,ido,2
            idij = idij+2
            do 124 k=1,l1
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
  124       continue
  125    continue
  126 continue
      return
  127 idj = 2-ido
      do 130 j=2,ip
         idj = idj+ido
         do 129 k=1,l1
            idij = idj
            do 128 i=4,ido,2
               idij = idij+2
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
  128       continue
  129    continue
  130 continue
      return
      end
*deck passf2
      subroutine passf2 (ido,l1,cc,ch,wa1)
c***begin prologue  passf2
c***refer to cfftf
c***routines called  (none)
c***end prologue  passf2
      dimension       cc(ido,2,l1)           ,ch(ido,l1,2)           ,
     1                wa1(*)
c***first executable statement  passf2
      if (ido .gt. 2) go to 102
      do 101 k=1,l1
         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
            ti2 = cc(i,1,k)-cc(i,2,k)
            ch(i,k,2) = wa1(i-1)*ti2-wa1(i)*tr2
            ch(i-1,k,2) = wa1(i-1)*tr2+wa1(i)*ti2
  103    continue
  104 continue
      return
      end
*deck passf3
      subroutine passf3 (ido,l1,cc,ch,wa1,wa2)
c***begin prologue  passf3
c***refer to cfftf
c***routines called  (none)
c***end prologue  passf3
      dimension       cc(ido,3,l1)           ,ch(ido,l1,3)           ,
     1                wa1(*)     ,wa2(*)
      data taur,taui /-.5,-.866025403784439/
c***first executable statement  passf3
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         tr2 = cc(1,2,k)+cc(1,3,k)
         cr2 = cc(1,1,k)+taur*tr2
         ch(1,k,1) = cc(1,1,k)+tr2
         ti2 = cc(2,2,k)+cc(2,3,k)
         ci2 = cc(2,1,k)+taur*ti2
         ch(2,k,1) = cc(2,1,k)+ti2
         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
         ch(1,k,2) = cr2-ci3
         ch(1,k,3) = cr2+ci3
         ch(2,k,2) = ci2+cr3
         ch(2,k,3) = ci2-cr3
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
            cr2 = cc(i-1,1,k)+taur*tr2
            ch(i-1,k,1) = cc(i-1,1,k)+tr2
            ti2 = cc(i,2,k)+cc(i,3,k)
            ci2 = cc(i,1,k)+taur*ti2
            ch(i,k,1) = cc(i,1,k)+ti2
            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
            dr2 = cr2-ci3
            dr3 = cr2+ci3
            di2 = ci2+cr3
            di3 = ci2-cr3
            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
  103    continue
  104 continue
      return
      end
*deck passf4
      subroutine passf4 (ido,l1,cc,ch,wa1,wa2,wa3)
c***begin prologue  passf4
c***refer to cfftf
c***routines called  (none)
c***end prologue  passf4
      dimension       cc(ido,4,l1)           ,ch(ido,l1,4)           ,
     1                wa1(*)     ,wa2(*)     ,wa3(*)
c***first executable statement  passf4
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti1 = cc(2,1,k)-cc(2,3,k)
         ti2 = cc(2,1,k)+cc(2,3,k)
         tr4 = cc(2,2,k)-cc(2,4,k)
         ti3 = cc(2,2,k)+cc(2,4,k)
         tr1 = cc(1,1,k)-cc(1,3,k)
         tr2 = cc(1,1,k)+cc(1,3,k)
         ti4 = cc(1,4,k)-cc(1,2,k)
         tr3 = cc(1,2,k)+cc(1,4,k)
         ch(1,k,1) = tr2+tr3
         ch(1,k,3) = tr2-tr3
         ch(2,k,1) = ti2+ti3
         ch(2,k,3) = ti2-ti3
         ch(1,k,2) = tr1+tr4
         ch(1,k,4) = tr1-tr4
         ch(2,k,2) = ti1+ti4
         ch(2,k,4) = ti1-ti4
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti1 = cc(i,1,k)-cc(i,3,k)
            ti2 = cc(i,1,k)+cc(i,3,k)
            ti3 = cc(i,2,k)+cc(i,4,k)
            tr4 = cc(i,2,k)-cc(i,4,k)
            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
            ti4 = cc(i-1,4,k)-cc(i-1,2,k)
            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
            ch(i-1,k,1) = tr2+tr3
            cr3 = tr2-tr3
            ch(i,k,1) = ti2+ti3
            ci3 = ti2-ti3
            cr2 = tr1+tr4
            cr4 = tr1-tr4
            ci2 = ti1+ti4
            ci4 = ti1-ti4
            ch(i-1,k,2) = wa1(i-1)*cr2+wa1(i)*ci2
            ch(i,k,2) = wa1(i-1)*ci2-wa1(i)*cr2
            ch(i-1,k,3) = wa2(i-1)*cr3+wa2(i)*ci3
            ch(i,k,3) = wa2(i-1)*ci3-wa2(i)*cr3
            ch(i-1,k,4) = wa3(i-1)*cr4+wa3(i)*ci4
            ch(i,k,4) = wa3(i-1)*ci4-wa3(i)*cr4
  103    continue
  104 continue
      return
      end
*deck passf5
      subroutine passf5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
c***begin prologue  passf5
c***refer to cfftf
c***routines called  (none)
c***end prologue  passf5
      dimension       cc(ido,5,l1)           ,ch(ido,l1,5)           ,
     1                wa1(*)     ,wa2(*)     ,wa3(*)     ,wa4(*)
      data tr11,ti11,tr12,ti12 /.309016994374947,-.951056516295154,
     1-.809016994374947,-.587785252292473/
c***first executable statement  passf5
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti5 = cc(2,2,k)-cc(2,5,k)
         ti2 = cc(2,2,k)+cc(2,5,k)
         ti4 = cc(2,3,k)-cc(2,4,k)
         ti3 = cc(2,3,k)+cc(2,4,k)
         tr5 = cc(1,2,k)-cc(1,5,k)
         tr2 = cc(1,2,k)+cc(1,5,k)
         tr4 = cc(1,3,k)-cc(1,4,k)
         tr3 = cc(1,3,k)+cc(1,4,k)
         ch(1,k,1) = cc(1,1,k)+tr2+tr3
         ch(2,k,1) = cc(2,1,k)+ti2+ti3
         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
         cr5 = ti11*tr5+ti12*tr4
         ci5 = ti11*ti5+ti12*ti4
         cr4 = ti12*tr5-ti11*tr4
         ci4 = ti12*ti5-ti11*ti4
         ch(1,k,2) = cr2-ci5
         ch(1,k,5) = cr2+ci5
         ch(2,k,2) = ci2+cr5
         ch(2,k,3) = ci3+cr4
         ch(1,k,3) = cr3-ci4
         ch(1,k,4) = cr3+ci4
         ch(2,k,4) = ci3-cr4
         ch(2,k,5) = ci2-cr5
  101 continue
      return
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti5 = cc(i,2,k)-cc(i,5,k)
            ti2 = cc(i,2,k)+cc(i,5,k)
            ti4 = cc(i,3,k)-cc(i,4,k)
            ti3 = cc(i,3,k)+cc(i,4,k)
            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
            ch(i,k,1) = cc(i,1,k)+ti2+ti3
            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
            cr5 = ti11*tr5+ti12*tr4
            ci5 = ti11*ti5+ti12*ti4
            cr4 = ti12*tr5-ti11*tr4
            ci4 = ti12*ti5-ti11*ti4
            dr3 = cr3-ci4
            dr4 = cr3+ci4
            di3 = ci3+cr4
            di4 = ci3-cr4
            dr5 = cr2+ci5
            dr2 = cr2-ci5
            di5 = ci2-cr5
            di2 = ci2+cr5
            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
            ch(i-1,k,4) = wa3(i-1)*dr4+wa3(i)*di4
            ch(i,k,4) = wa3(i-1)*di4-wa3(i)*dr4
            ch(i-1,k,5) = wa4(i-1)*dr5+wa4(i)*di5
            ch(i,k,5) = wa4(i-1)*di5-wa4(i)*dr5
  103    continue
  104 continue
      return
      end
      subroutine dcffti (n,wsave)
      double precision wsave(*)
c
      if (n .eq. 1) return
c
      iw1 = n+n+1
      iw2 = iw1+n+n
      call dcfti1 (n,wsave(iw1),wsave(iw2))
c
      return
      end
      subroutine dcfti1 (n,wa,ifac)
      double precision wa(*), arg, argh, argld, fi, tpi
      double precision ifac(*)
      integer ntryh(4)
      data ntryh(1), ntryh(2), ntryh(3), ntryh(4) /3, 4, 2, 5/
      data tpi   /  6.2831853071 7958647692 5286766559 00577d0/
c
      nl = n
      nf = 0
      j = 0
c
  101 j = j+1
      if (j.le.4) ntry = ntryh(j)
      if (j.gt.4) ntry = ntry + 2
  104 nq = nl/ntry
      nr = nl-ntry*nq
      if (nr.ne.0) go to 101
c
  105 nf = nf+1
      ifac(nf+2) = ntry
      nl = nq
      if (ntry .ne. 2) go to 107
      if (nf .eq. 1) go to 107
      do 106 i=2,nf
         ib = nf-i+2
         ifac(ib+2) = ifac(ib+1)
  106 continue
      ifac(3) = 2
c
  107 if (nl .ne. 1) go to 104
c
      ifac(1) = n
      ifac(2) = nf
c
      argh = tpi/dfloat(n)
      i = 2
      l1 = 1
      do 110 k1=1,nf
         ip = ifac(k1+2)
         ld = 0
         l2 = l1*ip
         ido = n/l2
         idot = ido+ido+2
         ipm = ip-1
c
         do 109 j=1,ipm
            i1 = i
            wa(i-1) = 1.d0
            wa(i) = 0.d0
            ld = ld+l1
            fi = 0.d0
            argld = dfloat(ld)*argh
            do 108 ii=4,idot,2
               i = i+2
               fi = fi+1.d0
               arg = fi*argld
               wa(i-1) = dcos(arg)
               wa(i) = dsin(arg)
  108       continue
            if (ip .le. 5) go to 109
            wa(i1-1) = wa(i-1)
            wa(i1) = wa(i)
  109    continue
c
         l1 = l2
  110 continue
c
      return
      end
      subroutine dcfftf (n,c,wsave)
      double precision c(*), wsave(*)
c
      if (n .eq. 1) return
c
      iw1 = n+n+1
      iw2 = iw1+n+n
      call dcftf1 (n,c,wsave,wsave(iw1),wsave(iw2))
c
      return
      end
      subroutine dcftf1 (n,c,ch,wa,ifac)
      double precision c(*), ch(*), wa(*)
      double precision ifac(*)
c
      nf = ifac(2)
      na = 0
      l1 = 1
      iw = 1
      do 116 k1=1,nf
         ip = ifac(k1+2)
         l2 = ip*l1
         ido = n/l2
         idot = ido+ido
         idl1 = idot*l1
         if (ip .ne. 4) go to 103
         ix2 = iw+idot
         ix3 = ix2+idot
         if (na .ne. 0) go to 101
         call dpssf4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
         go to 102
  101    call dpssf4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
  102    na = 1-na
         go to 115
c
  103    if (ip .ne. 2) go to 106
         if (na .ne. 0) go to 104
         call dpssf2 (idot,l1,c,ch,wa(iw))
         go to 105
  104    call dpssf2 (idot,l1,ch,c,wa(iw))
  105    na = 1-na
         go to 115
c
  106    if (ip .ne. 3) go to 109
         ix2 = iw+idot
         if (na .ne. 0) go to 107
         call dpssf3 (idot,l1,c,ch,wa(iw),wa(ix2))
         go to 108
  107    call dpssf3 (idot,l1,ch,c,wa(iw),wa(ix2))
  108    na = 1-na
         go to 115
c
  109    if (ip .ne. 5) go to 112
         ix2 = iw+idot
         ix3 = ix2+idot
         ix4 = ix3+idot
         if (na .ne. 0) go to 110
         call dpssf5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
         go to 111
  110    call dpssf5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
  111    na = 1-na
         go to 115
c
  112    if (na .ne. 0) go to 113
         call dpssf (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
         go to 114
  113    call dpssf (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
  114    if (nac .ne. 0) na = 1-na
c
  115    l1 = l2
         iw = iw+(ip-1)*idot
  116 continue
      if (na .eq. 0) return
c
      n2 = n+n
      do 117 i=1,n2
         c(i) = ch(i)
  117 continue
c
      return
      end
      subroutine dpssf (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
      double precision cc(ido,ip,l1), c1(ido,l1,ip), c2(idl1,ip),
     1  ch(ido,l1,ip), ch2(idl1,ip), wa(*), wai, war
c
      idot = ido/2
      nt = ip*idl1
      ipp2 = ip+2
      ipph = (ip+1)/2
      idp = ip*ido
c
      if (ido .lt. l1) go to 106
      do 103 j=2,ipph
         jc = ipp2-j
         do 102 k=1,l1
            do 101 i=1,ido
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  101       continue
  102    continue
  103 continue
c
      do 105 k=1,l1
         do 104 i=1,ido
            ch(i,k,1) = cc(i,1,k)
  104    continue
  105 continue
      go to 112
c
  106 do 109 j=2,ipph
         jc = ipp2-j
         do 108 i=1,ido
            do 107 k=1,l1
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  107       continue
  108    continue
  109 continue
c
      do 111 i=1,ido
         do 110 k=1,l1
            ch(i,k,1) = cc(i,1,k)
  110    continue
  111 continue
c
  112 idl = 2-ido
      inc = 0
      do 116 l=2,ipph
         lc = ipp2-l
         idl = idl+ido
         do 113 ik=1,idl1
            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
            c2(ik,lc) = -wa(idl)*ch2(ik,ip)
  113    continue
         idlj = idl
         inc = inc+ido
         do 115 j=3,ipph
            jc = ipp2-j
            idlj = idlj+inc
            if (idlj .gt. idp) idlj = idlj-idp
            war = wa(idlj-1)
            wai = wa(idlj)
            do 114 ik=1,idl1
               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
               c2(ik,lc) = c2(ik,lc)-wai*ch2(ik,jc)
  114       continue
  115    continue
  116 continue
c
      do 118 j=2,ipph
         do 117 ik=1,idl1
            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
  117    continue
  118 continue
c
      do 120 j=2,ipph
         jc = ipp2-j
         do 119 ik=2,idl1,2
            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
  119    continue
  120 continue
c
      nac = 1
      if (ido .eq. 2) return
      nac = 0
c
      do 121 ik=1,idl1
         c2(ik,1) = ch2(ik,1)
  121 continue
c
      do 123 j=2,ip
         do 122 k=1,l1
            c1(1,k,j) = ch(1,k,j)
            c1(2,k,j) = ch(2,k,j)
  122    continue
  123 continue
c
      if (idot .gt. l1) go to 127
      idij = 0
      do 126 j=2,ip
         idij = idij+2
         do 125 i=4,ido,2
            idij = idij+2
            do 124 k=1,l1
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
  124       continue
  125    continue
  126 continue
      return
c
  127 idj = 2-ido
      do 130 j=2,ip
         idj = idj+ido
         do 129 k=1,l1
            idij = idj
            do 128 i=4,ido,2
               idij = idij+2
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)+wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)-wa(idij)*ch(i-1,k,j)
  128       continue
  129    continue
  130 continue
c
      return
      end
      subroutine dpssf2 (ido,l1,cc,ch,wa1)
      double precision cc(ido,2,l1), ch(ido,l1,2), wa1(*), ti2, tr2
c
      if (ido .gt. 2) go to 102
      do 101 k=1,l1
         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
            ti2 = cc(i,1,k)-cc(i,2,k)
            ch(i,k,2) = wa1(i-1)*ti2-wa1(i)*tr2
            ch(i-1,k,2) = wa1(i-1)*tr2+wa1(i)*ti2
  103    continue
  104 continue
c
      return
      end
      subroutine dpssf3 (ido,l1,cc,ch,wa1,wa2)
      double precision cc(ido,3,l1), ch(ido,l1,3), wa1(*), wa2(*),
     1  ci2, ci3, cr2, cr3, di2, di3, dr2, dr3, taui, taur, ti2, tr2
      data taur / -0.5 d0 /
      data taui  / -0.8660254037 8443864676 3723170752 93618d0/
c
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         tr2 = cc(1,2,k)+cc(1,3,k)
         cr2 = cc(1,1,k)+taur*tr2
         ch(1,k,1) = cc(1,1,k)+tr2
         ti2 = cc(2,2,k)+cc(2,3,k)
         ci2 = cc(2,1,k)+taur*ti2
         ch(2,k,1) = cc(2,1,k)+ti2
         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
         ch(1,k,2) = cr2-ci3
         ch(1,k,3) = cr2+ci3
         ch(2,k,2) = ci2+cr3
         ch(2,k,3) = ci2-cr3
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
            cr2 = cc(i-1,1,k)+taur*tr2
            ch(i-1,k,1) = cc(i-1,1,k)+tr2
            ti2 = cc(i,2,k)+cc(i,3,k)
            ci2 = cc(i,1,k)+taur*ti2
            ch(i,k,1) = cc(i,1,k)+ti2
            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
            dr2 = cr2-ci3
            dr3 = cr2+ci3
            di2 = ci2+cr3
            di3 = ci2-cr3
            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
  103    continue
  104 continue
c
      return
      end
      subroutine dpssf4 (ido,l1,cc,ch,wa1,wa2,wa3)
      double precision cc(ido,4,l1), ch(ido,l1,4), wa1(*), wa2(*),
     1  wa3(*), ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4,
     2  tr1, tr2, tr3, tr4
c
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti1 = cc(2,1,k)-cc(2,3,k)
         ti2 = cc(2,1,k)+cc(2,3,k)
         tr4 = cc(2,2,k)-cc(2,4,k)
         ti3 = cc(2,2,k)+cc(2,4,k)
         tr1 = cc(1,1,k)-cc(1,3,k)
         tr2 = cc(1,1,k)+cc(1,3,k)
         ti4 = cc(1,4,k)-cc(1,2,k)
         tr3 = cc(1,2,k)+cc(1,4,k)
         ch(1,k,1) = tr2+tr3
         ch(1,k,3) = tr2-tr3
         ch(2,k,1) = ti2+ti3
         ch(2,k,3) = ti2-ti3
         ch(1,k,2) = tr1+tr4
         ch(1,k,4) = tr1-tr4
         ch(2,k,2) = ti1+ti4
         ch(2,k,4) = ti1-ti4
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti1 = cc(i,1,k)-cc(i,3,k)
            ti2 = cc(i,1,k)+cc(i,3,k)
            ti3 = cc(i,2,k)+cc(i,4,k)
            tr4 = cc(i,2,k)-cc(i,4,k)
            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
            ti4 = cc(i-1,4,k)-cc(i-1,2,k)
            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
            ch(i-1,k,1) = tr2+tr3
            cr3 = tr2-tr3
            ch(i,k,1) = ti2+ti3
            ci3 = ti2-ti3
            cr2 = tr1+tr4
            cr4 = tr1-tr4
            ci2 = ti1+ti4
            ci4 = ti1-ti4
            ch(i-1,k,2) = wa1(i-1)*cr2+wa1(i)*ci2
            ch(i,k,2) = wa1(i-1)*ci2-wa1(i)*cr2
            ch(i-1,k,3) = wa2(i-1)*cr3+wa2(i)*ci3
            ch(i,k,3) = wa2(i-1)*ci3-wa2(i)*cr3
            ch(i-1,k,4) = wa3(i-1)*cr4+wa3(i)*ci4
            ch(i,k,4) = wa3(i-1)*ci4-wa3(i)*cr4
  103    continue
  104 continue
c
      return
      end
      subroutine dpssf5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
      double precision cc(ido,5,l1), ch(ido,l1,5), wa1(*), wa2(*),
     1  wa3(*), wa4(*), ci2, ci3, ci4, ci5, cr2, cr3, cr4, cr5, di2,
     2  di3, di4, di5, dr2, dr3, dr4, dr5, ti11, ti12, ti2, ti3, ti4,
     3  ti5, tr11, tr12, tr2, tr3, tr4, tr5
      data tr11  /  0.3090169943 7494742410 2293417182 81906d0/
      data ti11  / -0.9510565162 9515357211 6439333379 38214d0/
      data tr12  / -0.8090169943 7494742410 2293417182 81906d0/
      data ti12  / -0.5877852522 9247312916 8705954639 07277d0/
c
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti5 = cc(2,2,k)-cc(2,5,k)
         ti2 = cc(2,2,k)+cc(2,5,k)
         ti4 = cc(2,3,k)-cc(2,4,k)
         ti3 = cc(2,3,k)+cc(2,4,k)
         tr5 = cc(1,2,k)-cc(1,5,k)
         tr2 = cc(1,2,k)+cc(1,5,k)
         tr4 = cc(1,3,k)-cc(1,4,k)
         tr3 = cc(1,3,k)+cc(1,4,k)
         ch(1,k,1) = cc(1,1,k)+tr2+tr3
         ch(2,k,1) = cc(2,1,k)+ti2+ti3
         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
         cr5 = ti11*tr5+ti12*tr4
         ci5 = ti11*ti5+ti12*ti4
         cr4 = ti12*tr5-ti11*tr4
         ci4 = ti12*ti5-ti11*ti4
         ch(1,k,2) = cr2-ci5
         ch(1,k,5) = cr2+ci5
         ch(2,k,2) = ci2+cr5
         ch(2,k,3) = ci3+cr4
         ch(1,k,3) = cr3-ci4
         ch(1,k,4) = cr3+ci4
         ch(2,k,4) = ci3-cr4
         ch(2,k,5) = ci2-cr5
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti5 = cc(i,2,k)-cc(i,5,k)
            ti2 = cc(i,2,k)+cc(i,5,k)
            ti4 = cc(i,3,k)-cc(i,4,k)
            ti3 = cc(i,3,k)+cc(i,4,k)
            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
            ch(i,k,1) = cc(i,1,k)+ti2+ti3
            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
            cr5 = ti11*tr5+ti12*tr4
            ci5 = ti11*ti5+ti12*ti4
            cr4 = ti12*tr5-ti11*tr4
            ci4 = ti12*ti5-ti11*ti4
            dr3 = cr3-ci4
            dr4 = cr3+ci4
            di3 = ci3+cr4
            di4 = ci3-cr4
            dr5 = cr2+ci5
            dr2 = cr2-ci5
            di5 = ci2-cr5
            di2 = ci2+cr5
            ch(i-1,k,2) = wa1(i-1)*dr2+wa1(i)*di2
            ch(i,k,2) = wa1(i-1)*di2-wa1(i)*dr2
            ch(i-1,k,3) = wa2(i-1)*dr3+wa2(i)*di3
            ch(i,k,3) = wa2(i-1)*di3-wa2(i)*dr3
            ch(i-1,k,4) = wa3(i-1)*dr4+wa3(i)*di4
            ch(i,k,4) = wa3(i-1)*di4-wa3(i)*dr4
            ch(i-1,k,5) = wa4(i-1)*dr5+wa4(i)*di5
            ch(i,k,5) = wa4(i-1)*di5-wa4(i)*dr5
  103    continue
  104 continue
c
      return
      end
      subroutine dcfftb (n,c,wsave)
      double precision c(*), wsave(*)
c
      if (n .eq. 1) return
c
      iw1 = n+n+1
      iw2 = iw1+n+n
      call dcftb1 (n,c,wsave,wsave(iw1),wsave(iw2))
c
      return
      end
      subroutine dcftb1 (n,c,ch,wa,ifac)
      double precision c(*), ch(*), wa(*)
      double precision ifac(*)
c
      nf = ifac(2)
      na = 0
      l1 = 1
      iw = 1
      do 116 k1=1,nf
         ip = ifac(k1+2)
         l2 = ip*l1
         ido = n/l2
         idot = ido+ido
         idl1 = idot*l1
         if (ip .ne. 4) go to 103
         ix2 = iw+idot
         ix3 = ix2+idot
         if (na .ne. 0) go to 101
         call dpssb4 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3))
         go to 102
  101    call dpssb4 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3))
  102    na = 1-na
         go to 115
c
  103    if (ip .ne. 2) go to 106
         if (na .ne. 0) go to 104
         call dpssb2 (idot,l1,c,ch,wa(iw))
         go to 105
  104    call dpssb2 (idot,l1,ch,c,wa(iw))
  105    na = 1-na
         go to 115
c
  106    if (ip .ne. 3) go to 109
         ix2 = iw+idot
         if (na .ne. 0) go to 107
         call dpssb3 (idot,l1,c,ch,wa(iw),wa(ix2))
         go to 108
  107    call dpssb3 (idot,l1,ch,c,wa(iw),wa(ix2))
  108    na = 1-na
         go to 115
c
  109    if (ip .ne. 5) go to 112
         ix2 = iw+idot
         ix3 = ix2+idot
         ix4 = ix3+idot
         if (na .ne. 0) go to 110
         call dpssb5 (idot,l1,c,ch,wa(iw),wa(ix2),wa(ix3),wa(ix4))
         go to 111
  110    call dpssb5 (idot,l1,ch,c,wa(iw),wa(ix2),wa(ix3),wa(ix4))
  111    na = 1-na
         go to 115
c
  112    if (na .ne. 0) go to 113
         call dpssb (nac,idot,ip,l1,idl1,c,c,c,ch,ch,wa(iw))
         go to 114
  113    call dpssb (nac,idot,ip,l1,idl1,ch,ch,ch,c,c,wa(iw))
  114    if (nac .ne. 0) na = 1-na
c
  115    l1 = l2
         iw = iw+(ip-1)*idot
  116 continue
      if (na .eq. 0) return
c
      n2 = n+n
      do 117 i=1,n2
         c(i) = ch(i)
  117 continue
c
      return
      end
      subroutine dpssb (nac,ido,ip,l1,idl1,cc,c1,c2,ch,ch2,wa)
      double precision cc(ido,ip,l1), c1(ido,l1,ip), c2(idl1,ip),
     1  ch(ido,l1,ip), ch2(idl1,ip), wa(*), wai, war
c
      idot = ido/2
      nt = ip*idl1
      ipp2 = ip+2
      ipph = (ip+1)/2
      idp = ip*ido
c
      if (ido .lt. l1) go to 106
      do 103 j=2,ipph
         jc = ipp2-j
         do 102 k=1,l1
            do 101 i=1,ido
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  101       continue
  102    continue
  103 continue
c
      do 105 k=1,l1
         do 104 i=1,ido
            ch(i,k,1) = cc(i,1,k)
  104    continue
  105 continue
      go to 112
c
  106 do 109 j=2,ipph
         jc = ipp2-j
         do 108 i=1,ido
            do 107 k=1,l1
               ch(i,k,j) = cc(i,j,k)+cc(i,jc,k)
               ch(i,k,jc) = cc(i,j,k)-cc(i,jc,k)
  107       continue
  108    continue
  109 continue
c
      do 111 i=1,ido
         do 110 k=1,l1
            ch(i,k,1) = cc(i,1,k)
  110    continue
  111 continue
c
  112 idl = 2-ido
      inc = 0
      do 116 l=2,ipph
         lc = ipp2-l
         idl = idl+ido
         do 113 ik=1,idl1
            c2(ik,l) = ch2(ik,1)+wa(idl-1)*ch2(ik,2)
            c2(ik,lc) = wa(idl)*ch2(ik,ip)
  113    continue
         idlj = idl
         inc = inc+ido
         do 115 j=3,ipph
            jc = ipp2-j
            idlj = idlj+inc
            if (idlj .gt. idp) idlj = idlj-idp
            war = wa(idlj-1)
            wai = wa(idlj)
            do 114 ik=1,idl1
               c2(ik,l) = c2(ik,l)+war*ch2(ik,j)
               c2(ik,lc) = c2(ik,lc)+wai*ch2(ik,jc)
  114       continue
  115    continue
  116 continue
c
      do 118 j=2,ipph
         do 117 ik=1,idl1
            ch2(ik,1) = ch2(ik,1)+ch2(ik,j)
  117    continue
  118 continue
c
      do 120 j=2,ipph
         jc = ipp2-j
         do 119 ik=2,idl1,2
            ch2(ik-1,j) = c2(ik-1,j)-c2(ik,jc)
            ch2(ik-1,jc) = c2(ik-1,j)+c2(ik,jc)
            ch2(ik,j) = c2(ik,j)+c2(ik-1,jc)
            ch2(ik,jc) = c2(ik,j)-c2(ik-1,jc)
  119    continue
  120 continue
c
      nac = 1
      if (ido .eq. 2) return
      nac = 0
c
      do 121 ik=1,idl1
         c2(ik,1) = ch2(ik,1)
  121 continue
c
      do 123 j=2,ip
         do 122 k=1,l1
            c1(1,k,j) = ch(1,k,j)
            c1(2,k,j) = ch(2,k,j)
  122    continue
  123 continue
c
      if (idot .gt. l1) go to 127
      idij = 0
      do 126 j=2,ip
         idij = idij+2
         do 125 i=4,ido,2
            idij = idij+2
            do 124 k=1,l1
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
  124       continue
  125    continue
  126 continue
      return
c
  127 idj = 2-ido
      do 130 j=2,ip
         idj = idj+ido
         do 129 k=1,l1
            idij = idj
            do 128 i=4,ido,2
               idij = idij+2
               c1(i-1,k,j) = wa(idij-1)*ch(i-1,k,j)-wa(idij)*ch(i,k,j)
               c1(i,k,j) = wa(idij-1)*ch(i,k,j)+wa(idij)*ch(i-1,k,j)
  128       continue
  129    continue
  130 continue
c
      return
      end
      subroutine dpssb2 (ido,l1,cc,ch,wa1)
      double precision cc(ido,2,l1), ch(ido,l1,2), wa1(*), ti2, tr2
c
      if (ido .gt. 2) go to 102
      do 101 k=1,l1
         ch(1,k,1) = cc(1,1,k)+cc(1,2,k)
         ch(1,k,2) = cc(1,1,k)-cc(1,2,k)
         ch(2,k,1) = cc(2,1,k)+cc(2,2,k)
         ch(2,k,2) = cc(2,1,k)-cc(2,2,k)
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ch(i-1,k,1) = cc(i-1,1,k)+cc(i-1,2,k)
            tr2 = cc(i-1,1,k)-cc(i-1,2,k)
            ch(i,k,1) = cc(i,1,k)+cc(i,2,k)
            ti2 = cc(i,1,k)-cc(i,2,k)
            ch(i,k,2) = wa1(i-1)*ti2+wa1(i)*tr2
            ch(i-1,k,2) = wa1(i-1)*tr2-wa1(i)*ti2
  103    continue
  104 continue
c
      return
      end
      subroutine dpssb3 (ido,l1,cc,ch,wa1,wa2)
      double precision cc(ido,3,l1), ch(ido,l1,3), wa1(*), wa2(*),
     1 ci2, ci3, cr2, cr3, di2, di3, dr2, dr3, taui, taur, ti2, tr2
      data taur / -0.5 d0 /
      data taui  /  0.8660254037 8443864676 3723170752 93618d0/
c
c     one half sqrt(3) = .866025.....  .
c
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         tr2 = cc(1,2,k)+cc(1,3,k)
         cr2 = cc(1,1,k)+taur*tr2
         ch(1,k,1) = cc(1,1,k)+tr2
         ti2 = cc(2,2,k)+cc(2,3,k)
         ci2 = cc(2,1,k)+taur*ti2
         ch(2,k,1) = cc(2,1,k)+ti2
         cr3 = taui*(cc(1,2,k)-cc(1,3,k))
         ci3 = taui*(cc(2,2,k)-cc(2,3,k))
         ch(1,k,2) = cr2-ci3
         ch(1,k,3) = cr2+ci3
         ch(2,k,2) = ci2+cr3
         ch(2,k,3) = ci2-cr3
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            tr2 = cc(i-1,2,k)+cc(i-1,3,k)
            cr2 = cc(i-1,1,k)+taur*tr2
            ch(i-1,k,1) = cc(i-1,1,k)+tr2
            ti2 = cc(i,2,k)+cc(i,3,k)
            ci2 = cc(i,1,k)+taur*ti2
            ch(i,k,1) = cc(i,1,k)+ti2
            cr3 = taui*(cc(i-1,2,k)-cc(i-1,3,k))
            ci3 = taui*(cc(i,2,k)-cc(i,3,k))
            dr2 = cr2-ci3
            dr3 = cr2+ci3
            di2 = ci2+cr3
            di3 = ci2-cr3
            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
  103    continue
  104 continue
c
      return
      end
      subroutine dpssb4 (ido,l1,cc,ch,wa1,wa2,wa3)
      double precision cc(ido,4,l1), ch(ido,l1,4), wa1(*), wa2(*),
     1  wa3(*), ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1,
     2  tr2, tr3, tr4
c
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti1 = cc(2,1,k)-cc(2,3,k)
         ti2 = cc(2,1,k)+cc(2,3,k)
         tr4 = cc(2,4,k)-cc(2,2,k)
         ti3 = cc(2,2,k)+cc(2,4,k)
         tr1 = cc(1,1,k)-cc(1,3,k)
         tr2 = cc(1,1,k)+cc(1,3,k)
         ti4 = cc(1,2,k)-cc(1,4,k)
         tr3 = cc(1,2,k)+cc(1,4,k)
         ch(1,k,1) = tr2+tr3
         ch(1,k,3) = tr2-tr3
         ch(2,k,1) = ti2+ti3
         ch(2,k,3) = ti2-ti3
         ch(1,k,2) = tr1+tr4
         ch(1,k,4) = tr1-tr4
         ch(2,k,2) = ti1+ti4
         ch(2,k,4) = ti1-ti4
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti1 = cc(i,1,k)-cc(i,3,k)
            ti2 = cc(i,1,k)+cc(i,3,k)
            ti3 = cc(i,2,k)+cc(i,4,k)
            tr4 = cc(i,4,k)-cc(i,2,k)
            tr1 = cc(i-1,1,k)-cc(i-1,3,k)
            tr2 = cc(i-1,1,k)+cc(i-1,3,k)
            ti4 = cc(i-1,2,k)-cc(i-1,4,k)
            tr3 = cc(i-1,2,k)+cc(i-1,4,k)
            ch(i-1,k,1) = tr2+tr3
            cr3 = tr2-tr3
            ch(i,k,1) = ti2+ti3
            ci3 = ti2-ti3
            cr2 = tr1+tr4
            cr4 = tr1-tr4
            ci2 = ti1+ti4
            ci4 = ti1-ti4
            ch(i-1,k,2) = wa1(i-1)*cr2-wa1(i)*ci2
            ch(i,k,2) = wa1(i-1)*ci2+wa1(i)*cr2
            ch(i-1,k,3) = wa2(i-1)*cr3-wa2(i)*ci3
            ch(i,k,3) = wa2(i-1)*ci3+wa2(i)*cr3
            ch(i-1,k,4) = wa3(i-1)*cr4-wa3(i)*ci4
            ch(i,k,4) = wa3(i-1)*ci4+wa3(i)*cr4
  103    continue
  104 continue
c
      return
      end
      subroutine dpssb5 (ido,l1,cc,ch,wa1,wa2,wa3,wa4)
      double precision cc(ido,5,l1), ch(ido,l1,5), wa1(*), wa2(*),
     1  wa3(*), wa4(*), ci2, ci3, ci4, ci5, cr2, cr3, cr4, cr5,
     2  di2, di3, di4, di5, dr2, dr3, dr4, dr5, ti11, ti12, ti2, ti3,
     3  ti4, ti5, tr11, tr12, tr2, tr3, tr4, tr5
      data tr11  /  0.3090169943 7494742410 2293417182 81906d0/
      data ti11  /  0.9510565162 9515357211 6439333379 38214d0/
      data tr12  / -0.8090169943 7494742410 2293417182 81906d0/
      data ti12  /  0.5877852522 9247312916 8705954639 07277d0/
c
c     sin(pi/10) = .30901699....    .
c     cos(pi/10) = .95105651....    .
c     sin(pi/5 ) = .58778525....    .
c     cos(pi/5 ) = .80901699....    .
c
      if (ido .ne. 2) go to 102
      do 101 k=1,l1
         ti5 = cc(2,2,k)-cc(2,5,k)
         ti2 = cc(2,2,k)+cc(2,5,k)
         ti4 = cc(2,3,k)-cc(2,4,k)
         ti3 = cc(2,3,k)+cc(2,4,k)
         tr5 = cc(1,2,k)-cc(1,5,k)
         tr2 = cc(1,2,k)+cc(1,5,k)
         tr4 = cc(1,3,k)-cc(1,4,k)
         tr3 = cc(1,3,k)+cc(1,4,k)
         ch(1,k,1) = cc(1,1,k)+tr2+tr3
         ch(2,k,1) = cc(2,1,k)+ti2+ti3
         cr2 = cc(1,1,k)+tr11*tr2+tr12*tr3
         ci2 = cc(2,1,k)+tr11*ti2+tr12*ti3
         cr3 = cc(1,1,k)+tr12*tr2+tr11*tr3
         ci3 = cc(2,1,k)+tr12*ti2+tr11*ti3
         cr5 = ti11*tr5+ti12*tr4
         ci5 = ti11*ti5+ti12*ti4
         cr4 = ti12*tr5-ti11*tr4
         ci4 = ti12*ti5-ti11*ti4
         ch(1,k,2) = cr2-ci5
         ch(1,k,5) = cr2+ci5
         ch(2,k,2) = ci2+cr5
         ch(2,k,3) = ci3+cr4
         ch(1,k,3) = cr3-ci4
         ch(1,k,4) = cr3+ci4
         ch(2,k,4) = ci3-cr4
         ch(2,k,5) = ci2-cr5
  101 continue
      return
c
  102 do 104 k=1,l1
         do 103 i=2,ido,2
            ti5 = cc(i,2,k)-cc(i,5,k)
            ti2 = cc(i,2,k)+cc(i,5,k)
            ti4 = cc(i,3,k)-cc(i,4,k)
            ti3 = cc(i,3,k)+cc(i,4,k)
            tr5 = cc(i-1,2,k)-cc(i-1,5,k)
            tr2 = cc(i-1,2,k)+cc(i-1,5,k)
            tr4 = cc(i-1,3,k)-cc(i-1,4,k)
            tr3 = cc(i-1,3,k)+cc(i-1,4,k)
            ch(i-1,k,1) = cc(i-1,1,k)+tr2+tr3
            ch(i,k,1) = cc(i,1,k)+ti2+ti3
            cr2 = cc(i-1,1,k)+tr11*tr2+tr12*tr3
            ci2 = cc(i,1,k)+tr11*ti2+tr12*ti3
            cr3 = cc(i-1,1,k)+tr12*tr2+tr11*tr3
            ci3 = cc(i,1,k)+tr12*ti2+tr11*ti3
            cr5 = ti11*tr5+ti12*tr4
            ci5 = ti11*ti5+ti12*ti4
            cr4 = ti12*tr5-ti11*tr4
            ci4 = ti12*ti5-ti11*ti4
            dr3 = cr3-ci4
            dr4 = cr3+ci4
            di3 = ci3+cr4
            di4 = ci3-cr4
            dr5 = cr2+ci5
            dr2 = cr2-ci5
            di5 = ci2-cr5
            di2 = ci2+cr5
            ch(i-1,k,2) = wa1(i-1)*dr2-wa1(i)*di2
            ch(i,k,2) = wa1(i-1)*di2+wa1(i)*dr2
            ch(i-1,k,3) = wa2(i-1)*dr3-wa2(i)*di3
            ch(i,k,3) = wa2(i-1)*di3+wa2(i)*dr3
            ch(i-1,k,4) = wa3(i-1)*dr4-wa3(i)*di4
            ch(i,k,4) = wa3(i-1)*di4+wa3(i)*dr4
            ch(i-1,k,5) = wa4(i-1)*dr5-wa4(i)*di5
            ch(i,k,5) = wa4(i-1)*di5+wa4(i)*dr5
  103    continue
  104 continue
c
      return
      end

languages: Makefile C Fortran

repo_name: MilenkoM/b