123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- !
- !ProTeX: 1.14-AJS
- !
- !BOI
- !
- ! !TITLE: Num - numerical interpolation, quadrature, etc
- ! !AUTHORS: Arjo Segers
- ! !AFFILIATION: KNMI
- ! !DATE: \today
- !
- ! !INTRODUCTION: Tools
- !
- ! \begin{itemize}
- !
- ! \item Search interval that contains a value:
- !
- ! \bv
- ! subroutine Interval( x, a, ileft, iflag )
- ! real, intent(in) :: x(:)
- ! real, intent(in) :: a
- ! integer, intent(inout) :: ileft
- ! integer, intent(out) :: iflag
- ! end subroutine Interval
- !
- ! Computes:
- ! ileft = max( i, 1 <= i <= n, and x(i) < a )
- !
- ! Input:
- ! x: a real sequence of length n, assumed nondecreasing.
- ! a: the point whose location with tespect to the sequence
- ! x is to be determined.
- ! ileft: a 'first guess' estimate of the index to be found.
- ! this variable should be set to 1 for the first call to
- ! INTERVAL.
- ! Interpretate 'ileft' as the interval number {1,..,n-1}
- !
- ! Output:
- ! ileft iflag meaning
- ! ------ -------- -------------------------------------
- ! 1 -1 a < x(1)
- ! i 0 x(i) <= a < x(i+1)
- ! n-1 0 a = x( n )
- ! n 1 x( n ) < a
- !
- ! Method:
- ! Same as de Boor's INTERV sr, but not using a local index variable to
- ! store the last index found. Instead the 'first guess' index LEFT is
- ! used to initiate a search for the 'true' LEFT.
- !
- ! \ev
- !
- ! \item Swaps the elements in array 'xx' with length 'lx' :
- !
- ! \bv
- ! subroutine Swap( lx, xx )
- ! integer, intent(in) :: lx
- ! real, intent(inout) :: xx(lx)
- ! end subroutine Swap
- ! \ev
- !
- ! \end{itemize}
- !
- !
- ! !INTRODUCTION: Interpolation
- !
- ! \begin{itemize}
- !
- ! \item Linear interpolation, 1D arrays.
- ! \bv
- ! subroutine Interp_Lin( x,y, x0, y0, last, status )
- ! real, intent(in) :: x(n), y(n)
- ! real, intent(in) :: x0
- ! real, intent(out) :: y0
- ! integer, intent(inout) :: last
- ! integer, intent(out) :: status
- ! end subroutine Interp_Lin
- ! \ev
- ! Interpolate 'y' defined at positions 'x' linear to 'x0',
- ! return result in 'y0'. Index 'last' is a help variable used
- ! to speedup search algorithm in repated calls to this routine.
- !
- ! \item Linear interpolation in 2D array 'y'; last dimension corresponds to 'x'.
- ! \bv
- ! subroutine Interp_Lin( x,y, x0, y0, last, status )
- ! real, intent(in) :: x(n2), y(n1,n2)
- ! real, intent(in) :: x0
- ! real, intent(out) :: y0(n1)
- ! integer, intent(inout) :: last
- ! integer, intent(out) :: status
- ! end subroutine Interp_Lin
- ! \ev
- !
- ! \item Linear interpolation in 3D array 'y'; last dimension corresponds to 'x'.
- ! \bv
- ! subroutine Interp_Lin( x,y, x0, y0, last, status )
- ! real, intent(in) :: x(n3), y(n1,n2,n3)
- ! real, intent(in) :: x0
- ! real, intent(out) :: y0(n1,n2)
- ! integer, intent(inout) :: last
- ! integer, intent(out) :: status
- ! end subroutine Interp_Lin
- ! \ev
- !
- ! \item Compute interpolation weights.
- ! \bv
- ! subroutine Interp_Lin_Weight( x, x0, w, status )
- ! real, intent(in) :: x(n)
- ! real, intent(in) :: x0
- ! real, intent(out) :: w(n)
- ! integer, intent(out) :: status
- ! end subroutine InterpolWeight
- ! \ev
- ! Let array 'y' be defined on axis points 'x',
- ! and let 'x0' be a point on the axis. The weights 'w' are then
- ! computed such that:
- ! \bv
- ! y interpolated to x0 = sum( y(:) * w(:) )
- ! \ev
- !
- ! \item Linear interpolation, 1D arrays, 'x' cyclic with period 'p' :
- ! \bv
- ! subroutine CircInterp_Lin( x, p, y, x0, y0, last, status )
- ! real, intent(in) :: x(:), y(:)
- ! real, intent(in) :: p
- ! real, intent(in) :: x0
- ! real, intent(out) :: y0
- ! integer, intent(inout) :: last
- ! integer, intent(out) :: status
- ! end subroutine Interp_Lin
- ! \ev
- !
- ! \item Linear interpolation in 1D arrays to multiple points 'x0'.
- ! \bv
- ! subroutine Interp_Lin( x,y, x0, y0, status )
- ! real, intent(in) :: x(n), y(n)
- ! real, intent(in) :: x0(q)
- ! real, intent(out) :: y0(q)
- ! integer, intent(out) :: status
- ! end subroutine Interp_Lin
- ! \ev
- !
- ! \item Hermite-cubic interpolation in 1D arrays to multiple points 'x0'.
- ! \bv
- ! subroutine Interp_MuHerm( x,y, x0, y0, status )
- ! real, intent(in) :: x(n), y(n)
- ! real, intent(in) :: x0(q)
- ! real, intent(out) :: y0(q)
- ! integer, intent(out) :: status
- ! end subroutine Interp_MuHerm
- ! \ev
- !
- ! \end{itemize}
- !
- !
- !
- ! !INTRODUCTION: Quadrature
- !
- ! \begin{itemize}
- !
- ! \item Qudrature assuming linear interpolation.
- ! \bv
- ! subroutine IntervalQuad_Lin( x,y, a,b, c, ilast, status )
- ! real, intent(in) :: x(n), y(n)
- ! real, intent(in) :: a, b
- ! real, intent(out) :: c
- ! integer, intent(inout) :: ilast
- ! integer, intent(out) :: status
- ! end subroutine IntervalQuad_Lin
- ! \ev
- ! Compute an approximation to the integral:
- ! \bv
- ! b
- ! int y(x) dx
- ! x=a
- ! \ev
- ! Input is formed by two vectors 'x' and 'y' .
- ! Vector 'y' contains the function
- ! values to the abscissa values contained in 'x'.
- ! The result, stored in 'c', is computed using the trapezoid formula
- ! throughout the domain of integration.
- ! If 'a < x(1)' or 'b > x(n)' then the function is extended to 'a', resp. 'b',
- ! assuming a constant value of 'y(1)', resp. 'y(n)'.
- !
- ! The index 'ilast' should be set to 1 in the first call. If subsequent
- ! integrals on the same vector are to be computed, it should be kept
- ! unaltered between calls. This will speed up the lookup of values
- ! if the various integrals are ascending in 'x'.
- !
- ! \item Qudrature of cosined function assuming linear interpolation.
- ! \bv
- ! subroutine IntervalQuad_Cos_Lin( x, y, a, b, c, ilast, status )
- ! real, intent(in) :: x(n), y(n)
- ! real, intent(in) :: a, b
- ! real, intent(out) :: c
- ! integer, intent(inout) :: ilast
- ! integer, intent(out) :: status
- ! \ev
- ! Compute an approximation to the integral:
- ! \bv
- ! b
- ! int y(x) cos(x) dx
- ! x=a
- ! \ev
- ! See routine '\texttt{IntervalQuad\_Lin}' for method.
- !
- ! \item Qudrature of piecewise constant function.
- ! \bv
- ! subroutine IntervalQuad_Const( x, y, a,b, c, ilast, status )
- ! real, intent(in) :: x(n+1), y(n)
- ! real, intent(in) :: a, b
- ! real, intent(out) :: c
- ! integer, intent(inout) :: ilast
- ! integer, intent(out) :: status
- ! end subroutine IntervalQuad_Const
- ! \ev
- ! Compute integral over '[a,b]' for function specified by:
- ! \begin{itemize}
- ! \item interval boundaries 'x(1),..,x(n),x(n+1)'
- ! \item function values 'y(1),..,y(n)' ; constant in interval
- ! \end{itemize}
- ! \bv
- !
- ! y(1) y(2) y(3)
- ! +-----o-----+
- ! |/ / / / / /+-----o----+
- ! +----o----+ / / / / / / / / / /|
- ! | / / / / / / / / / / / |
- ! |/ / / / / / / / / / / /|
- ! ----+------|--+-----------+--------|-+---
- ! x(1) x(2) x(3) x(4)
- ! a b
- ! \ev
- ! See routine '\texttt{IntervalQuad\_Lin}' for method.
- !
- ! \item Sum values defined in interval.
- ! \bv
- ! subroutine IntervalSum( x, y, a_in, b_in, c, ilast, status, fac )
- ! real, intent(in) :: x(n+1), y(n)
- ! real, intent(in) :: a_in, b_in
- ! real, intent(out) :: c
- ! integer, intent(inout) :: ilast
- ! integer, intent(inout) :: status
- ! real, intent(out), optional :: fac(n)
- ! end subroutine IntervalSum
- ! \ev
- ! Compute sum of values 'y' over interval '[a,b]',
- ! \begin{itemize}
- ! \item interval boundaries 'x(1),..,x(n),x(n+1)'
- ! \item function values 'y(1),..,y(n)' ; constant in interval
- ! \end{itemize}
- ! \bv
- ! y(1) y(2) y(3)
- !
- ! 100%
- ! +-----o-----+ 60%
- ! 30% | ^ +-----o----+
- ! +----o----+ | ^
- ! ^ | |
- ! | | |
- ! | | |
- ! ----+------|--+-----------+--------|-+---
- ! x(1) x(2) x(3) x(4)
- ! a b
- ! \ev
- ! Each 'y(i)' contributes to the sum for the fraction
- ! of '[x(i),x(i+1)]' covered by '[a,b]'.
- ! If optional output array 'fac' is provided it is filled
- ! with the contributions for each element of 'y'.
- ! The result is stored in 'c'.
- ! If 'a<x(1)' or 'b>x(n+1)' an error is issued.
- !
- ! \end{itemize}
- !
- ! !INTRODUCTION: Sorting
- !
- ! \begin{itemize}
- !
- ! \item Sort rank-1 array:
- !
- ! \bv
- ! subroutine Sort( x, xsort, isort, status )
- ! real, intent(in) :: x (n)
- ! real, intent(out) :: xsort(n)
- ! integer, intent(out) :: isort(n)
- ! integer, intent(out) :: status
- ! end subroutine
- ! \ev
- !
- ! Sort the values of an array 'x' in increasing order.
- ! Sorted 'x' is stored in 'xsort', indices in 'isort' such that:
- ! \bv
- ! xsort(i) = x(isort(i))
- ! \ev
- !
- ! \item Sort rank-2 array:
- !
- ! \bv
- ! subroutine Sort( x, xsort, isort, status )
- ! real, intent(in) :: x (n1,n2)
- ! real, intent(out) :: xsort(n1,n2)
- ! integer, intent(out) :: isort(n1,n2,2)
- ! integer, intent(out) :: status
- ! end subroutine Sort
- ! \ev
- !
- ! Sort the values of an array 'x' in increasing order.
- ! Sorted 'x' is stored in 'xsort', indices in 'isort' such that:
- ! \bv
- ! xsort(i,j) = x(isort(i,j,1),isort(i,j,2))
- ! \ev
- !
- ! \end{itemize}
- !
- !
- !EOI
- !
- module num
- use num_tools
- use num_sort
- use num_minimum
- use num_interp
- use num_quad
- use num_matrix
-
- implicit none
-
- public
- end module num
|