!
!##################################################################
!##################################################################
!######                                                      ######
!######                 SUBROUTINE RECURFILT_1D              ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                                                      ######
!##################################################################
!##################################################################
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  recursive filter in one direction. 
!  developed accoring to the paper by Jim Purser and also A. Lorenc 
!
!-----------------------------------------------------------------------
!
!  Jidong Gao, CAPS, July, 2000
!
!-----------------------------------------------------------------------
!

SUBROUTINE  recurfilt_1d(vara, nx, alpha,ipass) 5
!
!
  INTEGER :: nx
  REAL :: vara(nx)
  REAL :: alpha
  INTEGER :: ipass
  REAL,   DIMENSION (:), allocatable :: varb
  REAL,   DIMENSION (:), allocatable :: varc
!
  allocate (varb(nx))
  allocate (varc(nx))
!
  DO n = 1, nx
    varb(n) = 0.
    varc(n) = 0.
  END DO
!
!  varb(1) = (1-alpha) * vara(1)
  if(ipass==1) varb(1) = (1-alpha) * vara(1)
  if(ipass==2) varb(1) = (1-alpha)/(1-alpha*alpha) * vara(1)
  if(ipass==3) then
     temp = (1-alpha)/((1-alpha*alpha)*(1-alpha*alpha))
     temp2 =alpha*alpha*alpha
     varb(1) = temp * (vara(1)-temp2*vara(2))
  ENDIF
  if(ipass>=4) then
     temp2 =alpha*alpha*alpha
     temp = (1-alpha)/(1-3*alpha*alpha+3*temp2*alpha-temp2*temp2)
     varb(1) = temp * (vara(1)-3*temp2*vara(2)+                         &
           temp2*alpha*alpha*vara(2)+temp2*alpha*vara(3))
  ENDIF

!
!
  DO i = 2, nx, 1
    varb(i) = alpha*varb(i-1) + (1.-alpha)*vara(i)
  END DO
!
!
!  varc(nx) =  (1./(1.+alpha)) * varb(nx)
  if(ipass==0) varc(nx) = (1-alpha) * varb(nx)
  if(ipass==1) varc(nx) = (1-alpha)/(1-alpha*alpha) * varb(nx)
  if(ipass==2) then
     temp = (1-alpha)/((1-alpha*alpha)*(1-alpha*alpha))
     temp2 =alpha*alpha*alpha
     varc(nx) = temp * (varb(nx)-temp2*varb(nx-1))
  ENDIF
  if(ipass>=3) then
     temp2 =alpha*alpha*alpha
     temp = (1-alpha)/(1-3*alpha*alpha+3*temp2*alpha-temp2*temp2)
     varc(nx) = temp * (varb(nx)-3*temp2*varb(nx-1)+                    &
           temp2*alpha*alpha*varb(nx-1)+temp2*alpha*varb(nx-2))
  ENDIF
!
  DO i = nx-1, 1, -1
    varc(i) = alpha*varc(i+1) + (1.-alpha)*varb(i)
  END DO
!
  DO i = 1, nx
    vara (i) = varc (i)
  END DO
!
  deallocate (varb)
  deallocate (varc)

  RETURN
END SUBROUTINE  recurfilt_1d
!
!=============================================================
!

SUBROUTINE arecurfilt_1d(vara,nx,alpha,ipass) 5
!
!
  INTEGER :: nx
  DIMENSION vara(nx)
  INTEGER :: ipass
  REAL, DIMENSION (:), allocatable :: varb
  REAL, DIMENSION (:), allocatable :: varc
!
!
  allocate (varb (nx))
  allocate (varc (nx))
!
  DO i = 1, nx
    varb(i) = 0.
    varc(i) = 0.
  END DO
!
!
  DO i = nx, 1, -1
    varc(i) = varc(i) + vara(i)
    vara(i) = 0.
  END DO
!
  DO i = 1, nx-1, 1
    varb(i  ) = varb(i  ) + (1. - alpha)*varc(i)
    varc(i+1) = varc(i+1) +       alpha *varc(i)
    varc(i)   = 0.
  END DO
!
  IF(ipass==1) THEN
    varb(nx) = varb(nx)+(1-alpha)/(1-alpha*alpha) * varc(nx)
  ENDIF
  IF(ipass==2) THEN
    temp = (1-alpha)/((1-alpha*alpha)*(1-alpha*alpha))
    temp2 =alpha*alpha*alpha
    varb(nx) = varb(nx)+temp * varc(nx)
    varb(nx-1) = varb(nx-1)-temp * temp2*varc(nx)
  ENDIF
  IF(ipass>=3) THEN
    temp2 =alpha*alpha*alpha
    temp = (1-alpha)/(1-3*alpha*alpha+3*temp2*alpha-temp2*temp2)
    varb(nx) = varb(nx)+temp * varc(nx)
    varb(nx-1) = varb(nx-1)+temp*(temp2*alpha*alpha-3*temp2)*varc(nx)
    varb(nx-2) = varb(nx-2)+temp*temp2*alpha*varc(nx)
  ENDIF
!
  DO i = nx, 2, -1
    vara(i)   = vara(i  ) + (1. - alpha)*varb(i)
    varb(i-1) = varb(i-1) +       alpha *varb(i)
    varb(i) = 0.
  END DO
!
!
  IF(ipass==1) THEN
    vara(1) = vara(1)+(1-alpha) * varb(1)
  ENDIF
  IF(ipass==2) THEN
    vara(1) = vara(1)+(1-alpha)/(1-alpha*alpha) * varb(1)
  ENDIF
  IF(ipass==3) THEN
    temp = (1-alpha)/((1-alpha*alpha)*(1-alpha*alpha))
    temp2 =alpha*alpha*alpha
    vara(1) = vara(1)+temp * varb(1)
    vara(2) = vara(2)-temp * temp2*varb(1)
  ENDIF
  IF(ipass>=4) THEN
    temp2 =alpha*alpha*alpha
    temp = (1-alpha)/(1-3*alpha*alpha+3*temp2*alpha-temp2*temp2)
    vara(1) = vara(1)+temp * varb(1)
    vara(2) = vara(2)+temp * (temp2*alpha*alpha-3*temp2)*varb(1)
    vara(3) = vara(3)+temp * temp2*alpha*varb(1)
  ENDIF
!
  deallocate (varb)
  deallocate (varc)
!
  RETURN
END SUBROUTINE arecurfilt_1d