num.F90 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. !
  2. !ProTeX: 1.14-AJS
  3. !
  4. !BOI
  5. !
  6. ! !TITLE: Num - numerical interpolation, quadrature, etc
  7. ! !AUTHORS: Arjo Segers
  8. ! !AFFILIATION: KNMI
  9. ! !DATE: \today
  10. !
  11. ! !INTRODUCTION: Tools
  12. !
  13. ! \begin{itemize}
  14. !
  15. ! \item Search interval that contains a value:
  16. !
  17. ! \bv
  18. ! subroutine Interval( x, a, ileft, iflag )
  19. ! real, intent(in) :: x(:)
  20. ! real, intent(in) :: a
  21. ! integer, intent(inout) :: ileft
  22. ! integer, intent(out) :: iflag
  23. ! end subroutine Interval
  24. !
  25. ! Computes:
  26. ! ileft = max( i, 1 <= i <= n, and x(i) < a )
  27. !
  28. ! Input:
  29. ! x: a real sequence of length n, assumed nondecreasing.
  30. ! a: the point whose location with tespect to the sequence
  31. ! x is to be determined.
  32. ! ileft: a 'first guess' estimate of the index to be found.
  33. ! this variable should be set to 1 for the first call to
  34. ! INTERVAL.
  35. ! Interpretate 'ileft' as the interval number {1,..,n-1}
  36. !
  37. ! Output:
  38. ! ileft iflag meaning
  39. ! ------ -------- -------------------------------------
  40. ! 1 -1 a < x(1)
  41. ! i 0 x(i) <= a < x(i+1)
  42. ! n-1 0 a = x( n )
  43. ! n 1 x( n ) < a
  44. !
  45. ! Method:
  46. ! Same as de Boor's INTERV sr, but not using a local index variable to
  47. ! store the last index found. Instead the 'first guess' index LEFT is
  48. ! used to initiate a search for the 'true' LEFT.
  49. !
  50. ! \ev
  51. !
  52. ! \item Swaps the elements in array 'xx' with length 'lx' :
  53. !
  54. ! \bv
  55. ! subroutine Swap( lx, xx )
  56. ! integer, intent(in) :: lx
  57. ! real, intent(inout) :: xx(lx)
  58. ! end subroutine Swap
  59. ! \ev
  60. !
  61. ! \end{itemize}
  62. !
  63. !
  64. ! !INTRODUCTION: Interpolation
  65. !
  66. ! \begin{itemize}
  67. !
  68. ! \item Linear interpolation, 1D arrays.
  69. ! \bv
  70. ! subroutine Interp_Lin( x,y, x0, y0, last, status )
  71. ! real, intent(in) :: x(n), y(n)
  72. ! real, intent(in) :: x0
  73. ! real, intent(out) :: y0
  74. ! integer, intent(inout) :: last
  75. ! integer, intent(out) :: status
  76. ! end subroutine Interp_Lin
  77. ! \ev
  78. ! Interpolate 'y' defined at positions 'x' linear to 'x0',
  79. ! return result in 'y0'. Index 'last' is a help variable used
  80. ! to speedup search algorithm in repated calls to this routine.
  81. !
  82. ! \item Linear interpolation in 2D array 'y'; last dimension corresponds to 'x'.
  83. ! \bv
  84. ! subroutine Interp_Lin( x,y, x0, y0, last, status )
  85. ! real, intent(in) :: x(n2), y(n1,n2)
  86. ! real, intent(in) :: x0
  87. ! real, intent(out) :: y0(n1)
  88. ! integer, intent(inout) :: last
  89. ! integer, intent(out) :: status
  90. ! end subroutine Interp_Lin
  91. ! \ev
  92. !
  93. ! \item Linear interpolation in 3D array 'y'; last dimension corresponds to 'x'.
  94. ! \bv
  95. ! subroutine Interp_Lin( x,y, x0, y0, last, status )
  96. ! real, intent(in) :: x(n3), y(n1,n2,n3)
  97. ! real, intent(in) :: x0
  98. ! real, intent(out) :: y0(n1,n2)
  99. ! integer, intent(inout) :: last
  100. ! integer, intent(out) :: status
  101. ! end subroutine Interp_Lin
  102. ! \ev
  103. !
  104. ! \item Compute interpolation weights.
  105. ! \bv
  106. ! subroutine Interp_Lin_Weight( x, x0, w, status )
  107. ! real, intent(in) :: x(n)
  108. ! real, intent(in) :: x0
  109. ! real, intent(out) :: w(n)
  110. ! integer, intent(out) :: status
  111. ! end subroutine InterpolWeight
  112. ! \ev
  113. ! Let array 'y' be defined on axis points 'x',
  114. ! and let 'x0' be a point on the axis. The weights 'w' are then
  115. ! computed such that:
  116. ! \bv
  117. ! y interpolated to x0 = sum( y(:) * w(:) )
  118. ! \ev
  119. !
  120. ! \item Linear interpolation, 1D arrays, 'x' cyclic with period 'p' :
  121. ! \bv
  122. ! subroutine CircInterp_Lin( x, p, y, x0, y0, last, status )
  123. ! real, intent(in) :: x(:), y(:)
  124. ! real, intent(in) :: p
  125. ! real, intent(in) :: x0
  126. ! real, intent(out) :: y0
  127. ! integer, intent(inout) :: last
  128. ! integer, intent(out) :: status
  129. ! end subroutine Interp_Lin
  130. ! \ev
  131. !
  132. ! \item Linear interpolation in 1D arrays to multiple points 'x0'.
  133. ! \bv
  134. ! subroutine Interp_Lin( x,y, x0, y0, status )
  135. ! real, intent(in) :: x(n), y(n)
  136. ! real, intent(in) :: x0(q)
  137. ! real, intent(out) :: y0(q)
  138. ! integer, intent(out) :: status
  139. ! end subroutine Interp_Lin
  140. ! \ev
  141. !
  142. ! \item Hermite-cubic interpolation in 1D arrays to multiple points 'x0'.
  143. ! \bv
  144. ! subroutine Interp_MuHerm( x,y, x0, y0, status )
  145. ! real, intent(in) :: x(n), y(n)
  146. ! real, intent(in) :: x0(q)
  147. ! real, intent(out) :: y0(q)
  148. ! integer, intent(out) :: status
  149. ! end subroutine Interp_MuHerm
  150. ! \ev
  151. !
  152. ! \end{itemize}
  153. !
  154. !
  155. !
  156. ! !INTRODUCTION: Quadrature
  157. !
  158. ! \begin{itemize}
  159. !
  160. ! \item Qudrature assuming linear interpolation.
  161. ! \bv
  162. ! subroutine IntervalQuad_Lin( x,y, a,b, c, ilast, status )
  163. ! real, intent(in) :: x(n), y(n)
  164. ! real, intent(in) :: a, b
  165. ! real, intent(out) :: c
  166. ! integer, intent(inout) :: ilast
  167. ! integer, intent(out) :: status
  168. ! end subroutine IntervalQuad_Lin
  169. ! \ev
  170. ! Compute an approximation to the integral:
  171. ! \bv
  172. ! b
  173. ! int y(x) dx
  174. ! x=a
  175. ! \ev
  176. ! Input is formed by two vectors 'x' and 'y' .
  177. ! Vector 'y' contains the function
  178. ! values to the abscissa values contained in 'x'.
  179. ! The result, stored in 'c', is computed using the trapezoid formula
  180. ! throughout the domain of integration.
  181. ! If 'a < x(1)' or 'b > x(n)' then the function is extended to 'a', resp. 'b',
  182. ! assuming a constant value of 'y(1)', resp. 'y(n)'.
  183. !
  184. ! The index 'ilast' should be set to 1 in the first call. If subsequent
  185. ! integrals on the same vector are to be computed, it should be kept
  186. ! unaltered between calls. This will speed up the lookup of values
  187. ! if the various integrals are ascending in 'x'.
  188. !
  189. ! \item Qudrature of cosined function assuming linear interpolation.
  190. ! \bv
  191. ! subroutine IntervalQuad_Cos_Lin( x, y, a, b, c, ilast, status )
  192. ! real, intent(in) :: x(n), y(n)
  193. ! real, intent(in) :: a, b
  194. ! real, intent(out) :: c
  195. ! integer, intent(inout) :: ilast
  196. ! integer, intent(out) :: status
  197. ! \ev
  198. ! Compute an approximation to the integral:
  199. ! \bv
  200. ! b
  201. ! int y(x) cos(x) dx
  202. ! x=a
  203. ! \ev
  204. ! See routine '\texttt{IntervalQuad\_Lin}' for method.
  205. !
  206. ! \item Qudrature of piecewise constant function.
  207. ! \bv
  208. ! subroutine IntervalQuad_Const( x, y, a,b, c, ilast, status )
  209. ! real, intent(in) :: x(n+1), y(n)
  210. ! real, intent(in) :: a, b
  211. ! real, intent(out) :: c
  212. ! integer, intent(inout) :: ilast
  213. ! integer, intent(out) :: status
  214. ! end subroutine IntervalQuad_Const
  215. ! \ev
  216. ! Compute integral over '[a,b]' for function specified by:
  217. ! \begin{itemize}
  218. ! \item interval boundaries 'x(1),..,x(n),x(n+1)'
  219. ! \item function values 'y(1),..,y(n)' ; constant in interval
  220. ! \end{itemize}
  221. ! \bv
  222. !
  223. ! y(1) y(2) y(3)
  224. ! +-----o-----+
  225. ! |/ / / / / /+-----o----+
  226. ! +----o----+ / / / / / / / / / /|
  227. ! | / / / / / / / / / / / |
  228. ! |/ / / / / / / / / / / /|
  229. ! ----+------|--+-----------+--------|-+---
  230. ! x(1) x(2) x(3) x(4)
  231. ! a b
  232. ! \ev
  233. ! See routine '\texttt{IntervalQuad\_Lin}' for method.
  234. !
  235. ! \item Sum values defined in interval.
  236. ! \bv
  237. ! subroutine IntervalSum( x, y, a_in, b_in, c, ilast, status, fac )
  238. ! real, intent(in) :: x(n+1), y(n)
  239. ! real, intent(in) :: a_in, b_in
  240. ! real, intent(out) :: c
  241. ! integer, intent(inout) :: ilast
  242. ! integer, intent(inout) :: status
  243. ! real, intent(out), optional :: fac(n)
  244. ! end subroutine IntervalSum
  245. ! \ev
  246. ! Compute sum of values 'y' over interval '[a,b]',
  247. ! \begin{itemize}
  248. ! \item interval boundaries 'x(1),..,x(n),x(n+1)'
  249. ! \item function values 'y(1),..,y(n)' ; constant in interval
  250. ! \end{itemize}
  251. ! \bv
  252. ! y(1) y(2) y(3)
  253. !
  254. ! 100%
  255. ! +-----o-----+ 60%
  256. ! 30% | ^ +-----o----+
  257. ! +----o----+ | ^
  258. ! ^ | |
  259. ! | | |
  260. ! | | |
  261. ! ----+------|--+-----------+--------|-+---
  262. ! x(1) x(2) x(3) x(4)
  263. ! a b
  264. ! \ev
  265. ! Each 'y(i)' contributes to the sum for the fraction
  266. ! of '[x(i),x(i+1)]' covered by '[a,b]'.
  267. ! If optional output array 'fac' is provided it is filled
  268. ! with the contributions for each element of 'y'.
  269. ! The result is stored in 'c'.
  270. ! If 'a<x(1)' or 'b>x(n+1)' an error is issued.
  271. !
  272. ! \end{itemize}
  273. !
  274. ! !INTRODUCTION: Sorting
  275. !
  276. ! \begin{itemize}
  277. !
  278. ! \item Sort rank-1 array:
  279. !
  280. ! \bv
  281. ! subroutine Sort( x, xsort, isort, status )
  282. ! real, intent(in) :: x (n)
  283. ! real, intent(out) :: xsort(n)
  284. ! integer, intent(out) :: isort(n)
  285. ! integer, intent(out) :: status
  286. ! end subroutine
  287. ! \ev
  288. !
  289. ! Sort the values of an array 'x' in increasing order.
  290. ! Sorted 'x' is stored in 'xsort', indices in 'isort' such that:
  291. ! \bv
  292. ! xsort(i) = x(isort(i))
  293. ! \ev
  294. !
  295. ! \item Sort rank-2 array:
  296. !
  297. ! \bv
  298. ! subroutine Sort( x, xsort, isort, status )
  299. ! real, intent(in) :: x (n1,n2)
  300. ! real, intent(out) :: xsort(n1,n2)
  301. ! integer, intent(out) :: isort(n1,n2,2)
  302. ! integer, intent(out) :: status
  303. ! end subroutine Sort
  304. ! \ev
  305. !
  306. ! Sort the values of an array 'x' in increasing order.
  307. ! Sorted 'x' is stored in 'xsort', indices in 'isort' such that:
  308. ! \bv
  309. ! xsort(i,j) = x(isort(i,j,1),isort(i,j,2))
  310. ! \ev
  311. !
  312. ! \end{itemize}
  313. !
  314. !
  315. !EOI
  316. !
  317. module num
  318. use num_tools
  319. use num_sort
  320. use num_minimum
  321. use num_interp
  322. use num_quad
  323. use num_matrix
  324. implicit none
  325. public
  326. end module num