CSPLINE Subroutine

public subroutine CSPLINE(TAU, C, N, IBCBEG, IBCEND, NDIM)

Arguments

Type IntentOptional Attributes Name
real(kind=8), intent(in) :: TAU(N)
complex(kind=8), intent(inout) :: C(4,NDIM)
integer, intent(in) :: N
integer, intent(in) :: IBCBEG
integer, intent(in) :: IBCEND
integer, intent(in) :: NDIM

Called by

proc~~cspline~~CalledByGraph proc~cspline CSPLINE proc~pchip PCHIP proc~pchip->proc~cspline proc~cpchip cPCHIP proc~cpchip->proc~pchip proc~evaluatessp EvaluateSSP proc~evaluatessp->proc~cpchip proc~bellhopcore~2 BellhopCore proc~bellhopcore~2->proc~evaluatessp proc~influencecervenycart InfluenceCervenyCart proc~bellhopcore~2->proc~influencecervenycart proc~traceray2d~2 TraceRay2D proc~bellhopcore~2->proc~traceray2d~2 proc~influencecervenycart->proc~evaluatessp proc~readenvironment ReadEnvironment proc~readenvironment->proc~evaluatessp proc~reflect2d~2 Reflect2D proc~reflect2d~2->proc~evaluatessp proc~step2d Step2D proc~step2d->proc~evaluatessp proc~traceray2d~2->proc~evaluatessp proc~traceray2d~2->proc~reflect2d~2 proc~traceray2d~2->proc~step2d proc~bellhopcore BellhopCore proc~bellhopcore->proc~influencecervenycart program~bellhop BELLHOP program~bellhop->proc~bellhopcore~2 program~bellhop->proc~readenvironment program~bellhop3d BELLHOP3D program~bellhop3d->proc~readenvironment program~bellhop3d->proc~bellhopcore

Source Code

SUBROUTINE CSPLINE (TAU, C, N, IBCBEG, IBCEND, NDIM)

  !  TAKEN FROM "A PRACTICAL GUIDE TO SPLINES", BY CARL DE BOOR. 1978.
  !  SPRINGER-VERLAG.  THE INPUT PARAMETER "NDIM" HAS BEEN ADDED TO
  !  ALLOW FOR MULTIPLE CALLS WITH DIFFERENT VALUES OF N. - DENNIS DUNDORE

  !  SUBSTANTIAL MODIFICATIONS MADE BY STEVE WALES, APRIL 1983,
  !  PRINCIPALLY TO HANDLE COMPLEX NUMBERS (C) & UPDATE THE FORTRAN.

  ! *****************************  I N P U T  ****************************

  !  N = NUMBER OF DATA POINTS.  ASSUMED TO BE .GE. 2.

  !  (TAU(I), C(1,I),I=1,...,N) = ABSCISSAE AND ORDINATES OF THE DATA
  !      POINTS.  TAU IS ASSUMED TO BE STRICTLY INCREASING.

  !  IBCBEG, IBCEND = BOUNDARY CONDITION INDICATORS, AND
  !  C(2,1), C(2,N) = BOUNDARY CONDITION INFORMATION.  SPECIFICALLY,
  !      IBCBEG = 0 IMPLIES NO BOUNDARY CONDITION AT TAU(1) IS GIVEN.
  !            IN THIS CASE, THE "NOT-A-KNOT" CONDITION IS USED, IE THE
  !            JUMP IN THE 3-RD DERIVATIVE ACROSS TAU(2) IS FORCED TO 0.,
  !            THUS THE 1-ST AND 2-ND POLYNOMIAL PIECES ARE MADE TO
  !            COINCIDE.
  !      IBCBEG = 1 IMPLIES THAT THE SLOPE AT TAU(1) IS SET EQUAL TO C(2,1)
  !            INPUT BY USER.
  !      IBCBEG = 2 IMPLIES THAT THE 2-ND DERIVATIVE AT TAU(1) IS SET EQUAL
  !            TO C(2,1), SUPPLIED BY INPUT.
  !      IBCEND = 0, 1, OR 2 HAS ANALOGOUS MEANING CONCERNING THE BOUNDARY
  !            CONDITION AT TAU(N), WITH INFORMATION SUPPLIED BY C(2,N).

  !  NDIM = ROW DIMENSION OF C MATRIX:  C(4,NDIM)

  ! **************************  O U T P U T  ****************************

  !  C(J,I), J=1,...,4;  I=1,...,L=N-1  =  THE POLY COEFFS OF THE CUBIC
  !      SPLINE WITH INTERIOR KNOTS TAU(2),...,TAU(N-1).  PRECISELY, IN THE
  !      INTERVAL (TAU(I), TAU(I+1)), THE SPLINE F IS GIVEN BY

  !       F(X) = C(1,I) + H*(C(2,I) + H*(C(3,I)/2. + H*C(4,I)/6.))

  !      WHERE H = X - TAU(I).

  !     THE COEFFICIENTS CALCULATED ARE, 1) THE VALUE, 2) THE SLOPE, AND
  !     3) THE CURVATURE AT EACH OF THE KNOTS 1 TO N-1, AND 4) THE RATE OF
  !     CHANGE OF THE CURVATURE OVER THE FOLLOWING INTERVAL.  IN ADDITION,
  !     WE HAVE THE VALUE AND THE SLOPE AT THE LAST POINT. THE LAST TWO
  !     POSTIONS AT THE LAST POINT ARE THEN SET TO THE CURVATURE AT THAT
  !     POINT (IN C(3,N)) AND THE MEAN VALUE OVER THE ENTIRE INTERVAL,
  !     CALCULATED AS THE INTEGRAL OVER THE INTERVAL DIVIDED BY THE LENGTH
  !     OF THE INTERVAL (IN C(4,N)).

  ! **********************************************************************

  INTEGER, INTENT(IN) :: N, IBCBEG, IBCEND, NDIM
  REAL    (KIND=8), INTENT(IN)  :: TAU(N)
  COMPLEX (KIND=8), INTENT(INOUT) :: C(4,NDIM)

  ! Local variables
  INTEGER :: L, M, I, J
  COMPLEX (KIND=8) :: G, DTAU, DIVDF1, DIVDF3

  L = N - 1

  DO M = 2,N
     C(3,M) = TAU(M) - TAU(M-1)
     C(4,M) = (C(1,M) - C(1,M-1)) / C(3,M)
  END DO

  !   * BEGINNING BOUNDARY CONDITION SECTION *

  IF (IBCBEG==0)  THEN                           ! IBCBEG = 0
     IF (N>2)  THEN                            !     N > 2
        C(4,1) = C(3,3)
        C(3,1) = C(3,2) + C(3,3)
        C(2,1) = ((C(3,2) + 2.0*C(3,1))*C(4,2)*C(3,3) + &
             C(3,2)**2 * C(4,3)) / C(3,1)
     ELSE                                       !     N = 2
        C(4,1) = (1.0,0.0)
        C(3,1) = (1.0,0.0)
        C(2,1) = 2.0 * C(4,2)
     END IF

  ELSE IF (IBCBEG==1)  THEN                      ! IBCBEG = 1
     C(4,1) = (1.0,0.0)
     C(3,1) = (0.0,0.0)

  ELSE IF (IBCBEG==2)  THEN                      ! IBCBEG = 2
     C(4,1) = (2.0,0.0)
     C(3,1) = (1.0,0.0)
     C(2,1) = 3.0*C(4,2) - C(2,1)*C(3,2)/2.0
  END IF

  !   * RUNNING CALCULATIONS TO N-1 - LOOP IS NOT EXECUTED IF N = 2 *

  DO M = 2,L
     G = -C(3,M+1) / C(4,M-1)
     C(2,M) = G*C(2,M-1) + 3.0*(C(3,M)*C(4,M+1) + C(3,M+1)*C(4,M))
     C(4,M) = G*C(3,M-1) + 2.0*(C(3,M) + C(3,M+1))
  END DO

  !   * ENDING BOUNDARY CONDITION SECTION *

  IF (IBCEND /= 1)  THEN
     IF (IBCEND==0)  THEN
        IF (N==2 .AND. IBCBEG==0)  THEN
           C(2,N) = C(4,N)
        ELSE IF ((N==3 .AND. IBCBEG==0) .OR. N==2)  THEN
           C(2,N) = 2.0 * C(4,N)
           C(4,N) = (1.,0.)
           G = -1.0 / C(4,N-1)
        ELSE
           G = C(3,N-1) + C(3,N)
           C(2,N) = ((C(3,N) + 2.0*G) * C(4,N)*C(3,N-1) + &
                C(3,N)**2 * (C(1,N-1)-C(1,N-2)) / C(3,N-1)) / G
           G = -G / C(4,N-1)
           C(4,N) = C(3,N-1)
        END IF

     ELSE IF (IBCEND==2)  THEN
        C(2,N) = 3.0 * C(4,N) + C(2,N)*C(3,N)/2.0
        C(4,N) = (2.0,0.0)
        G = -1.0 / C(4,N-1)
     END IF

     IF ( IBCBEG>0 .OR. N>2)  THEN
        C(4,N) = G*C(3,N-1) + C(4,N)
        C(2,N) = (G*C(2,N-1) + C(2,N)) / C(4,N)
     END IF
  END IF

  !   * RUN THE ENDING BOUNDARY EFFECT BACK THROUGH THE EQUATIONS *

  DO J = L,1,-1
     C(2,J) = (C(2,J) - C(3,J)*C(2,J+1)) / C(4,J)
  END DO

  !   * FINAL CALCULATIONS *

  DO I = 2,N
     DTAU = C(3,I)
     DIVDF1 = (C(1,I)-C(1,I-1)) / DTAU
     DIVDF3 = C(2,I-1) + C(2,I) - 2.0*DIVDF1
     C(3,I-1) = 2.0 * (DIVDF1-C(2,I-1)-DIVDF3) / DTAU
     C(4,I-1) = (DIVDF3/DTAU) * (6.0/DTAU)
  END DO

  !     * ADD THE CURVATURE AT THE LAST POINT IN THE THIRD POSITION OF THE
  !       LAST NODE *

  C(3,N) = C(3,L) + (TAU(N)-TAU(L)) * C(4,L)


  !     * ADD THE MEAN VALUE OF THE ENTIRE INTERVAL IN THE FOURTH POSITION OF
  !       THE LAST NODE.  MEAN VALUE IS CALCULATED AS THE INTEGRAL OVER THE
  !       INTERVAL DIVIDED BY THE LENGTH OF THE INTERVAL. *

  C(4,N) = (0.0,0.0)
  DO I = 1,L                            ! INTEGRATE OVER THE INTERVAL
     DTAU = TAU(I+1) - TAU(I)
     C(4,N) = C(4,N) + DTAU*(C(1,I) + DTAU*(C(2,I)/2.0 + &
          DTAU*(C(3,I)/6.0 + DTAU*C(4,I)/24.0)))
  END DO
  C(4,N) = C(4,N) / (TAU(N)-TAU(1))        ! DIVIDE BY LENGTH OF INTERVAL

  RETURN
END SUBROUTINE CSPLINE