storng.F90 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. MODULE storng
  2. !$AGRIF_DO_NOT_TREAT
  3. !!======================================================================
  4. !! *** MODULE storng ***
  5. !! Random number generator, used in NEMO stochastic parameterization
  6. !!
  7. !!=====================================================================
  8. !! History : 3.3 ! 2011-10 (J.-M. Brankart) Original code
  9. !!----------------------------------------------------------------------
  10. !!----------------------------------------------------------------------
  11. !! The module is based on (and includes) the
  12. !! 64-bit KISS (Keep It Simple Stupid) random number generator
  13. !! distributed by George Marsaglia :
  14. !! http://groups.google.com/group/comp.lang.fortran/
  15. !! browse_thread/thread/a85bf5f2a97f5a55
  16. !!----------------------------------------------------------------------
  17. !!----------------------------------------------------------------------
  18. !! kiss : 64-bit KISS random number generator (period ~ 2^250)
  19. !! kiss_seed : Define seeds for KISS random number generator
  20. !! kiss_state : Get current state of KISS random number generator
  21. !! kiss_save : Save current state of KISS (for future restart)
  22. !! kiss_load : Load the saved state of KISS
  23. !! kiss_reset : Reset the default seeds
  24. !! kiss_check : Check the KISS pseudo-random sequence
  25. !! kiss_uniform : Real random numbers with uniform distribution in [0,1]
  26. !! kiss_gaussian : Real random numbers with Gaussian distribution N(0,1)
  27. !! kiss_gamma : Real random numbers with Gamma distribution Gamma(k,1)
  28. !! kiss_sample : Select a random sample from a set of integers
  29. !!
  30. !! ---CURRENTLY NOT USED IN NEMO :
  31. !! kiss_save, kiss_load, kiss_check, kiss_gamma, kiss_sample
  32. !!----------------------------------------------------------------------
  33. USE par_kind
  34. USE lib_mpp
  35. IMPLICIT NONE
  36. PRIVATE
  37. ! Public functions/subroutines
  38. PUBLIC :: kiss, kiss_seed, kiss_state, kiss_reset ! kiss_save, kiss_load, kiss_check
  39. PUBLIC :: kiss_uniform, kiss_gaussian, kiss_gamma, kiss_sample
  40. ! Default/initial seeds
  41. INTEGER(KIND=i8) :: x=1234567890987654321_8
  42. INTEGER(KIND=i8) :: y=362436362436362436_8
  43. INTEGER(KIND=i8) :: z=1066149217761810_8
  44. INTEGER(KIND=i8) :: w=123456123456123456_8
  45. ! Parameters to generate real random variates
  46. REAL(KIND=wp), PARAMETER :: huge64=9223372036854775808.0 ! +1
  47. REAL(KIND=wp), PARAMETER :: zero=0.0, half=0.5, one=1.0, two=2.0
  48. ! Variables to store 2 Gaussian random numbers with current index (ig)
  49. INTEGER(KIND=i8), SAVE :: ig=1
  50. REAL(KIND=wp), SAVE :: gran1, gran2
  51. !!----------------------------------------------------------------------
  52. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  53. !! $Id: dynhpg.F90 2528 2010-12-27 17:33:53Z rblod $
  54. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  55. !!----------------------------------------------------------------------
  56. CONTAINS
  57. FUNCTION kiss()
  58. !! --------------------------------------------------------------------
  59. !! *** FUNCTION kiss ***
  60. !!
  61. !! ** Purpose : 64-bit KISS random number generator
  62. !!
  63. !! ** Method : combine several random number generators:
  64. !! (1) Xorshift (XSH), period 2^64-1,
  65. !! (2) Multiply-with-carry (MWC), period (2^121+2^63-1)
  66. !! (3) Congruential generator (CNG), period 2^64.
  67. !!
  68. !! overall period:
  69. !! (2^250+2^192+2^64-2^186-2^129)/6
  70. !! ~= 2^(247.42) or 10^(74.48)
  71. !!
  72. !! set your own seeds with 'kiss_seed'
  73. ! --------------------------------------------------------------------
  74. IMPLICIT NONE
  75. INTEGER(KIND=i8) :: kiss, t
  76. t = ISHFT(x,58) + w
  77. IF (s(x).eq.s(t)) THEN
  78. w = ISHFT(x,-6) + s(x)
  79. ELSE
  80. w = ISHFT(x,-6) + 1 - s(x+t)
  81. ENDIF
  82. x = t + x
  83. y = m( m( m(y,13_8), -17_8 ), 43_8 )
  84. z = 6906969069_8 * z + 1234567_8
  85. kiss = x + y + z
  86. CONTAINS
  87. FUNCTION s(k)
  88. INTEGER(KIND=i8) :: s, k
  89. s = ISHFT(k,-63)
  90. END FUNCTION s
  91. FUNCTION m(k, n)
  92. INTEGER(KIND=i8) :: m, k, n
  93. m = IEOR(k, ISHFT(k, n) )
  94. END FUNCTION m
  95. END FUNCTION kiss
  96. SUBROUTINE kiss_seed(ix, iy, iz, iw)
  97. !! --------------------------------------------------------------------
  98. !! *** ROUTINE kiss_seed ***
  99. !!
  100. !! ** Purpose : Define seeds for KISS random number generator
  101. !!
  102. !! --------------------------------------------------------------------
  103. IMPLICIT NONE
  104. INTEGER(KIND=i8) :: ix, iy, iz, iw
  105. x = ix
  106. y = iy
  107. z = iz
  108. w = iw
  109. END SUBROUTINE kiss_seed
  110. SUBROUTINE kiss_state(ix, iy, iz, iw)
  111. !! --------------------------------------------------------------------
  112. !! *** ROUTINE kiss_state ***
  113. !!
  114. !! ** Purpose : Get current state of KISS random number generator
  115. !!
  116. !! --------------------------------------------------------------------
  117. IMPLICIT NONE
  118. INTEGER(KIND=i8) :: ix, iy, iz, iw
  119. ix = x
  120. iy = y
  121. iz = z
  122. iw = w
  123. END SUBROUTINE kiss_state
  124. SUBROUTINE kiss_reset()
  125. !! --------------------------------------------------------------------
  126. !! *** ROUTINE kiss_reset ***
  127. !!
  128. !! ** Purpose : Reset the default seeds for KISS random number generator
  129. !!
  130. !! --------------------------------------------------------------------
  131. IMPLICIT NONE
  132. x=1234567890987654321_8
  133. y=362436362436362436_8
  134. z=1066149217761810_8
  135. w=123456123456123456_8
  136. END SUBROUTINE kiss_reset
  137. ! SUBROUTINE kiss_check(check_type)
  138. ! !! --------------------------------------------------------------------
  139. ! !! *** ROUTINE kiss_check ***
  140. ! !!
  141. ! !! ** Purpose : Check the KISS pseudo-random sequence
  142. ! !!
  143. ! !! ** Method : Check that it reproduces the correct sequence
  144. ! !! from the default seed
  145. ! !!
  146. ! !! --------------------------------------------------------------------
  147. ! IMPLICIT NONE
  148. ! INTEGER(KIND=i8) :: iter, niter, correct, iran
  149. ! CHARACTER(LEN=*) :: check_type
  150. ! LOGICAL :: print_success
  151. ! ! Save current state of KISS
  152. ! CALL kiss_save()
  153. ! ! Reset the default seed
  154. ! CALL kiss_reset()
  155. ! ! Select check type
  156. ! SELECT CASE(check_type)
  157. ! CASE('short')
  158. ! niter = 5_8
  159. ! correct = 542381058189297533
  160. ! print_success = .FALSE.
  161. ! CASE('long')
  162. ! niter = 100000000_8
  163. ! correct = 1666297717051644203 ! Check provided by G. Marsaglia
  164. ! print_success = .TRUE.
  165. ! CASE('default')
  166. ! CASE DEFAULT
  167. ! STOP 'Bad check type in kiss_check'
  168. ! END SELECT
  169. ! ! Run kiss for the required number of iterations (niter)
  170. ! DO iter=1,niter
  171. ! iran = kiss()
  172. ! ENDDO
  173. ! ! Check that last iterate is correct
  174. ! IF (iran.NE.correct) THEN
  175. ! STOP 'Check failed: KISS internal error !!'
  176. ! ELSE
  177. ! IF (print_success) PRINT *, 'Check successful: 100 million calls to KISS OK'
  178. ! ENDIF
  179. ! ! Reload the previous state of KISS
  180. ! CALL kiss_load()
  181. ! END SUBROUTINE kiss_check
  182. ! SUBROUTINE kiss_save
  183. ! !! --------------------------------------------------------------------
  184. ! !! *** ROUTINE kiss_save ***
  185. ! !!
  186. ! !! ** Purpose : Save current state of KISS random number generator
  187. ! !!
  188. ! !! --------------------------------------------------------------------
  189. ! INTEGER :: inum !! Local integer
  190. ! IMPLICIT NONE
  191. ! CALL ctl_opn( inum, '.kiss_restart', 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, numout, lwp )
  192. ! ! OPEN(UNIT=30,FILE='.kiss_restart')
  193. ! WRITE(inum,*) x
  194. ! WRITE(inum,*) y
  195. ! WRITE(inum,*) z
  196. ! WRITE(inum,*) w
  197. ! CALL flush(inum)
  198. ! END SUBROUTINE kiss_save
  199. ! SUBROUTINE kiss_load
  200. ! !! --------------------------------------------------------------------
  201. ! !! *** ROUTINE kiss_load ***
  202. ! !!
  203. ! !! ** Purpose : Load the saved state of KISS random number generator
  204. ! !!
  205. ! !! --------------------------------------------------------------------
  206. ! IMPLICIT NONE
  207. ! LOGICAL :: filexists
  208. ! Use ctl_opn routine rather than fortran intrinsic functions
  209. ! INQUIRE(FILE='.kiss_restart',EXIST=filexists)
  210. ! IF (filexists) THEN
  211. ! OPEN(UNIT=30,FILE='.kiss_restart')
  212. ! READ(30,*) x
  213. ! READ(30,*) y
  214. ! READ(30,*) z
  215. ! READ(30,*) w
  216. ! CLOSE(30)
  217. ! ENDIF
  218. ! END SUBROUTINE kiss_load
  219. SUBROUTINE kiss_uniform(uran)
  220. !! --------------------------------------------------------------------
  221. !! *** ROUTINE kiss_uniform ***
  222. !!
  223. !! ** Purpose : Real random numbers with uniform distribution in [0,1]
  224. !!
  225. !! --------------------------------------------------------------------
  226. IMPLICIT NONE
  227. REAL(KIND=wp) :: uran
  228. uran = half * ( one + REAL(kiss(),wp) / huge64 )
  229. END SUBROUTINE kiss_uniform
  230. SUBROUTINE kiss_gaussian(gran)
  231. !! --------------------------------------------------------------------
  232. !! *** ROUTINE kiss_gaussian ***
  233. !!
  234. !! ** Purpose : Real random numbers with Gaussian distribution N(0,1)
  235. !!
  236. !! ** Method : Generate 2 new Gaussian draws (gran1 and gran2)
  237. !! from 2 uniform draws on [-1,1] (u1 and u2),
  238. !! using the Marsaglia polar method
  239. !! (see Devroye, Non-Uniform Random Variate Generation, p. 235-236)
  240. !!
  241. !! --------------------------------------------------------------------
  242. IMPLICIT NONE
  243. REAL(KIND=wp) :: gran, u1, u2, rsq, fac
  244. IF (ig.EQ.1) THEN
  245. rsq = two
  246. DO WHILE ( (rsq.GE.one).OR. (rsq.EQ.zero) )
  247. u1 = REAL(kiss(),wp) / huge64
  248. u2 = REAL(kiss(),wp) / huge64
  249. rsq = u1*u1 + u2*u2
  250. ENDDO
  251. fac = SQRT(-two*LOG(rsq)/rsq)
  252. gran1 = u1 * fac
  253. gran2 = u2 * fac
  254. ENDIF
  255. ! Output one of the 2 draws
  256. IF (ig.EQ.1) THEN
  257. gran = gran1 ; ig = 2
  258. ELSE
  259. gran = gran2 ; ig = 1
  260. ENDIF
  261. END SUBROUTINE kiss_gaussian
  262. SUBROUTINE kiss_gamma(gamr,k)
  263. !! --------------------------------------------------------------------
  264. !! *** ROUTINE kiss_gamma ***
  265. !!
  266. !! ** Purpose : Real random numbers with Gamma distribution Gamma(k,1)
  267. !!
  268. !! --------------------------------------------------------------------
  269. IMPLICIT NONE
  270. REAL(KIND=wp), PARAMETER :: p1 = 4.5_8
  271. REAL(KIND=wp), PARAMETER :: p2 = 2.50407739677627_8 ! 1+LOG(9/2)
  272. REAL(KIND=wp), PARAMETER :: p3 = 1.38629436111989_8 ! LOG(4)
  273. REAL(KIND=wp) :: gamr, k, u1, u2, b, c, d, xx, yy, zz, rr, ee
  274. LOGICAL :: accepted
  275. IF (k.GT.one) THEN
  276. ! Cheng's rejection algorithm
  277. ! (see Devroye, Non-Uniform Random Variate Generation, p. 413)
  278. b = k - p3 ; d = SQRT(two*k-one) ; c = k + d
  279. accepted=.FALSE.
  280. DO WHILE (.NOT.accepted)
  281. CALL kiss_uniform(u1)
  282. yy = LOG(u1/(one-u1)) / d ! Mistake in Devroye: "* k" instead of "/ d"
  283. xx = k * EXP(yy)
  284. rr = b + c * yy - xx
  285. CALL kiss_uniform(u2)
  286. zz = u1 * u1 * u2
  287. accepted = rr .GE. (zz*p1-p2)
  288. IF (.NOT.accepted) accepted = rr .GE. LOG(zz)
  289. ENDDO
  290. gamr = xx
  291. ELSEIF (k.LT.one) THEN
  292. ! Rejection from the Weibull density
  293. ! (see Devroye, Non-Uniform Random Variate Generation, p. 415)
  294. c = one/k ; d = (one-k) * EXP( (k/(one-k)) * LOG(k) )
  295. accepted=.FALSE.
  296. DO WHILE (.NOT.accepted)
  297. CALL kiss_uniform(u1)
  298. zz = -LOG(u1)
  299. xx = EXP( c * LOG(zz) )
  300. CALL kiss_uniform(u2)
  301. ee = -LOG(u2)
  302. accepted = (zz+ee) .GE. (d+xx) ! Mistake in Devroye: "LE" instead of "GE"
  303. ENDDO
  304. gamr = xx
  305. ELSE
  306. ! Exponential distribution
  307. CALL kiss_uniform(u1)
  308. gamr = -LOG(u1)
  309. ENDIF
  310. END SUBROUTINE kiss_gamma
  311. SUBROUTINE kiss_sample(a,n,k)
  312. !! --------------------------------------------------------------------
  313. !! *** ROUTINE kiss_sample ***
  314. !!
  315. !! ** Purpose : Select a random sample of size k from a set of n integers
  316. !!
  317. !! ** Method : The sample is output in the first k elements of a
  318. !! Set k equal to n to obtain a random permutation
  319. !! of the whole set of integers
  320. !!
  321. !! --------------------------------------------------------------------
  322. IMPLICIT NONE
  323. INTEGER(KIND=i8), DIMENSION(:) :: a
  324. INTEGER(KIND=i8) :: n, k, i, j, atmp
  325. REAL(KIND=wp) :: uran
  326. ! Select the sample using the swapping method
  327. ! (see Devroye, Non-Uniform Random Variate Generation, p. 612)
  328. DO i=1,k
  329. ! Randomly select the swapping element between i and n (inclusive)
  330. CALL kiss_uniform(uran)
  331. j = i - 1 + CEILING( REAL(n-i+1,8) * uran )
  332. ! Swap elements i and j
  333. atmp = a(i) ; a(i) = a(j) ; a(j) = atmp
  334. ENDDO
  335. END SUBROUTINE kiss_sample
  336. !$AGRIF_END_DO_NOT_TREAT
  337. END MODULE storng