SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
mode_random.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 MODULE mode_random
6 ! A module for random number generation from the following distributions:
7 !
8 ! Distribution Function/subroutine name
9 !
10 ! Normal (Gaussian) random_normal
11 ! Gamma random_gamma
12 ! Chi-squared random_chisq
13 ! Exponential random_exponential
14 ! Weibull random_Weibull
15 ! Beta random_beta
16 ! t random_t
17 ! Multivariate normal random_mvnorm
18 ! Generalized inverse Gaussian random_inv_gauss
19 ! Poisson random_Poisson
20 ! Binomialrandom_binomial1 *
21 ! random_binomial2 *
22 ! Negative binomial random_neg_binomial
23 ! von Mises random_von_Mises
24 ! Cauchy random_Cauchy
25 !
26 ! Generate a random ordering of the integers 1 .. N
27 ! random_order
28 ! Initialize (seed) the uniform random number generator for ANY compiler
29 ! seed_random_number
30 
31 ! Lognormal - see note below.
32 
33 ! ** Two functions are provided for the binomial distribution.
34 ! If the parameter values remain constant, it is recommended that the
35 ! first function is used (random_binomial1). If one or both of the
36 ! parameters change, use the second function (random_binomial2).
37 
38 ! The compilers own random number generator, SUBROUTINE RANDOM_NUMBER(r),
39 ! is used to provide a source of uniformly distributed random numbers.
40 
41 ! N.B. At this stage, only one random number is generated at each call to
42 ! one of the functions above.
43 
44 ! The module uses the following functions which are included here:
45 ! bin_prob to calculate a single binomial probability
46 ! lngamma to calculate the logarithm to base e of the gamma function
47 
48 ! Some of the code is adapted from Dagpunar's book:
49 ! Dagpunar, J. 'Principles of random variate generation'
50 ! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
51 !
52 ! In most of Dagpunar's routines, there is a test to see whether the value
53 ! of one or two floating-point parameters has changed since the last call.
54 ! These tests have been replaced by using a logical variable FIRST.
55 ! This should be set to .TRUE. on the first call using new values of the
56 ! parameters, and .FALSE. if the parameter values are the same as for the
57 ! previous call.
58 
59 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
60 ! Lognormal distribution
61 ! If X has a lognormal distribution, then log(X) is normally distributed.
62 ! Here the logarithm is the natural logarithm, that is to base e, sometimes
63 ! denoted as ln. To generate random variates from this distribution, generate
64 ! a random deviate from the normal distribution with mean and variance equal
65 ! to the mean and variance of the logarithms of X, then take its exponential.
66 
67 ! Relationship between the mean & variance of log(X) and the mean & variance
68 ! of X, when X has a lognormal distribution.
69 ! Let m = mean of log(X), and s^2 = variance of log(X)
70 ! Then
71 ! mean of X = exp(m + 0.5s^2)
72 ! variance of X = (mean(X))^2.[exp(s^2) - 1]
73 
74 ! In the reverse direction (rarely used)
75 ! variance of log(X) = log[1 + var(X)/(mean(X))^2]
76 ! mean of log(X) = log(mean(X) - 0.5var(log(X))
77 
78 ! N.B. The above formulae relate to population parameters; they will only be
79 ! approximate if applied to sample values.
80 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
81 
82 ! Version 1.13, 2 October 2000
83 ! Changes from version 1.01
84 ! 1. The random_order, random_Poisson & random_binomial routines have been
85 ! replaced with more efficient routines.
86 ! 2. A routine, seed_random_number, has been added to seed the uniform random
87 ! number generator. This requires input of the required number of seeds
88 ! for the particular compiler from a specified I/O unit such as a keyboard.
89 ! 3. Made compatible with Lahey's ELF90.
90 ! 4. Marsaglia & Tsang algorithm used for random_gamma when shape parameter > 1.
91 ! 5. INTENT for array f corrected in random_mvnorm.
92 
93 ! Author: Alan Miller
94 ! CSIRO Division of Mathematical & Information Sciences
95 ! Private Bag 10, Clayton South MDC
96 ! Clayton 3169, Victoria, Australia
97 ! Phone: (+61) 3 9545-8016 Fax: (+61) 3 9545-8080
98 ! e-mail: amiller @ bigpond.net.au
99 !
100 USE yomhook ,ONLY : lhook, dr_hook
101 USE parkind1 ,ONLY : jprb
102 !
103 IMPLICIT NONE
104 !
105 REAL :: XHALF = 0.5
106 !REAL :: XZERO = 0.0, XONE = 1.0, XTWO = 2.0, &
107 ! XVSMALL = TINY(1.0), XVLARGE = HUGE(1.0)
108 !INTEGER, PARAMETER :: IDP = SELECTED_REAL_KIND(12, 60)
109 !
110  CONTAINS
111 !
112 !
113 SUBROUTINE init_random_seed()
114 !
115 INTEGER, DIMENSION(:), ALLOCATABLE :: iseed
116 INTEGER :: i, iin, iclock
117 REAL(KIND=JPRB) :: zhook_handle
118 !
119 IF (lhook) CALL dr_hook('MODE_RANDOM_NUMBER:INIT_RANDOM_SEED',0,zhook_handle)
120 !
121  CALL random_seed(size = iin)
122 ALLOCATE(iseed(iin))
123 !
124  CALL system_clock(count=iclock)
125 !
126 iseed(:) = iclock + 37 * (/ (i - 1, i = 1, iin) /)
127 !
128  CALL random_seed(put = iseed)
129 !
130 DEALLOCATE(iseed)
131 !
132 IF (lhook) CALL dr_hook('MODE_RANDOM_NUMBER:INIT_RANDOM_SEED',1,zhook_handle)
133 !
134 END SUBROUTINE init_random_seed
135 !
136 !
137 FUNCTION random_normal() RESULT(PFN_VAL)
138 !
139 ! Adapted from the following Fortran 77 code
140 ! ALGORITHM 712, COLLECTED ALGORITHMS FROM ACM.
141 ! THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE,
142 ! VOL. 18, NO. 4, DECEMBER, 1992, PP. 434-435.
143 !
144 ! The function random_normal() returns a normally distributed pseudo-random
145 ! number with zero mean and unit variance.
146 !
147 ! The algorithm uses the ratio of uniforms method of A.J. Kinderman
148 ! and J.F. Monahan augmented with quadratic bounding curves.
149 !
150 REAL :: pfn_val
151 !
152 ! Local variables
153 REAL :: zs = 0.449871, zt = -0.386595, za = 0.19600, zb = 0.25472, &
154  zr1 = 0.27597, zr2 = 0.27846, zu, zv, zx, zy, zq
155 !
156 REAL(KIND=JPRB) :: zhook_handle
157 !
158 ! Generate P = (u,v) uniform in rectangle enclosing acceptance region
159 !
160 IF (lhook) CALL dr_hook('MODE_RANDOM_NUMBER:RANDOM_NORMAL',0,zhook_handle)
161 !
162 DO
163  !
164  CALL random_number(zu)
165  CALL random_number(zv)
166  !
167  zv = 1.7156 * (zv - xhalf)
168  !
169  ! Evaluate the quadratic form
170  !
171  zx = zu - zs
172  zy = abs(zv) - zt
173  zq = zx**2 + zy*(za*zy - zb*zx)
174  !
175  ! Accept P if inside inner ellipse
176  IF (zq < zr1) EXIT
177  !
178  ! Reject P if outside outer ellipse
179  IF (zq > zr2) cycle
180  !
181  ! Reject P if outside acceptance region
182  IF (zv**2 < -4.0*log(zu)*zu**2) EXIT
183  !
184 END DO
185 !
186 ! Return ratio of P's coordinates as the normal deviate
187 pfn_val = zv/zu
188 !
189 IF (lhook) CALL dr_hook('MODE_RANDOM_NUMBER:RANDOM_NORMAL',1,zhook_handle)
190 !
191 END FUNCTION random_normal
192 !
193 !FUNCTION random_gamma(s, first) RESULT(fn_val)
194 !
195 !! Adapted from Fortran 77 code from the book:
196 !! Dagpunar, J. 'Principles of random variate generation'
197 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
198 !
199 !! FUNCTION GENERATES A RANDOM GAMMA VARIATE.
200 !! CALLS EITHER random_gamma1 (S > 1.0)
201 !! OR random_exponential (S = 1.0)
202 !! OR random_gamma2 (S < 1.0).
203 !
204 !! S = SHAPE PARAMETER OF DISTRIBUTION (0 < REAL).
205 !
206 !REAL, INTENT(IN) :: s
207 !LOGICAL, INTENT(IN) :: first
208 !REAL :: fn_val
209 !
210 !IF (s <= XZERO) THEN
211 ! WRITE(*, *) 'SHAPE PARAMETER VALUE MUST BE POSITIVE'
212 ! STOP
213 !END IF
214 !
215 !IF (s > XONE) THEN
216 ! fn_val = random_gamma1(s, first)
217 !ELSE IF (s < XONE) THEN
218 ! fn_val = random_gamma2(s, first)
219 !ELSE
220 ! fn_val = random_expXONEntial()
221 !END IF
222 !
223 !RETURN
224 !END FUNCTION random_gamma
225 !
226 !
227 !
228 !FUNCTION random_gamma1(s, first) RESULT(fn_val)
229 !
230 !! Uses the algorithm in
231 !! Marsaglia, G. and Tsang, W.W. (2000) `A simple method for generating
232 !! gamma variables', Trans. om Math. Software (TOMS), vol.26(3), pp.363-372.
233 !
234 !! Generates a random gamma deviate for shape parameter s >= 1.
235 !
236 !REAL, INTENT(IN) :: s
237 !LOGICAL, INTENT(IN) :: first
238 !REAL :: fn_val
239 !
240 !! Local variables
241 !REAL, SAVE :: c, d
242 !REAL :: u, v, x
243 !
244 !IF (first) THEN
245 ! d = s - XONE/3.
246 ! c = XONE/SQRT(9.0*d)
247 !END IF
248 !
249 !! Start of main loop
250 !DO
251 !
252 !! Generate v = (1+cx)^3 where x is random normal; repeat if v <= 0.
253 !
254 ! DO
255 ! x = random_normal()
256 ! v = (XONE + c*x)**3
257 ! IF (v > XZERO) EXIT
258 ! END DO
259 !
260 !! Generate uniform variable U
261 !
262 ! CALL RANDOM_NUMBER(u)
263 ! IF (u < XONE - 0.0331*x**4) THEN
264 ! fn_val = d*v
265 ! EXIT
266 ! ELSE IF (LOG(u) < XHALF*x**2 + d*(XONE - v + LOG(v))) THEN
267 ! fn_val = d*v
268 ! EXIT
269 ! END IF
270 !END DO
271 !
272 !RETURN
273 !END FUNCTION random_gamma1
274 !
275 !
276 !
277 !FUNCTION random_gamma2(s, first) RESULT(fn_val)
278 !
279 !! Adapted from Fortran 77 code from the book:
280 !! Dagpunar, J. 'Principles of random variate generation'
281 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
282 !
283 !! FUNCTION GENERATES A RANDOM VARIATE IN [0,INFINITY) FROM
284 !! A GAMMA DISTRIBUTION WITH DENSITY PROPORTIONAL TO
285 !! GAMMA2**(S-1) * EXP(-GAMMA2),
286 !! USING A SWITCHING METHOD.
287 !
288 !! S = SHAPE PARAMETER OF DISTRIBUTION
289 !! (REAL < 1.0)
290 !
291 !REAL, INTENT(IN) :: s
292 !LOGICAL, INTENT(IN) :: first
293 !REAL :: fn_val
294 !
295 !! Local variables
296 !REAL :: r, x, w
297 !REAL, SAVE :: a, p, c, uf, vr, d
298 !
299 !IF (s <= XZERO .OR. s >= XONE) THEN
300 ! WRITE(*, *) 'SHAPE PARAMETER VALUE OUTSIDE PERMITTED RANGE'
301 ! STOP
302 !END IF
303 !
304 !IF (first) THEN! Initialization, if necessary
305 ! a = XONE - s
306 ! p = a/(a + s*EXP(-a))
307 ! IF (s < XVSMALL) THEN
308 ! WRITE(*, *) 'SHAPE PARAMETER VALUE TOO SMALL'
309 ! STOP
310 ! END IF
311 ! c = XONE/s
312 ! uf = p*(XVSMALL/a)**s
313 ! vr = XONE - XVSMALL
314 ! d = a*LOG(a)
315 !END IF
316 !
317 !DO
318 ! CALL RANDOM_NUMBER(r)
319 ! IF (r >= vr) THEN
320 ! CYCLE
321 ! ELSE IF (r > p) THEN
322 ! x = a - LOG((XONE - r)/(XONE - p))
323 ! w = a*LOG(x)-d
324 ! ELSE IF (r > uf) THEN
325 ! x = a*(r/p)**c
326 ! w = x
327 ! ELSE
328 ! fn_val = XZERO
329 ! RETURN
330 ! END IF
331 !
332 ! CALL RANDOM_NUMBER(r)
333 ! IF (XONE-r <= w .AND. r > XZERO) THEN
334 ! IF (r*(w + XONE) >= XONE) CYCLE
335 ! IF (-LOG(r) <= w) CYCLE
336 ! END IF
337 ! EXIT
338 !END DO
339 !
340 !fn_val = x
341 !RETURN
342 !
343 !END FUNCTION random_gamma2
344 !
345 !
346 !
347 !FUNCTION random_chisq(ndf, first) RESULT(fn_val)
348 !
349 !! Generates a random variate from the chi-squared distribution with
350 !! ndf degrees of freedom
351 !
352 !INTEGER, INTENT(IN) :: ndf
353 !LOGICAL, INTENT(IN) :: first
354 !REAL :: fn_val
355 !
356 !fn_val = XTWO * random_gamma(XHALF*ndf, first)
357 !RETURN
358 !
359 !END FUNCTION random_chisq
360 !
361 !!
362 !FUNCTION random_exponential() RESULT(fn_val)
363 !
364 !! Adapted from Fortran 77 code from the book:
365 !! Dagpunar, J. 'Principles of random variate generation'
366 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
367 !
368 !! FUNCTION GENERATES A RANDOM VARIATE IN [0,INFINITY) FROM
369 !! A NEGATIVE EXPONENTIAL DlSTRIBUTION WlTH DENSITY PROPORTIONAL
370 !! TO EXP(-random_exponential), USING INVERSION.
371 !
372 !REAL :: fn_val
373 !
374 !! Local variable
375 !REAL :: r
376 !
377 !DO
378 ! CALL RANDOM_NUMBER(r)
379 ! IF (r > XZERO) EXIT
380 !END DO
381 !
382 !fn_val = -LOG(r)
383 !RETURN
384 !
385 !END FUNCTION random_exponential
386 !
387 !
388 !
389 !FUNCTION random_Weibull(a) RESULT(fn_val)
390 !
391 !! Generates a random variate from the Weibull distribution with
392 !! probability density:
393 !! a
394 !! a-1 -x
395 !! f(x) = a.x e
396 !
397 !REAL, INTENT(IN) :: a
398 !REAL :: fn_val
399 !
400 !! For speed, there is no checking that a is not zero or very small.
401 !
402 !fn_val = random_exponential() ** (XONE/a)
403 !RETURN
404 !
405 !END FUNCTION random_Weibull
406 !
407 !
408 !
409 !FUNCTION random_beta(aa, bb, first) RESULT(fn_val)
410 !
411 !! Adapted from Fortran 77 code from the book:
412 !! Dagpunar, J. 'Principles of random variate generation'
413 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
414 !
415 !! FUNCTION GENERATES A RANDOM VARIATE IN [0,1]
416 !! FROM A BETA DISTRIBUTION WITH DENSITY
417 !! PROPORTIONAL TO BETA**(AA-1) * (1-BETA)**(BB-1).
418 !! USING CHENG'S LOG LOGISTIC METHOD.
419 !
420 !! AA = SHAPE PARAMETER FROM DISTRIBUTION (0 < REAL)
421 !! BB = SHAPE PARAMETER FROM DISTRIBUTION (0 < REAL)
422 !
423 !REAL, INTENT(IN) :: aa, bb
424 !LOGICAL, INTENT(IN) :: first
425 !REAL :: fn_val
426 !
427 !! Local variables
428 !REAL, PARAMETER :: aln4 = 1.3862944
429 !REAL :: a, b, g, r, s, x, y, z
430 !REAL, SAVE :: d, f, h, t, c
431 !LOGICAL, SAVE :: swap
432 !
433 !IF (aa <= XZERO .OR. bb <= XZERO) THEN
434 ! WRITE(*, *) 'IMPERMISSIBLE SHAPE PARAMETER VALUE(S)'
435 ! STOP
436 !END IF
437 !
438 !IF (first) THEN! Initialization, if necessary
439 ! a = aa
440 ! b = bb
441 ! swap = b > a
442 ! IF (swap) THEN
443 ! g = b
444 ! b = a
445 ! a = g
446 ! END IF
447 ! d = a/b
448 ! f = a+b
449 ! IF (b > XONE) THEN
450 ! h = SQRT((XTWO*a*b - f)/(f - XTWO))
451 ! t = XONE
452 ! ELSE
453 ! h = b
454 ! t = XONE/(XONE + (a/(XVLARGE*b))**b)
455 ! END IF
456 ! c = a+h
457 !END IF
458 !
459 !DO
460 ! CALL RANDOM_NUMBER(r)
461 ! CALL RANDOM_NUMBER(x)
462 ! s = r*r*x
463 ! IF (r < XVSMALL .OR. s <= XZERO) CYCLE
464 ! IF (r < t) THEN
465 ! x = LOG(r/(XONE - r))/h
466 ! y = d*EXP(x)
467 ! z = c*x + f*LOG((XONE + d)/(XONE + y)) - aln4
468 ! IF (s - XONE > z) THEN
469 ! IF (s - s*z > XONE) CYCLE
470 ! IF (LOG(s) > z) CYCLE
471 ! END IF
472 ! fn_val = y/(XONE + y)
473 ! ELSE
474 ! IF (4.0*s > (XONE + XONE/d)**f) CYCLE
475 ! fn_val = XONE
476 ! END IF
477 ! EXIT
478 !END DO
479 !
480 !IF (swap) fn_val = XONE - fn_val
481 !RETURN
482 !END FUNCTION random_beta
483 !
484 !
485 !
486 !FUNCTION random_t(m) RESULT(fn_val)
487 !
488 !! Adapted from Fortran 77 code from the book:
489 !! Dagpunar, J. 'Principles of random variate generation'
490 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
491 !
492 !! FUNCTION GENERATES A RANDOM VARIATE FROM A
493 !! T DISTRIBUTION USING KINDERMAN AND MONAHAN'S RATIO METHOD.
494 !
495 !! M = DEGREES OF FREEDOM OF DISTRIBUTION
496 !! (1 <= 1NTEGER)
497 !
498 !INTEGER, INTENT(IN) :: m
499 !REAL :: fn_val
500 !
501 !! Local variables
502 !REAL, SAVE :: s, c, a, f, g
503 !REAL:: r, x, v
504 !
505 !REAL, PARAMETER :: three = 3.0, four = 4.0, quart = 0.25, &
506 ! five = 5.0, sixteen = 16.0
507 !INTEGER :: mm = 0
508 !
509 !IF (m < 1) THEN
510 ! WRITE(*, *) 'IMPERMISSIBLE DEGREES OF FREEDOM'
511 ! STOP
512 !END IF
513 !
514 !IF (m /= mm) THEN ! Initialization, if necessary
515 ! s = m
516 ! c = -quart*(s + XONE)
517 ! a = four/(XONE + XONE/s)**c
518 ! f = sixteen/a
519 ! IF (m > 1) THEN
520 ! g = s - XONE
521 ! g = ((s + XONE)/g)**c*SQRT((s+s)/g)
522 ! ELSE
523 ! g = XONE
524 ! END IF
525 ! mm = m
526 !END IF
527 !
528 !DO
529 ! CALL RANDOM_NUMBER(r)
530 ! IF (r <= XZERO) CYCLE
531 ! CALL RANDOM_NUMBER(v)
532 ! x = (XTWO*v - XONE)*g/r
533 ! v = x*x
534 ! IF (v > five - a*r) THEN
535 ! IF (m >= 1 .AND. r*(v + three) > f) CYCLE
536 ! IF (r > (XONE + v/s)**c) CYCLE
537 ! END IF
538 ! EXIT
539 !END DO
540 !
541 !fn_val = x
542 !RETURN
543 !END FUNCTION random_t
544 !
545 !
546 !
547 !SUBROUTINE random_mvnorm(n, h, d, f, first, x, ier)
548 !
549 !! Adapted from Fortran 77 code from the book:
550 !! Dagpunar, J. 'Principles of random variate generation'
551 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
552 !
553 !! N.B. An extra argument, ier, has been added to Dagpunar's routine
554 !
555 !! SUBROUTINE GENERATES AN N VARIATE RANDOM NORMAL
556 !! VECTOR USING A CHOLESKY DECOMPOSITION.
557 !
558 !! ARGUMENTS:
559 !! N = NUMBER OF VARIATES IN VECTOR
560 !! (INPUT,INTEGER >= 1)
561 !! H(J) = J'TH ELEMENT OF VECTOR OF MEANS
562 !! (INPUT,REAL)
563 !! X(J) = J'TH ELEMENT OF DELIVERED VECTOR
564 !! (OUTPUT,REAL)
565 !!
566 !! D(J*(J-1)/2+I) = (I,J)'TH ELEMENT OF VARIANCE MATRIX (J> = I)
567 !!(INPUT,REAL)
568 !! F((J-1)*(2*N-J)/2+I) = (I,J)'TH ELEMENT OF LOWER TRIANGULAR
569 !! DECOMPOSITION OF VARIANCE MATRIX (J <= I)
570 !!(OUTPUT,REAL)
571 !
572 !! FIRST = .TRUE. IF THIS IS THE FIRST CALL OF THE ROUTINE
573 !! OR IF THE DISTRIBUTION HAS CHANGED SINCE THE LAST CALL OF THE ROUTINE.
574 !! OTHERWISE SET TO .FALSE.
575 !!(INPUT,LOGICAL)
576 !
577 !! ier = 1 if the input covariance matrix is not +ve definite
578 !! = 0 otherwise
579 !
580 !INTEGER, INTENT(IN) :: n
581 !REAL, INTENT(IN) :: h(:), d(:) ! d(n*(n+1)/2)
582 !REAL, INTENT(IN OUT) :: f(:) ! f(n*(n+1)/2)
583 !REAL, INTENT(OUT) :: x(:)
584 !LOGICAL, INTENT(IN) :: first
585 !INTEGER, INTENT(OUT) :: ier
586 !
587 !! Local variables
588 !INTEGER :: j, i, m
589 !REAL :: y, v
590 !INTEGER, SAVE :: n2
591 !
592 !IF (n < 1) THEN
593 ! WRITE(*, *) 'SIZE OF VECTOR IS NON POSITIVE'
594 ! STOP
595 !END IF
596 !
597 !ier = 0
598 !IF (first) THEN! Initialization, if necessary
599 ! n2 = 2*n
600 ! IF (d(1) < XZERO) THEN
601 ! ier = 1
602 ! RETURN
603 ! END IF
604 !
605 ! f(1) = SQRT(d(1))
606 ! y = XONE/f(1)
607 ! DO j = 2,n
608 ! f(j) = d(1+j*(j-1)/2) * y
609 ! END DO
610 !
611 ! DO i = 2,n
612 ! v = d(i*(i-1)/2+i)
613 ! DO m = 1,i-1
614 ! v = v - f((m-1)*(n2-m)/2+i)**2
615 ! END DO
616 !
617 ! IF (v < XZERO) THEN
618 ! ier = 1
619 ! RETURN
620 ! END IF
621 !
622 ! v = SQRT(v)
623 ! y = XONE/v
624 ! f((i-1)*(n2-i)/2+i) = v
625 ! DO j = i+1,n
626 ! v = d(j*(j-1)/2+i)
627 ! DO m = 1,i-1
628 ! v = v - f((m-1)*(n2-m)/2+i)*f((m-1)*(n2-m)/2 + j)
629 ! END DO ! m = 1,i-1
630 ! f((i-1)*(n2-i)/2 + j) = v*y
631 ! END DO ! j = i+1,n
632 ! END DO ! i = 2,n
633 !END IF
634 !
635 !x(1:n) = h(1:n)
636 !DO j = 1,n
637 ! y = random_normal()
638 ! DO i = j,n
639 ! x(i) = x(i) + f((j-1)*(n2-j)/2 + i) * y
640 ! END DO ! i = j,n
641 !END DO ! j = 1,n
642 !
643 !RETURN
644 !END SUBROUTINE random_mvnorm
645 !
646 !
647 !
648 !FUNCTION random_inv_gauss(h, b, first) RESULT(fn_val)
649 !
650 !! Adapted from Fortran 77 code from the book:
651 !! Dagpunar, J. 'Principles of random variate generation'
652 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
653 !
654 !! FUNCTION GENERATES A RANDOM VARIATE IN [0,INFINITY] FROM
655 !! A REPARAMETERISED GENERALISED INVERSE GAUSSIAN (GIG) DISTRIBUTION
656 !! WITH DENSITY PROPORTIONAL TO GIG**(H-1) * EXP(-0.5*B*(GIG+1/GIG))
657 !! USING A RATIO METHOD.
658 !
659 !! H = PARAMETER OF DISTRIBUTION (0 <= REAL)
660 !! B = PARAMETER OF DISTRIBUTION (0 < REAL)
661 !
662 !REAL, INTENT(IN) :: h, b
663 !LOGICAL, INTENT(IN) :: first
664 !REAL :: fn_val
665 !
666 !! Local variables
667 !REAL:: ym, xm, r, w, r1, r2, x
668 !REAL, SAVE :: a, c, d, e
669 !REAL, PARAMETER :: quart = 0.25
670 !
671 !IF (h < XZERO .OR. b <= XZERO) THEN
672 ! WRITE(*, *) 'IMPERMISSIBLE DISTRIBUTION PARAMETER VALUES'
673 ! STOP
674 !END IF
675 !
676 !IF (first) THEN! Initialization, if necessary
677 ! IF (h > quart*b*SQRT(XVLARGE)) THEN
678 ! WRITE(*, *) 'THE RATIO H:B IS TOO SMALL'
679 ! STOP
680 ! END IF
681 ! e = b*b
682 ! d = h + XONE
683 ! ym = (-d + SQRT(d*d + e))/b
684 ! IF (ym < XVSMALL) THEN
685 ! WRITE(*, *) 'THE VALUE OF B IS TOO SMALL'
686 ! STOP
687 ! END IF
688 !
689 ! d = h - XONE
690 ! xm = (d + SQRT(d*d + e))/b
691 ! d = XHALF*d
692 ! e = -quart*b
693 ! r = xm + XONE/xm
694 ! w = xm*ym
695 ! a = w**(-XHALF*h) * SQRT(xm/ym) * EXP(-e*(r - ym - XONE/ym))
696 ! IF (a < XVSMALL) THEN
697 ! WRITE(*, *) 'THE VALUE OF H IS TOO LARGE'
698 ! STOP
699 ! END IF
700 ! c = -d*LOG(xm) - e*r
701 !END IF
702 !
703 !DO
704 ! CALL RANDOM_NUMBER(r1)
705 ! IF (r1 <= XZERO) CYCLE
706 ! CALL RANDOM_NUMBER(r2)
707 ! x = a*r2/r1
708 ! IF (x <= XZERO) CYCLE
709 ! IF (LOG(r1) < d*LOG(x) + e*(x + XONE/x) + c) EXIT
710 !END DO
711 !
712 !fn_val = x
713 !
714 !RETURN
715 !END FUNCTION random_inv_gauss
716 !
717 !
718 !
719 !FUNCTION random_Poisson(mu, first) RESULT(ival)
720 !!**********************************************************************
721 !! Translated to Fortran 90 by Alan Miller from:
722 !! RANLIB
723 !!
724 !! Library of Fortran Routines for Random Number Generation
725 !!
726 !! Compiled and Written by:
727 !!
728 !! Barry W. Brown
729 !! James Lovato
730 !!
731 !! Department of Biomathematics, Box 237
732 !! The University of Texas, M.D. Anderson Cancer Center
733 !! 1515 Holcombe Boulevard
734 !! Houston, TX 77030
735 !!
736 !! This work was supported by grant CA-16672 from the National Cancer Institute.
737 !
738 !! GENerate POIsson random deviate
739 !
740 !! Function
741 !
742 !! Generates a single random deviate from a Poisson distribution with mean mu.
743 !
744 !! Arguments
745 !
746 !! mu --> The mean of the Poisson distribution from which
747 !!a random deviate is to be generated.
748 !! REAL mu
749 !
750 !! Method
751 !
752 !! For details see:
753 !
754 !! Ahrens, J.H. and Dieter, U.
755 !! Computer Generation of Poisson Deviates
756 !! From Modified Normal Distributions.
757 !! ACM Trans. Math. Software, 8, 2
758 !! (June 1982),163-179
759 !
760 !! TABLES: COEFFICIENTS A0-A7 FOR STEP F. FACTORIALS FACT
761 !! COEFFICIENTS A(K) - FOR PX = FK*V*V*SUM(A(K)*V**K)-DEL
762 !
763 !! SEPARATION OF CASES A AND B
764 !
765 !! .. Scalar Arguments ..
766 !REAL, INTENT(IN) :: mu
767 !LOGICAL, INTENT(IN) :: first
768 !INTEGER :: ival
769 !! ..
770 !! .. Local Scalars ..
771 !REAL :: b1, b2, c, c0, c1, c2, c3, del, difmuk, e, fk, fx, fy, g, &
772 ! omega, px, py, t, u, v, x, xx
773 !REAL, SAVE :: s, d, p, q, p0
774 !INTEGER :: j, k, kflag
775 !LOGICAL, SAVE :: full_init
776 !INTEGER, SAVE :: l, m
777 !! ..
778 !! .. Local Arrays ..
779 !REAL, SAVE :: pp(35)
780 !! ..
781 !! .. Data statements ..
782 !REAL, PARAMETER :: a0 = -.5, a1 = .3333333, a2 = -.2500068, a3 = .2000118, &
783 ! a4 = -.1661269, a5 = .1421878, a6 = -.1384794, &
784 ! a7 = .1250060
785 !
786 !REAL, PARAMETER :: fact(10) = (/ 1., 1., 2., 6., 24., 120., 720., 5040., &
787 ! 40320., 362880. /)
788 !
789 !! ..
790 !! .. Executable Statements ..
791 !IF (mu > 10.0) THEN
792 !! C A S E A. (RECALCULATION OF S, D, L IF MU HAS CHANGED)
793 !
794 ! IF (first) THEN
795 ! s = SQRT(mu)
796 ! d = 6.0*mu*mu
797 !
798 !! THE POISSON PROBABILITIES PK EXCEED THE DISCRETE NORMAL
799 !! PROBABILITIES FK WHENEVER K >= M(MU). L=IFIX(MU-1.1484)
800 !! IS AN UPPER BOUND TO M(MU) FOR ALL MU >= 10 .
801 !
802 ! l = mu - 1.1484
803 ! full_init = .false.
804 ! END IF
805 !
806 !
807 !! STEP N. NORMAL SAMPLE - random_normal() FOR STANDARD NORMAL DEVIATE
808 !
809 ! g = mu + s*random_normal()
810 ! IF (g > 0.0) THEN
811 ! ival = g
812 !
813 !! STEP I. IMMEDIATE ACCEPTANCE IF ival IS LARGE ENOUGH
814 !
815 ! IF (ival>=l) RETURN
816 !
817 !! STEP S. SQUEEZE ACCEPTANCE - SAMPLE U
818 !
819 ! fk = ival
820 ! difmuk = mu - fk
821 ! CALL RANDOM_NUMBER(u)
822 ! IF (d*u >= difmuk*difmuk*difmuk) RETURN
823 ! END IF
824 !
825 !! STEP P. PREPARATIONS FOR STEPS Q AND H.
826 !! (RECALCULATIONS OF PARAMETERS IF NECESSARY)
827 !! .3989423=(2*PI)**(-.5) .416667E-1=1./24. .1428571=1./7.
828 !! THE QUANTITIES B1, B2, C3, C2, C1, C0 ARE FOR THE HERMITE
829 !! APPROXIMATIONS TO THE DISCRETE NORMAL PROBABILITIES FK.
830 !! C=.1069/MU GUARANTEES MAJORIZATION BY THE 'HAT'-FUNCTION.
831 !
832 ! IF (.NOT. full_init) THEN
833 ! omega = .3989423/s
834 ! b1 = .4166667E-1/mu
835 ! b2 = .3*b1*b1
836 ! c3 = .1428571*b1*b2
837 ! c2 = b2 - 15.*c3
838 ! c1 = b1 - 6.*b2 + 45.*c3
839 ! c0 = 1. - b1 + 3.*b2 - 15.*c3
840 ! c = .1069/mu
841 ! full_init = .true.
842 ! END IF
843 !
844 ! IF (g < 0.0) GO TO 50
845 !
846 !! 'SUBROUTINE' F IS CALLED (KFLAG=0 FOR CORRECT RETURN)
847 !
848 ! kflag = 0
849 ! GO TO 70
850 !
851 !! STEP Q. QUOTIENT ACCEPTANCE (RARE CASE)
852 !
853 ! 40 IF (fy-u*fy <= py*EXP(px-fx)) RETURN
854 !
855 !! STEP E. EXPONENTIAL SAMPLE - random_exponential() FOR STANDARD EXPONENTIAL
856 !! DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT'
857 !! (IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.)
858 !
859 ! 50 e = random_exponential()
860 ! CALL RANDOM_NUMBER(u)
861 ! u = u + u - XONE
862 ! t = 1.8 + SIGN(e, u)
863 ! IF (t <= (-.6744)) GO TO 50
864 ! ival = mu + s*t
865 ! fk = ival
866 ! difmuk = mu - fk
867 !
868 !! 'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN)
869 !
870 ! kflag = 1
871 ! GO TO 70
872 !
873 !! STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION)
874 !
875 ! 60 IF (c*ABS(u) > py*EXP(px+e) - fy*EXP(fx+e)) GO TO 50
876 ! RETURN
877 !
878 !! STEP F. 'SUBROUTINE' F. CALCULATION OF PX, PY, FX, FY.
879 !! CASE ival < 10 USES FACTORIALS FROM TABLE FACT
880 !
881 ! 70 IF (ival>=10) GO TO 80
882 ! px = -mu
883 ! py = mu**ival/fact(ival+1)
884 ! GO TO 110
885 !
886 !! CASE ival >= 10 USES POLYNOMIAL APPROXIMATION
887 !! A0-A7 FOR ACCURACY WHEN ADVISABLE
888 !! .8333333E-1=1./12. .3989423=(2*PI)**(-.5)
889 !
890 ! 80 del = .8333333E-1/fk
891 ! del = del - 4.8*del*del*del
892 ! v = difmuk/fk
893 ! IF (ABS(v)>0.25) THEN
894 ! px = fk*LOG(XONE + v) - difmuk - del
895 ! ELSE
896 ! px = fk*v*v* (((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0) - del
897 ! END IF
898 ! py = .3989423/SQRT(fk)
899 ! 110 x = (XHALF - difmuk)/s
900 ! xx = x*x
901 ! fx = -XHALF*xx
902 ! fy = omega* (((c3*xx + c2)*xx + c1)*xx + c0)
903 ! IF (kflag <= 0) GO TO 40
904 ! GO TO 60
905 !
906 !!---------------------------------------------------------------------------
907 !! C A S E B. mu < 10
908 !! START NEW TABLE AND CALCULATE P0 IF NECESSARY
909 !
910 !ELSE
911 ! IF (first) THEN
912 ! m = MAX(1, INT(mu))
913 ! l = 0
914 ! p = EXP(-mu)
915 ! q = p
916 ! p0 = p
917 ! END IF
918 !
919 !! STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
920 !
921 ! DO
922 ! CALL RANDOM_NUMBER(u)
923 ! ival = 0
924 ! IF (u <= p0) RETURN
925 !
926 !! STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE
927 !! PP-TABLE OF CUMULATIVE POISSON PROBABILITIES
928 !! (0.458=PP(9) FOR MU=10)
929 !
930 ! IF (l == 0) GO TO 150
931 ! j = 1
932 ! IF (u > 0.458) j = MIN(l, m)
933 ! DO k = j, l
934 ! IF (u <= pp(k)) GO TO 180
935 ! END DO
936 ! IF (l == 35) CYCLE
937 !
938 !! STEP C. CREATION OF NEW POISSON PROBABILITIES P
939 !! AND THEIR CUMULATIVES Q=PP(K)
940 !
941 ! 150 l = l + 1
942 ! DO k = l, 35
943 ! p = p*mu / k
944 ! q = q + p
945 ! pp(k) = q
946 ! IF (u <= q) GO TO 170
947 ! END DO
948 ! l = 35
949 ! END DO
950 !
951 ! 170 l = k
952 ! 180 ival = k
953 ! RETURN
954 !END IF
955 !
956 !RETURN
957 !END FUNCTION random_Poisson
958 !
959 !
960 !
961 !FUNCTION random_binomial1(n, p, first) RESULT(ival)
962 !
963 !! FUNCTION GENERATES A RANDOM BINOMIAL VARIATE USING C.D.Kemp's method.
964 !! This algorithm is suitable when many random variates are required
965 !! with the SAME parameter values for n & p.
966 !
967 !! P = BERNOULLI SUCCESS PROBABILITY
968 !! (0 <= REAL <= 1)
969 !! N = NUMBER OF BERNOULLI TRIALS
970 !! (1 <= INTEGER)
971 !! FIRST = .TRUE. for the first call using the current parameter values
972 !! = .FALSE. if the values of (n,p) are unchanged from last call
973 !
974 !! Reference: Kemp, C.D. (1986). `A modal method for generating binomial
975 !!variables', Commun. Statist. - Theor. Meth. 15(3), 805-813.
976 !
977 !INTEGER, INTENT(IN) :: n
978 !REAL, INTENT(IN) :: p
979 !LOGICAL, INTENT(IN) :: first
980 !INTEGER :: ival
981 !
982 !! Local variables
983 !
984 !INTEGER :: ru, rd
985 !INTEGER, SAVE :: r0
986 !REAL:: u, pd, pu
987 !REAL, SAVE :: odds_ratio, p_r
988 !REAL, PARAMETER :: ZZERO = 0.0, ZONE = 1.0
989 !
990 !IF (first) THEN
991 ! r0 = (n+1)*p
992 ! p_r = bin_prob(n, p, r0)
993 ! odds_ratio = p / (ZONE - p)
994 !END IF
995 !
996 !CALL RANDOM_NUMBER(u)
997 !u = u - p_r
998 !IF (u < ZZERO) THEN
999 ! ival = r0
1000 ! RETURN
1001 !END IF
1002 !
1003 !pu = p_r
1004 !ru = r0
1005 !pd = p_r
1006 !rd = r0
1007 !DO
1008 ! rd = rd - 1
1009 ! IF (rd >= 0) THEN
1010 ! pd = pd * (rd+1) / (odds_ratio * (n-rd))
1011 ! u = u - pd
1012 ! IF (u < ZZERO) THEN
1013 ! ival = rd
1014 ! RETURN
1015 ! END IF
1016 ! END IF
1017 !
1018 ! ru = ru + 1
1019 ! IF (ru <= n) THEN
1020 ! pu = pu * (n-ru+1) * odds_ratio / ru
1021 ! u = u - pu
1022 ! IF (u < ZZERO) THEN
1023 ! ival = ru
1024 ! RETURN
1025 ! END IF
1026 ! END IF
1027 !END DO
1028 !
1029 !! This point should not be reached, but just in case:
1030 !
1031 !ival = r0
1032 !RETURN
1033 !
1034 !END FUNCTION random_binomial1
1035 !
1036 !
1037 !
1038 !FUNCTION bin_prob(n, p, r) RESULT(fn_val)
1039 !! Calculate a binomial probability
1040 !
1041 !INTEGER, INTENT(IN) :: n, r
1042 !REAL, INTENT(IN) :: p
1043 !REAL :: fn_val
1044 !
1045 !! Local variable
1046 !REAL :: ZONE = 1.0
1047 !
1048 !fn_val = EXP( lngamma(DBLE(n+1)) - lngamma(DBLE(r+1)) - lngamma(DBLE(n-r+1)) &
1049 ! + r*LOG(p) + (n-r)*LOG(ZONE - p) )
1050 !RETURN
1051 !
1052 !END FUNCTION bin_prob
1053 !
1054 !
1055 !
1056 !FUNCTION lngamma(x) RESULT(fn_val)
1057 !
1058 !! Logarithm to base e of the gamma function.
1059 !!
1060 !! Accurate to about 1.e-14.
1061 !! Programmer: Alan Miller
1062 !
1063 !! Latest revision of Fortran 77 version - 28 February 1988
1064 !
1065 !REAL (IDP), INTENT(IN) :: x
1066 !REAL (IDP) :: fn_val
1067 !
1068 !! Local variables
1069 !
1070 !REAL (IDP) :: a1 = -4.166666666554424D-02, a2 = 2.430554511376954D-03, &
1071 ! a3 = -7.685928044064347D-04, a4 = 5.660478426014386D-04, &
1072 ! temp, arg, product, lnrt2pi = 9.189385332046727D-1, &
1073 ! pi = 3.141592653589793D0
1074 !LOGICAL :: reflect
1075 !
1076 !! lngamma is not defined if x = 0 or a negative integer.
1077 !
1078 !IF (x > 0.d0) GO TO 10
1079 !IF (x /= INT(x)) GO TO 10
1080 !fn_val = 0.d0
1081 !RETURN
1082 !
1083 !! If x < 0, use the reflection formula:
1084 !! gamma(x) * gamma(1-x) = pi * cosec(pi.x)
1085 !
1086 !10 reflect = (x < 0.d0)
1087 !IF (reflect) THEN
1088 ! arg = 1.d0 - x
1089 !ELSE
1090 ! arg = x
1091 !END IF
1092 !
1093 !! Increase the argument, if necessary, to make it > 10.
1094 !
1095 !product = 1.d0
1096 !20 IF (arg <= 10.d0) THEN
1097 ! product = product * arg
1098 ! arg = arg + 1.d0
1099 ! GO TO 20
1100 !END IF
1101 !
1102 !! Use a polynomial approximation to Stirling's formula.
1103 !! N.B. The real Stirling's formula is used here, not the simpler, but less
1104 !! accurate formula given by De Moivre in a letter to Stirling, which
1105 !! is the one usually quoted.
1106 !
1107 !arg = arg - 0.5D0
1108 !temp = 1.d0/arg**2
1109 !fn_val = lnrt2pi + arg * (LOG(arg) - 1.d0 + &
1110 ! (((a4*temp + a3)*temp + a2)*temp + a1)*temp) - LOG(product)
1111 !IF (reflect) THEN
1112 ! temp = SIN(pi * x)
1113 ! fn_val = LOG(pi/temp) - fn_val
1114 !END IF
1115 !RETURN
1116 !END FUNCTION lngamma
1117 !
1118 !
1119 !
1120 !FUNCTION random_binomial2(n, pp, first) RESULT(ival)
1121 !!**********************************************************************
1122 !! Translated to Fortran 90 by Alan Miller from:
1123 !! RANLIB
1124 !!
1125 !! Library of Fortran Routines for Random Number Generation
1126 !!
1127 !! Compiled and Written by:
1128 !!
1129 !! Barry W. Brown
1130 !! James Lovato
1131 !!
1132 !! Department of Biomathematics, Box 237
1133 !! The University of Texas, M.D. Anderson Cancer Center
1134 !! 1515 Holcombe Boulevard
1135 !! Houston, TX 77030
1136 !!
1137 !! This work was supported by grant CA-16672 from the National Cancer Institute.
1138 !
1139 !! GENerate BINomial random deviate
1140 !
1141 !! Function
1142 !
1143 !! Generates a single random deviate from a binomial
1144 !! distribution whose number of trials is N and whose
1145 !! probability of an event in each trial is P.
1146 !
1147 !! Arguments
1148 !
1149 !! N --> The number of trials in the binomial distribution
1150 !!from which a random deviate is to be generated.
1151 !! INTEGER N
1152 !
1153 !! P --> The probability of an event in each trial of the
1154 !!binomial distribution from which a random deviate
1155 !!is to be generated.
1156 !! REAL P
1157 !
1158 !! FIRST --> Set FIRST = .TRUE. for the first call to perform initialization
1159 !! the set FIRST = .FALSE. for further calls using the same pair
1160 !! of parameter values (N, P).
1161 !! LOGICAL FIRST
1162 !
1163 !! random_binomial2 <-- A random deviate yielding the number of events
1164 !! from N independent trials, each of which has
1165 !! a probability of event P.
1166 !! INTEGER random_binomial
1167 !
1168 !! Method
1169 !
1170 !! This is algorithm BTPE from:
1171 !
1172 !! Kachitvichyanukul, V. and Schmeiser, B. W.
1173 !! Binomial Random Variate Generation.
1174 !! Communications of the ACM, 31, 2 (February, 1988) 216.
1175 !
1176 !!**********************************************************************
1177 !
1178 !!*****DETERMINE APPROPRIATE ALGORITHM AND WHETHER SETUP IS NECESSARY
1179 !
1180 !! ..
1181 !! .. Scalar Arguments ..
1182 !REAL, INTENT(IN) :: pp
1183 !INTEGER, INTENT(IN) :: n
1184 !LOGICAL, INTENT(IN) :: first
1185 !INTEGER :: ival
1186 !! ..
1187 !! .. Local Scalars ..
1188 !REAL:: alv, amaxp, f, f1, f2, u, v, w, w2, x, x1, x2, ynorm, z, z2
1189 !REAL, PARAMETER :: ZZERO = 0.0, ZHALF = 0.5, ZONE = 1.0
1190 !INTEGER :: i, ix, ix1, k, mp
1191 !INTEGER, SAVE :: m
1192 !REAL, SAVE :: p, q, xnp, ffm, fm, xnpq, p1, xm, xl, xr, c, al, xll, &
1193 ! xlr, p2, p3, p4, qn, r, g
1194 !
1195 !! ..
1196 !! .. Executable Statements ..
1197 !
1198 !!*****SETUP, PERFORM ONLY WHEN PARAMETERS CHANGE
1199 !
1200 !IF (first) THEN
1201 ! p = MIN(pp, ZONE-pp)
1202 ! q = ZONE - p
1203 ! xnp = n * p
1204 !END IF
1205 !
1206 !IF (xnp > 30.) THEN
1207 ! IF (first) THEN
1208 ! ffm = xnp + p
1209 ! m = ffm
1210 ! fm = m
1211 ! xnpq = xnp * q
1212 ! p1 = INT(2.195*SQRT(xnpq) - 4.6*q) + ZHALF
1213 ! xm = fm + ZHALF
1214 ! xl = xm - p1
1215 ! xr = xm + p1
1216 ! c = 0.134 + 20.5 / (15.3 + fm)
1217 ! al = (ffm-xl) / (ffm - xl*p)
1218 ! xll = al * (ZONE + ZHALF*al)
1219 ! al = (xr - ffm) / (xr*q)
1220 ! xlr = al * (ZONE + ZHALF*al)
1221 ! p2 = p1 * (ZONE + c + c)
1222 ! p3 = p2 + c / xll
1223 ! p4 = p3 + c / xlr
1224 ! END IF
1225 !
1226 !!*****GENERATE VARIATE, Binomial mean at least 30.
1227 !
1228 ! 20 CALL RANDOM_NUMBER(u)
1229 ! u = u * p4
1230 ! CALL RANDOM_NUMBER(v)
1231 !
1232 !! TRIANGULAR REGION
1233 !
1234 ! IF (u <= p1) THEN
1235 ! ix = xm - p1 * v + u
1236 ! GO TO 110
1237 ! END IF
1238 !
1239 !! PARALLELOGRAM REGION
1240 !
1241 ! IF (u <= p2) THEN
1242 ! x = xl + (u-p1) / c
1243 ! v = v * c + ZONE - ABS(xm-x) / p1
1244 ! IF (v > ZONE .OR. v <= ZZERO) GO TO 20
1245 ! ix = x
1246 ! ELSE
1247 !
1248 !! LEFT TAIL
1249 !
1250 ! IF (u <= p3) THEN
1251 ! ix = xl + LOG(v) / xll
1252 ! IF (ix < 0) GO TO 20
1253 ! v = v * (u-p2) * xll
1254 ! ELSE
1255 !
1256 !! RIGHT TAIL
1257 !
1258 ! ix = xr - LOG(v) / xlr
1259 ! IF (ix > n) GO TO 20
1260 ! v = v * (u-p3) * xlr
1261 ! END IF
1262 ! END IF
1263 !
1264 !!*****DETERMINE APPROPRIATE WAY TO PERFORM ACCEPT/REJECT TEST
1265 !
1266 ! k = ABS(ix-m)
1267 ! IF (k <= 20 .OR. k >= xnpq/2-1) THEN
1268 !
1269 !! EXPLICIT EVALUATION
1270 !
1271 ! f = ZONE
1272 ! r = p / q
1273 ! g = (n+1) * r
1274 ! IF (m < ix) THEN
1275 ! mp = m + 1
1276 ! DO i = mp, ix
1277 ! f = f * (g/i-r)
1278 ! END DO
1279 !
1280 ! ELSE IF (m > ix) THEN
1281 ! ix1 = ix + 1
1282 ! DO i = ix1, m
1283 ! f = f / (g/i-r)
1284 ! END DO
1285 ! END IF
1286 !
1287 ! IF (v > f) THEN
1288 ! GO TO 20
1289 ! ELSE
1290 ! GO TO 110
1291 ! END IF
1292 ! END IF
1293 !
1294 !! SQUEEZING USING UPPER AND LOWER BOUNDS ON LOG(F(X))
1295 !
1296 ! amaxp = (k/xnpq) * ((k*(k/3. + .625) + .1666666666666)/xnpq + ZHALF)
1297 ! ynorm = -k * k / (2.*xnpq)
1298 ! alv = LOG(v)
1299 ! IF (alv<ynorm - amaxp) GO TO 110
1300 ! IF (alv>ynorm + amaxp) GO TO 20
1301 !
1302 !! STIRLING'S (actually de Moivre's) FORMULA TO MACHINE ACCURACY FOR
1303 !! THE FINAL ACCEPTANCE/REJECTION TEST
1304 !
1305 ! x1 = ix + 1
1306 ! f1 = fm + ZONE
1307 ! z = n + 1 - fm
1308 ! w = n - ix + ZONE
1309 ! z2 = z * z
1310 ! x2 = x1 * x1
1311 ! f2 = f1 * f1
1312 ! w2 = w * w
1313 ! IF (alv - (xm*LOG(f1/x1) + (n-m+ZHALF)*LOG(z/w) + (ix-m)*LOG(w*p/(x1*q)) + &
1314 ! (13860.-(462.-(132.-(99.-140./f2)/f2)/f2)/f2)/f1/166320. + &
1315 ! (13860.-(462.-(132.-(99.-140./z2)/z2)/z2)/z2)/z/166320. + &
1316 ! (13860.-(462.-(132.-(99.-140./x2)/x2)/x2)/x2)/x1/166320. + &
1317 ! (13860.-(462.-(132.-(99.-140./w2)/w2)/w2)/w2)/w/166320.) > ZZERO) THEN
1318 ! GO TO 20
1319 ! ELSE
1320 ! GO TO 110
1321 ! END IF
1322 !
1323 !ELSE
1324 !! INVERSE CDF LOGIC FOR MEAN LESS THAN 30
1325 ! IF (first) THEN
1326 ! qn = q ** n
1327 ! r = p / q
1328 ! g = r * (n+1)
1329 ! END IF
1330 !
1331 ! 90 ix = 0
1332 ! f = qn
1333 ! CALL RANDOM_NUMBER(u)
1334 ! 100 IF (u >= f) THEN
1335 ! IF (ix > 110) GO TO 90
1336 ! u = u - f
1337 ! ix = ix + 1
1338 ! f = f * (g/ix - r)
1339 ! GO TO 100
1340 ! END IF
1341 !END IF
1342 !
1343 !110 IF (pp > ZHALF) ix = n - ix
1344 !ival = ix
1345 !RETURN
1346 !
1347 !END FUNCTION random_binomial2
1348 !
1349 !
1350 !
1351 !
1352 !FUNCTION random_neg_binomial(sk, p) RESULT(ival)
1353 !
1354 !! Adapted from Fortran 77 code from the book:
1355 !! Dagpunar, J. 'Principles of random variate generation'
1356 !! Clarendon Press, Oxford, 1988. ISBN 0-19-852202-9
1357 !
1358 !! FUNCTION GENERATES A RANDOM NEGATIVE BINOMIAL VARIATE USING UNSTORED
1359 !! INVERSION AND/OR THE REPRODUCTIVE PROPERTY.
1360 !
1361 !! SK = NUMBER OF FAILURES REQUIRED (Dagpunar's words!)
1362 !! = the `power' parameter of the negative binomial
1363 !! (0 < REAL)
1364 !! P = BERNOULLI SUCCESS PROBABILITY
1365 !! (0 < REAL < 1)
1366 !
1367 !! THE PARAMETER H IS SET SO THAT UNSTORED INVERSION ONLY IS USED WHEN P <= H,
1368 !! OTHERWISE A COMBINATION OF UNSTORED INVERSION AND
1369 !! THE REPRODUCTIVE PROPERTY IS USED.
1370 !
1371 !REAL, INTENT(IN) :: sk, p
1372 !INTEGER:: ival
1373 !
1374 !! Local variables
1375 !! THE PARAMETER ULN = -LOG(MACHINE'S SMALLEST REAL NUMBER).
1376 !
1377 !REAL, PARAMETER :: h = 0.7
1378 !REAL :: q, x, st, uln, v, r, s, y, g
1379 !INTEGER:: k, i, n
1380 !
1381 !IF (sk <= XZERO .OR. p <= XZERO .OR. p >= XONE) THEN
1382 ! WRITE(*, *) 'IMPERMISSIBLE DISTRIBUTION PARAMETER VALUES'
1383 ! STOP
1384 !END IF
1385 !
1386 !q = XONE - p
1387 !x = XZERO
1388 !st = sk
1389 !IF (p > h) THEN
1390 ! v = XONE/LOG(p)
1391 ! k = st
1392 ! DO i = 1,k
1393 ! DO
1394 ! CALL RANDOM_NUMBER(r)
1395 ! IF (r > XZERO) EXIT
1396 ! END DO
1397 ! n = v*LOG(r)
1398 ! x = x + n
1399 ! END DO
1400 ! st = st - k
1401 !END IF
1402 !
1403 !s = XZERO
1404 !uln = -LOG(XVSMALL)
1405 !IF (st > -uln/LOG(q)) THEN
1406 ! WRITE(*, *) ' P IS TOO LARGE FOR THIS VALUE OF SK'
1407 ! STOP
1408 !END IF
1409 !
1410 !y = q**st
1411 !g = st
1412 !CALL RANDOM_NUMBER(r)
1413 !DO
1414 ! IF (y > r) EXIT
1415 ! r = r - y
1416 ! s = s + XONE
1417 ! y = y*p*g/s
1418 ! g = g + XONE
1419 !END DO
1420 !
1421 !ival = x + s + XHALF
1422 !RETURN
1423 !END FUNCTION random_neg_binomial
1424 !
1425 !
1426 !
1427 !FUNCTION random_von_Mises(k, first) RESULT(fn_val)
1428 !
1429 !! Algorithm VMD from:
1430 !! Dagpunar, J.S. (1990) `Sampling from the von Mises distribution via a
1431 !! comparison of random numbers', J. of Appl. Statist., 17, 165-168.
1432 !
1433 !! Fortran 90 code by Alan Miller
1434 !! CSIRO Division of Mathematical & Information Sciences
1435 !
1436 !! Arguments:
1437 !! k (real) parameter of the von Mises distribution.
1438 !! first (logical) set to .TRUE. the first time that the function
1439 !! is called, or the first time with a new value
1440 !! for k. When first = .TRUE., the function sets
1441 !! up starting values and may be very much slower.
1442 !
1443 !REAL, INTENT(IN) :: k
1444 !LOGICAL, INTENT(IN) :: first
1445 !REAL :: fn_val
1446 !
1447 !! Local variables
1448 !
1449 !INTEGER :: j, n
1450 !INTEGER, SAVE :: nk
1451 !REAL, PARAMETER :: pi = 3.14159265
1452 !REAL, SAVE :: p(20), theta(0:20)
1453 !REAL :: sump, r, th, lambda, rlast
1454 !REAL (IDP) :: dk
1455 !
1456 !IF (first) THEN! Initialization, if necessary
1457 ! IF (k < XZERO) THEN
1458 ! WRITE(*, *) '** Error: argument k for random_von_Mises = ', k
1459 ! RETURN
1460 ! END IF
1461 !
1462 ! nk = k + k + XONE
1463 ! IF (nk > 20) THEN
1464 ! WRITE(*, *) '** Error: argument k for random_von_Mises = ', k
1465 ! RETURN
1466 ! END IF
1467 !
1468 ! dk = k
1469 ! theta(0) = XZERO
1470 ! IF (k > XHALF) THEN
1471 !
1472 !! Set up array p of probabilities.
1473 !
1474 ! sump = XZERO
1475 ! DO j = 1, nk
1476 ! IF (j < nk) THEN
1477 ! theta(j) = ACOS(XONE - j/k)
1478 ! ELSE
1479 ! theta(nk) = pi
1480 ! END IF
1481 !
1482 !! Numerical integration of e^[k.cos(x)] from theta(j-1) to theta(j)
1483 !
1484 ! CALL integral(theta(j-1), theta(j), p(j), dk)
1485 ! sump = sump + p(j)
1486 ! END DO
1487 ! p(1:nk) = p(1:nk) / sump
1488 ! ELSE
1489 ! p(1) = XONE
1490 ! theta(1) = pi
1491 ! END IF ! if k > 0.5
1492 !END IF ! if first
1493 !
1494 !CALL RANDOM_NUMBER(r)
1495 !DO j = 1, nk
1496 ! r = r - p(j)
1497 ! IF (r < XZERO) EXIT
1498 !END DO
1499 !r = -r/p(j)
1500 !
1501 !DO
1502 ! th = theta(j-1) + r*(theta(j) - theta(j-1))
1503 ! lambda = k - j + XONE - k*COS(th)
1504 ! n = 1
1505 ! rlast = lambda
1506 !
1507 ! DO
1508 ! CALL RANDOM_NUMBER(r)
1509 ! IF (r > rlast) EXIT
1510 ! n = n + 1
1511 ! rlast = r
1512 ! END DO
1513 !
1514 ! IF (n .NE. 2*(n/2)) EXIT ! is n even?
1515 ! CALL RANDOM_NUMBER(r)
1516 !END DO
1517 !
1518 !fn_val = SIGN(th, (r - rlast)/(XONE - rlast) - XHALF)
1519 !RETURN
1520 !END FUNCTION random_von_Mises
1521 !
1522 !
1523 !
1524 !SUBROUTINE integral(a, b, result, dk)
1525 !
1526 !! Gaussian integration of exp(k.cosx) from a to b.
1527 !
1528 !REAL (IDP), INTENT(IN) :: dk
1529 !REAL, INTENT(IN) :: a, b
1530 !REAL, INTENT(OUT) :: result
1531 !
1532 !! Local variables
1533 !
1534 !REAL (IDP) :: xmid, range, x1, x2,&
1535 ! x(3) = (/0.238619186083197_IDP, 0.661209386466265_IDP, 0.932469514203152_IDP/), &
1536 ! w(3) = (/0.467913934572691_IDP, 0.360761573048139_IDP, 0.171324492379170_IDP/)
1537 !INTEGER :: i
1538 !
1539 !xmid = (a + b)/2._IDP
1540 !range = (b - a)/2._IDP
1541 !
1542 !result = 0._IDP
1543 !DO i = 1, 3
1544 ! x1 = xmid + x(i)*range
1545 ! x2 = xmid - x(i)*range
1546 ! result = result + w(i)*(EXP(dk*COS(x1)) + EXP(dk*COS(x2)))
1547 !END DO
1548 !
1549 !result = result * range
1550 !RETURN
1551 !END SUBROUTINE integral
1552 !
1553 !
1554 !
1555 !FUNCTION random_Cauchy() RESULT(fn_val)
1556 !
1557 !! Generate a random deviate from the standard Cauchy distribution
1558 !
1559 !REAL :: fn_val
1560 !
1561 !! Local variables
1562 !REAL :: v(2)
1563 !
1564 !DO
1565 ! CALL RANDOM_NUMBER(v)
1566 ! v = XTWO*(v - XHALF)
1567 ! IF (ABS(v(2)) < XVSMALL) CYCLE ! Test for zero
1568 ! IF (v(1)**2 + v(2)**2 < XONE) EXIT
1569 !END DO
1570 !fn_val = v(1) / v(2)
1571 !
1572 !RETURN
1573 !END FUNCTION random_Cauchy
1574 !
1575 !
1576 !
1577 !SUBROUTINE random_order(order, n)
1578 !
1579 !! Generate a random ordering of the integers 1 ... n.
1580 !
1581 !INTEGER, INTENT(IN) :: n
1582 !INTEGER, INTENT(OUT) :: order(n)
1583 !
1584 !! Local variables
1585 !
1586 !INTEGER :: i, j, k
1587 !REAL :: wk
1588 !
1589 !DO i = 1, n
1590 ! order(i) = i
1591 !END DO
1592 !
1593 !! Starting at the end, swap the current last indicator with one
1594 !! randomly chosen from those preceeding it.
1595 !
1596 !DO i = n, 2, -1
1597 ! CALL RANDOM_NUMBER(wk)
1598 ! j = 1 + i * wk
1599 ! IF (j < i) THEN
1600 ! k = order(i)
1601 ! order(i) = order(j)
1602 ! order(j) = k
1603 ! END IF
1604 !END DO
1605 !
1606 !RETURN
1607 !END SUBROUTINE random_order
1608 !
1609 !
1610 !
1611 !SUBROUTINE seed_random_number(iounit)
1612 !
1613 !INTEGER, INTENT(IN) :: iounit
1614 !
1615 !! Local variables
1616 !
1617 !INTEGER :: k
1618 !INTEGER, ALLOCATABLE :: seed(:)
1619 !
1620 !CALL RANDOM_SEED(SIZE=k)
1621 !ALLOCATE( seed(k) )
1622 !
1623 !WRITE(*, '(a, i2, a)')' Enter ', k, ' integers for random no. seeds: '
1624 !READ(*, *) seed
1625 !WRITE(iounit, '(a, (7i10))') ' Random no. seeds: ', seed
1626 !CALL RANDOM_SEED(PUT=seed)
1627 !
1628 !DEALLOCATE( seed )
1629 !
1630 !RETURN
1631 !END SUBROUTINE seed_random_number
1632 !
1633 !
1634 END MODULE mode_random
real function random_normal()
subroutine init_random_seed()