!******************** START FILE FILEPS.FOR ; GROUP FILTR6 ******************
!
!   FILEPS   IMPLIMENT ERROR BAR FEATURE OF ALGORITHM
!
!   THE SMOOTHING RADIUS ARRAY DELTA IS LOCALLY
!   ADJUSTED WHEREVER THE SMOOTHED DATA FUNCTION IS
!   OUTSIDE THE ERROR BARS OF THE ORIGINAL DATA, UNTIL
!   ALL ERROR BAR VIOLATIONS ARE REMOVED
!
!   THE DATA INITIALIZED VARIABLE RITER IS THE FACTOR BY
!   WHICH THE LOCAL DELTA IS TO BE REDUCED WHERE VIOLATIONS
!   ARE DETECTED.  RITER SHOULD BE SET BETWEEN 0. AND 1.
!   VALUES CLOSER TO ONE MAY PRODUCE BETTER SMOOTHING EFECT,
!   VALUES CLOSER TO ZERO WILL SPEED THE ALGORITHM.
!
!
SUBROUTINE r8fileps(X,Y,YSM,N,DELTA,EPS,NE,EPS2,NE2,XEND1,XEND2)
  use iso_c_binding, only: fp => c_double
  use physconst_mod, only: ZERO, HALF, ONE
  implicit none
  ! Arguments
  integer, intent(in) :: N, NE, NE2
  real(fp), dimension(n), intent(in)  :: x, y
  real(fp), dimension(ne), intent(in) :: eps
  real(fp), dimension(1), intent(in)  :: eps2
  real(fp), dimension(n), intent(out) :: ysm, delta
  real(fp), intent(in) :: xend1,xend2
  ! Local variables
  integer, dimension(6) :: ind0,ind
  integer :: js0,ij,jc1,js,jc2,i,jd1,j,jd2,j1,j2,jlp
  real(fp) :: riter,xisol,d1,d2,zs, &
       zds,zdsb,zp,zz,riterl,riterm,zdx,r8filfn6
!
!  THE "IND" ARRAYS WILL CONTAIN INFORMATION ON
!   ANY ERROR BAR VIOLATIONS.
!   THEY POINT TO LOCATIONS IN X,Y, AND YSM.
!    IND(3)=STARTING POINT OF AN ERROR BAR VIOLATION
!    IND(4)=END PT OF SAME VIOLATION IN CONTIGUOUS REGION
!           OF DIVERGENCE (Y-YSM) OF SAME SIGN
!    IND(2)=START POINT OF REGION OF SAME SIGN DIVERGENCE
!    IND(5)=END POINT OF REGION
!    IND(1)=LOCATION OF REGION DELTA(IND(3)) DISTANT FROM X(IND(3))
!           DEFINING END OF REGION WHERE DATA WILL BE RESMOOTHED
!    IND(6)=SAME AS IND(1), RIGHT ENDPT.
!  IND IS GENERALLY IN INCREASING ORDER
!
!
  riter = 0.9_fp
!  RITER= CONVERGENCE FACTOR IN REDIFINING DELTA ARRAY
!
  xisol = ONE
!  XISOL= ISOLATION PARAMETER IN DETERMINING SEPERATION
!         OF NEIGHBOURING REGIONS OF EPSILON VIOLATIONS
!
  JS0=1
!
  DO IJ=1,6
    IND(IJ)=0
    IND0(IJ)=0
  END DO
 10   CONTINUE
!  SEEK ERROR
9901 FORMAT(' FILERS--A')
  CALL r8filers(X,Y,YSM,N,DELTA,EPS,NE,EPS2,NE2,IND0,JS0)
  !
  !  IND0(0)=0==> NO MORE ERRORS
  !
  IF(IND0(1).EQ.0) RETURN
  !
  JC1=IND0(3)
  !  CHECK RELATIVE LOCATION OF LEFT ENDPOINT OF DATA
  IF(JS0.GT.1) GO TO 20
  D1=max(DELTA(IND0(1)),DELTA(1))
  IF((X(IND0(1))-X(1)).LT.(XISOL*(D1))) JC1=1
!
20 CONTINUE
  !  SEEK NEXT ERROR
25 CONTINUE
  JS=IND0(5)+1
9902 FORMAT(' FILERS--B')
  CALL r8filers(X,Y,YSM,N,DELTA,EPS,NE,EPS2,NE2,IND,JS)
  IF(IND(1).NE.0) GO TO 30
  JC2=IND0(4)
  !  CHECK RIGHT ENDPT OF DATA
  D1=max(DELTA(IND0(6)),DELTA(N))
  IF((X(N)-X(IND0(6))).LT.(XISOL*(D1))) JC2=N
  GO TO 90
  !  YES NEXT ERROR:  JOINT TREATMENT WITH LAST ERROR ?
30 CONTINUE
  JC2=IND0(4)
  D2=max(DELTA(IND0(6)),DELTA(IND(1)) )
  IF((X(IND(1))-X(IND0(6))).GE.(XISOL*(D2))) GO TO 90
  !  YES:  JOINT TREATMENT
  DO I=4,6
    IND0(I)=IND(I)
  END DO
  !  CHECK FOR ANOTHER ERROR
  GO TO 25
  !
  !  ERROR TREATMENT
  !
90 CONTINUE
  JD1=JC1-1
  IF(JC1.EQ.1) GO TO 95
  JD1=IND0(1)
  IF(JD1.GE.(JC1-1) ) GO TO 95
  ZS=X(JC1)-X(JC1-1)
  ZDS=DELTA(JC1)-ZS
  ZDSB=DELTA(JC1)*RITER-ZS
  IF(ZDSB.LE.ZERO) GO TO 95
  ZP=ZDSB/(RITER*ZDS)
  DO J=JD1+1,JC1-1
    ZS=X(JC1)-X(J)
    ZDS=DELTA(J)-ZS
    ZZ=ZP*ZDS/DELTA(J)
    RITERL=ZS*(ONE+ZZ)/DELTA(J)
    RITERM=min(ONE,max(RITERL,RITER))
    DELTA(J)=DELTA(J)*RITERM
  end do
95 CONTINUE
  DO J=JC1,JC2
    DELTA(J)=DELTA(J)*RITER
  END DO
!
  JD2=JC2+1
  IF(JC2.EQ.N) GO TO 100
  JD2=IND0(6)
  IF(JD2.LE.(JC2+1)) GO TO 100
  ZS=X(JC2+1)-X(JC2)
  ZDS=DELTA(JC2)-ZS
  ZDSB=RITER*DELTA(JC2)-ZS
  IF(ZDSB.LE.ZERO) GO TO 100
  ZP=ZDSB/(RITER*ZDS)
  DO J=JC2+1,JD2-1
    ZS=X(J)-X(JC2)
    ZDS=DELTA(J)-ZS
    ZZ=ZP*ZDS/DELTA(J)
    RITERL=ZS*(ONE+ZZ)/DELTA(J)
    RITERM=min(ONE,max(RITER,RITERL))
    DELTA(J)=RITERM*DELTA(J)
  END DO
  !
100 CONTINUE
  !  REEVALUATE SMOOTHED DATA IN REGION OF ERROR BAR VIOLATION(S)
  J1=min(JC1,(JD1+1))
  J2=max(JC2,(JD2-1))
  DO J=J1,J2
    !  DO NOT ALLOW DELTA(J) TO GET TOO SMALL -- RESET TO ZERO FOR SPEED
    JLP=J
    IF(JLP.EQ.1) ZDX=X(2)-X(1)
    IF(JLP.EQ.N) ZDX=X(N)-X(N-1)
    IF((JLP.GT.1).AND.(JLP.LT.N)) ZDX=HALF*(X(JLP+1)-X(JLP-1))
    IF(DELTA(J).LT.0.01E0_fp*ZDX) DELTA(J)=ZERO
    YSM(J)=r8filfn6(X,Y,N,JLP,DELTA,XEND1,XEND2,1)
  END DO
  GO TO 10
END SUBROUTINE r8fileps
