TABLE OF CONTENTS


ABINIT/cspint [ Functions ]

[ Top ] [ Functions ]

NAME

  cspint

FUNCTION

  CSPINT estimates the integral of a tabulated function.

INPUTS

OUTPUT

NOTES

    The routine is given the value of a function F(X) at a set of 
    nodes XTAB, and estimates

      Integral ( A <= X <= B ) F(X) DX

    by computing the cubic natural spline S(X) that interpolates
    F(X) at the nodes, and then computing

      Integral ( A <= X <= B ) S(X) DX

    exactly.

    Other output from the program includes the definite integral
    from X(1) to X(I) of S(X), and the coefficients necessary for
    the user to evaluate the spline S(X) at any point.

  Modified:

    30 October 2000

  Reference:

    Philip Davis and Philip Rabinowitz,
    Methods of Numerical Integration,
    Blaisdell Publishing, 1967.

  Parameters:

    Input, real (dp) FTAB(NTAB), contains the tabulated values of
    the function, FTAB(I) = F(XTAB(I)).

    Input, real (dp) XTAB(NTAB), contains the points at which the
    function was evaluated.  The XTAB's must be distinct and
    in ascending order.

    Input, integer NTAB, the number of entries in FTAB and
    XTAB.  NTAB must be at least 3.

    Input, real (dp) A, lower limit of integration.

    Input, real (dp) B, upper limit of integration.

    Output, real (dp) Y(3,NTAB), will contain the coefficients
    of the interpolating natural spline over each subinterval.

    For XTAB(I) <= X <= XTAB(I+1),

      S(X) = FTAB(I) + Y(1,I)*(X-XTAB(I))
                   + Y(2,I)*(X-XTAB(I))**2
                   + Y(3,I)*(X-XTAB(I))**3

    Output, real (dp) E(NTAB), E(I) = the definite integral from
    XTAB(1) to XTAB(I) of S(X).

    Workspace, real (dp) WORK(NTAB).

    Output, real (dp) RESULT, the estimated value of the integral.

PARENTS

      m_xc_vdw,mrgscr

CHILDREN

SOURCE

 81 #if defined HAVE_CONFIG_H
 82 #include "config.h"
 83 #endif
 84 
 85 #include "abi_common.h"
 86 
 87 subroutine cspint ( ftab, xtab, ntab, a, b, y, e, work, result )
 88 
 89  use defs_basis
 90  use m_profiling_abi
 91  use m_errors
 92 
 93 !This section has been created automatically by the script Abilint (TD).
 94 !Do not modify the following lines by hand.
 95 #undef ABI_FUNC
 96 #define ABI_FUNC 'cspint'
 97 !End of the abilint section
 98 
 99   implicit none
100 
101   integer, intent(in) :: ntab
102 
103   real(dp), intent(in) :: a
104   real(dp), intent(in) :: b
105   real(dp), intent(inout) :: e(ntab)
106   real(dp), intent(in) :: ftab(ntab)
107   integer :: i
108   integer :: j
109   real(dp) :: r
110   real(dp), intent(out) :: result
111   real(dp) :: s
112   real(dp) :: term
113   real(dp) :: u
114   real(dp), intent(inout) :: work(ntab)
115   real(dp), intent(in) :: xtab(ntab)
116   real(dp), intent(inout) :: y(3,ntab)
117 
118   if ( ntab < 3 ) then
119     write(std_out,'(a)' ) ' '
120     write(std_out,'(a)' ) 'CSPINT - Fatal error!'
121     write(std_out,'(a,i6)' ) '  NTAB must be at least 3, but input NTAB = ',ntab
122     MSG_ERROR("Aborting now")
123   end if
124  
125   do i = 1, ntab-1
126  
127     if ( xtab(i+1) <= xtab(i) ) then
128       write(std_out,'(a)' ) ' '
129       write(std_out,'(a)' ) 'CSPINT - Fatal error!'
130       write(std_out,'(a)' ) '  Nodes not in strict increasing order.'
131       write(std_out,'(a,i6)' ) '  XTAB(I) <= XTAB(I-1) for I=',i
132       write(std_out,'(a,g14.6)' ) '  XTAB(I) = ',xtab(i)
133       write(std_out,'(a,g14.6)' ) '  XTAB(I-1) = ',xtab(i-1)
134       MSG_ERROR("Aborting now")
135     end if
136  
137   end do
138  
139   s = zero
140   do i = 1, ntab-1
141     r = ( ftab(i+1) - ftab(i) ) / ( xtab(i+1) - xtab(i) )
142     y(2,i) = r - s
143     s = r
144   end do
145  
146   result = zero
147   s = zero
148   r = zero
149   y(2,1) = zero
150   y(2,ntab) = zero
151  
152   do i = 2, ntab-1
153     y(2,i) = y(2,i) + r * y(2,i-1)
154     work(i) = two * ( xtab(i-1) - xtab(i+1) ) - r * s
155     s = xtab(i+1) - xtab(i)
156     r = s / work(i)
157   end do
158  
159   do j = 2, ntab-1
160     i = ntab+1-j
161     y(2,i) = ( ( xtab(i+1) - xtab(i) ) * y(2,i+1) - y(2,i) ) / work(i)
162   end do
163  
164   do i = 1, ntab-1
165     s = xtab(i+1) - xtab(i)
166     r = y(2,i+1) - y(2,i)
167     y(3,i) = r / s
168     y(2,i) = three * y(2,i)
169     y(1,i) = ( ftab(i+1) - ftab(i) ) / s - ( y(2,i) + r ) * s
170   end do
171  
172   e(1) = 0.0D+00
173   do i = 1, ntab-1
174     s = xtab(i+1)-xtab(i)
175     term = ((( y(3,i) * quarter * s + y(2,i) * third ) * s &
176       + y(1,i) * half ) * s + ftab(i) ) * s
177     e(i+1) = e(i) + term
178   end do
179 !
180 !  Determine where the endpoints A and B lie in the mesh of XTAB's.
181 !
182   r = a
183   u = one
184  
185   do j = 1, 2
186 !
187 !  The endpoint is less than or equal to XTAB(1).
188 !
189     if ( r <= xtab(1) ) then
190       result = result-u*((r-xtab(1))*y(1,1)*half +ftab(1))*(r-xtab(1))
191 !
192 !  The endpoint is greater than or equal to XTAB(NTAB).
193 !
194     else if ( xtab(ntab) <= r ) then
195 
196       result = result -u * ( e(ntab) + ( r - xtab(ntab) ) &
197         * ( ftab(ntab) + half * ( ftab(ntab-1) &
198         + ( xtab(ntab) - xtab(ntab-1) ) * y(1,ntab-1) ) &
199         * ( r - xtab(ntab) )))
200 !
201 !  The endpoint is strictly between XTAB(1) and XTAB(NTAB).
202 !
203     else
204 
205       do i = 1, ntab-1
206  
207         if ( r <= xtab(i+1) ) then
208           r = r-xtab(i)
209           result = result-u*(e(i)+(((y(3,i)*quarter*r+y(2,i)*third)*r &
210             +y(1,i)*half )*r+ftab(i))*r)
211           go to 120
212         end if
213  
214       end do
215  
216     end if
217  
218   120   continue
219  
220     u = -one
221     r = b
222  
223   end do
224  
225   return
226 
227 end subroutine cspint