56#include "../base/base_uses.f90"
64 CHARACTER(LEN=*),
PARAMETER,
PRIVATE :: rng_record_format =
"(A40,I2,3L2,ES25.16,18F20.1)"
76 REAL(kind=
dp),
PARAMETER :: norm = 2.328306549295727688e-10_dp, &
77 m1 = 4294967087.0_dp, &
78 m2 = 4294944443.0_dp, &
82 a23n = 1370589.0_dp, &
83 two17 = 131072.0_dp, &
84 two53 = 9007199254740992.0_dp, &
85 fact = 5.9604644775390625e-8_dp
92 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: a1p0 = reshape([ &
93 0.0_dp, 0.0_dp, -810728.0_dp, &
94 1.0_dp, 0.0_dp, 1403580.0_dp, &
95 0.0_dp, 1.0_dp, 0.0_dp &
99 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: a2p0 = reshape([ &
100 0.0_dp, 0.0_dp, -1370589.0_dp, &
101 1.0_dp, 0.0_dp, 0.0_dp, &
102 0.0_dp, 1.0_dp, 527612.0_dp &
106 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: a1p76 = reshape([ &
107 82758667.0_dp, 3672831523.0_dp, 3672091415.0_dp, &
108 1871391091.0_dp, 69195019.0_dp, 3528743235.0_dp, &
109 4127413238.0_dp, 1871391091.0_dp, 69195019.0_dp &
113 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: a2p76 = reshape([ &
114 1511326704.0_dp, 4292754251.0_dp, 3859662829.0_dp, &
115 3759209742.0_dp, 1511326704.0_dp, 4292754251.0_dp, &
116 1610795712.0_dp, 3889917532.0_dp, 3708466080.0_dp &
120 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: a1p127 = reshape([ &
121 2427906178.0_dp, 226153695.0_dp, 1988835001.0_dp, &
122 3580155704.0_dp, 1230515664.0_dp, 986791581.0_dp, &
123 949770784.0_dp, 3580155704.0_dp, 1230515664.0_dp &
127 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: a2p127 = reshape([ &
128 1464411153.0_dp, 32183930.0_dp, 2824425944.0_dp, &
129 277697599.0_dp, 1464411153.0_dp, 32183930.0_dp, &
130 1610723613.0_dp, 1022607788.0_dp, 2093834863.0_dp &
134 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: inv_a1 = reshape([ &
135 184888585.0_dp, 1.0_dp, 0.0_dp, &
136 0.0_dp, 0.0_dp, 1.0_dp, &
137 1945170933.0_dp, 0.0_dp, 0.0_dp &
141 REAL(kind=
dp),
DIMENSION(3, 3),
PARAMETER :: inv_a2 = reshape([ &
142 0.0_dp, 1.0_dp, 0.0_dp, &
143 360363334.0_dp, 0.0_dp, 1.0_dp, &
144 4225571728.0_dp, 0.0_dp, 0.0_dp &
161 CHARACTER(LEN=rng_name_length) :: name =
""
164 REAL(kind=
dp),
DIMENSION(3, 2) :: bg = 0.0_dp, cg = 0.0_dp, ig = 0.0_dp
165 LOGICAL :: antithetic = .false., extended_precision = .false.
167 REAL(kind=
dp) :: buffer = 0.0_dp
168 LOGICAL :: buffer_filled = .false.
171 PROCEDURE, pass(self) :: fill_1
172 PROCEDURE, pass(self) :: fill_2
173 PROCEDURE, pass(self) :: fill_3
174 generic,
PUBLIC :: fill => fill_1, fill_2, fill_3
176 PROCEDURE, pass(self) :: next_int
177 PROCEDURE, pass(self) :: next_real
178 generic,
PUBLIC :: next => next_int, next_real
180 PROCEDURE, pass(self),
PUBLIC :: dump
181 PROCEDURE, pass(self),
PUBLIC :: write
183 PROCEDURE, pass(self),
PUBLIC :: set
184 PROCEDURE, pass(self),
PUBLIC :: get
185 PROCEDURE, pass(self),
PUBLIC :: reset
186 PROCEDURE, pass(self),
PUBLIC :: reset_to_substream
187 PROCEDURE, pass(self),
PUBLIC :: reset_to_next_substream
188 PROCEDURE, pass(self),
PUBLIC :: shuffle
192 MODULE PROCEDURE :: rng_stream_constructor
229 INTEGER,
INTENT(IN) :: e, c
231 REAL(KIND=
dp),
DIMENSION(3, 2) :: x
232 REAL(KIND=
dp),
DIMENSION(3, 3) :: u1, u2, v1, v2, w1, w2
242 CALL mat_two_pow_mod_m(a1p0, u1, m1, e)
243 CALL mat_two_pow_mod_m(a2p0, u2, m2, e)
245 CALL mat_two_pow_mod_m(inv_a1, u1, m1, -e)
246 CALL mat_two_pow_mod_m(inv_a2, u2, m2, -e)
250 CALL mat_pow_mod_m(a1p0, v1, m1, c)
251 CALL mat_pow_mod_m(a2p0, v2, m2, c)
253 CALL mat_pow_mod_m(inv_a1, v1, m1, -c)
254 CALL mat_pow_mod_m(inv_a2, v2, m2, -c)
261 CALL mat_mat_mod_m(u1, v1, w1, m1)
262 CALL mat_mat_mod_m(u2, v2, w2, m2)
267 CALL mat_vec_mod_m(w1, self%cg(:, 1), x(:, 1), m1)
268 CALL mat_vec_mod_m(w2, self%cg(:, 2), x(:, 2), m2)
282 INTEGER,
INTENT(IN) :: output_unit
283 LOGICAL,
INTENT(IN) :: ionode
286 REAL(kind=
dp) :: sum, sum3
287 REAL(kind=
dp),
DIMENSION(3, 2) :: germe
301 WRITE (unit=output_unit, fmt=
"(/,T2,A)") &
302 "RESULTS OF THE PSEUDO(RANDOM) NUMBER GENERATOR TEST RUNS", &
303 "Initial states of the (pseudo)random number streams (test 1):"
304 CALL g1%write(output_unit)
305 CALL g2%write(output_unit)
306 CALL g3%write(output_unit)
309 sum = g2%next() + g3%next()
311 CALL g1%advance(5, 3)
312 sum = sum + g1%next()
316 CALL g1%advance(0, 1)
318 sum = sum + g1%next()
324 sumi = sumi + g1%next(1, 10)
326 sum = sum + sumi/100.0_dp
330 sum3 = sum3 + g3%next()
332 sum = sum + sum3/10.0_dp
336 sum = sum + g3%next()
341 CALL g3%reset_to_next_substream()
344 sum = sum + g3%next()
347 CALL g3%reset_to_substream()
349 sum = sum + g3%next()
352 CALL g2%reset_to_next_substream()
355 sum3 = sum3 + g2%next()
357 sum = sum + sum3/10000.0_dp
359 CALL g3%set(antithetic=.true.)
362 sum3 = sum3 + g3%next()
364 sum = sum + sum3/10000.0_dp
367 WRITE (unit=output_unit, fmt=
"(/,T2,A)") &
368 "Final states of the (pseudo)random number streams (test 1):"
369 CALL g1%write(output_unit)
370 CALL g2%write(output_unit)
371 CALL g3%write(output_unit)
372 WRITE (unit=output_unit, fmt=
"(/,(T2,A))") &
373 "This test routine should print for test 1 the number 25.342059"
374 WRITE (unit=output_unit, fmt=
"(T2,A,F10.6)") &
375 "The actual result of test 1 is ", sum
389 WRITE (unit=output_unit, fmt=
"(/,T2,A)") &
390 "Initial states of the (pseudo)random number streams (test 2):"
391 CALL poisson%write(output_unit)
392 CALL laplace%write(output_unit)
393 CALL galois%write(output_unit)
394 CALL cantor%write(output_unit)
397 sum = sum + poisson%next() + laplace%next() + galois%next() + cantor%next()
399 CALL galois%advance(-127, 0)
400 sum = sum + galois%next()
402 CALL galois%reset_to_next_substream()
403 CALL galois%set(extended_precision=.true.)
406 sum3 = sum3 + galois%next()
408 sum = sum + sum3/10000.0_dp
410 CALL galois%set(antithetic=.true.)
413 sum3 = sum3 + galois%next()
415 sum = sum + sum3/10000.0_dp
416 CALL galois%set(antithetic=.false.)
418 CALL galois%set(extended_precision=.false.)
419 sum = sum + poisson%next() + laplace%next() + galois%next() + cantor%next()
422 WRITE (unit=output_unit, fmt=
"(/,T2,A)") &
423 "Final states of the (pseudo)random number streams (test 2):"
424 CALL poisson%write(output_unit)
425 CALL laplace%write(output_unit)
426 CALL galois%write(output_unit)
427 CALL cantor%write(output_unit)
428 WRITE (unit=output_unit, fmt=
"(/,(T2,A))") &
429 "This test routine should print for test 2 the number 39.697547"
430 WRITE (unit=output_unit, fmt=
"(T2,A,F10.6)") &
431 "The actual result of test 2 is ", sum
440 SUBROUTINE check_seed(seed)
441 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(IN) :: seed
443 CHARACTER(LEN=*),
PARAMETER :: fmtstr =
"(A,I1,A,ES23.14,A,ES23.14)"
445 CHARACTER(LEN=default_string_length) :: message
452 IF (seed(i, 1) < 0.0_dp)
THEN
453 WRITE (unit=message, fmt=fmtstr) &
454 "seed(", i,
",1) = ", seed(i, 1),
" < ", 0.0_dp
458 IF (seed(i, 1) >= m1)
THEN
459 WRITE (unit=message, fmt=fmtstr) &
460 "seed(", i,
",1) = ", seed(i, 1),
" >= ", m1
467 IF (seed(i, 2) < 0.0_dp)
THEN
468 WRITE (unit=message, fmt=fmtstr) &
469 "seed(", i,
",2) = ", seed(i, 2),
" < ", 0.0_dp
473 IF (seed(i, 2) >= m2)
THEN
474 WRITE (unit=message, fmt=fmtstr) &
475 "seed(", i,
",2) = ", seed(i, 2),
" >= ", m2
484 IF (all(seed(:, 1) < 1.0_dp))
THEN
485 cpabort(
"First seed = 0")
488 IF (all(seed(:, 2) < 1.0_dp))
THEN
489 cpabort(
"Second seed = 0")
492 END SUBROUTINE check_seed
504 FUNCTION rng_stream_constructor(name, last_rng_stream, distribution_type, seed, antithetic, extended_precision) &
507 CHARACTER(LEN=*),
INTENT(IN) :: name
509 INTEGER,
INTENT(IN),
OPTIONAL :: distribution_type
510 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(IN), &
512 LOGICAL,
INTENT(IN),
OPTIONAL :: antithetic, extended_precision
516 cpabort(
"given random number generator name is too long")
519 rng_stream%name = trim(name)
521 IF (
PRESENT(seed))
THEN
522 CALL check_seed(seed)
524 ELSE IF (
PRESENT(last_rng_stream))
THEN
530 rng_stream%cg = rng_stream%ig
531 rng_stream%bg = rng_stream%ig
533 IF (
PRESENT(distribution_type))
THEN
534 SELECT CASE (distribution_type)
536 rng_stream%distribution_type =
gaussian
538 rng_stream%distribution_type =
uniform
540 cpabort(
"Invalid distribution type specified")
542 ELSE IF (
PRESENT(last_rng_stream))
THEN
543 rng_stream%distribution_type = last_rng_stream%distribution_type
546 IF (
PRESENT(antithetic))
THEN
547 rng_stream%antithetic = antithetic
548 ELSE IF (
PRESENT(last_rng_stream))
THEN
549 rng_stream%antithetic = last_rng_stream%antithetic
552 IF (
PRESENT(extended_precision))
THEN
553 rng_stream%extended_precision = extended_precision
554 ELSE IF (
PRESENT(last_rng_stream))
THEN
555 rng_stream%extended_precision = last_rng_stream%extended_precision
557 END FUNCTION rng_stream_constructor
565 CHARACTER(LEN=rng_record_length),
INTENT(IN) :: rng_record
568 READ (unit=rng_record, fmt=rng_record_format) &
570 rng_stream%distribution_type, &
571 rng_stream%antithetic, &
572 rng_stream%extended_precision, &
573 rng_stream%buffer_filled, &
585 SUBROUTINE dump(self, rng_record)
587 CHARACTER(LEN=rng_record_length),
INTENT(OUT) :: rng_record
590 WRITE (unit=rng_record, fmt=rng_record_format) &
592 self%distribution_type, &
594 self%extended_precision, &
595 self%buffer_filled, &
620 SUBROUTINE get(self, name, distribution_type, bg, cg, ig, &
621 antithetic, extended_precision, &
622 buffer, buffer_filled)
625 CHARACTER(LEN=rng_name_length),
INTENT(OUT),
OPTIONAL :: name
626 INTEGER,
INTENT(OUT),
OPTIONAL :: distribution_type
627 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(OUT), &
628 OPTIONAL :: bg, cg, ig
629 LOGICAL,
INTENT(OUT),
OPTIONAL :: antithetic, extended_precision
630 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: buffer
631 LOGICAL,
INTENT(OUT),
OPTIONAL :: buffer_filled
633 IF (
PRESENT(name)) name = self%name
634 IF (
PRESENT(distribution_type))
THEN
635 distribution_type = self%distribution_type
637 IF (
PRESENT(bg)) bg = self%bg
638 IF (
PRESENT(cg)) cg = self%cg
639 IF (
PRESENT(ig)) ig = self%ig
640 IF (
PRESENT(antithetic)) antithetic = self%antithetic
641 IF (
PRESENT(extended_precision))
THEN
642 extended_precision = self%extended_precision
644 IF (
PRESENT(buffer)) buffer = self%buffer
645 IF (
PRESENT(buffer_filled)) buffer_filled = self%buffer_filled
655 PURE SUBROUTINE mat_mat_mod_m(a, b, c, m)
656 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: a, b
657 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: c
658 REAL(kind=
dp),
INTENT(IN) :: m
663 CALL mat_vec_mod_m(a, b(:, i), c(:, i), m)
666 END SUBROUTINE mat_mat_mod_m
675 PURE SUBROUTINE mat_pow_mod_m(a, b, m, n)
676 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: a
677 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: b
678 REAL(kind=
dp),
INTENT(IN) :: m
679 INTEGER,
INTENT(IN) :: n
682 REAL(kind=
dp),
DIMENSION(3, 3) :: u, v, w
703 IF (
modulo(i, 2) /= 0)
THEN
706 CALL mat_mat_mod_m(u, v, b, m)
712 CALL mat_mat_mod_m(u, v, w, m)
714 END SUBROUTINE mat_pow_mod_m
723 PURE SUBROUTINE mat_two_pow_mod_m(a, b, m, e)
724 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: a
725 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: b
726 REAL(kind=
dp),
INTENT(IN) :: m
727 INTEGER,
INTENT(IN) :: e
730 REAL(kind=
dp),
DIMENSION(3, 3) :: u, v
737 CALL mat_mat_mod_m(u, v, b, m)
740 END SUBROUTINE mat_two_pow_mod_m
749 PURE SUBROUTINE mat_vec_mod_m(a, s, v, m)
750 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: a
751 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: s
752 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: v
753 REAL(kind=
dp),
INTENT(IN) :: m
756 REAL(kind=
dp) :: a1, a2, c
765 IF ((v(i) >= two53) .OR. (v(i) <= -two53))
THEN
771 v(i) = v(i)*two17 + a2*s(j) + c
775 IF (v(i) < 0.0_dp) v(i) = v(i) + m
779 END SUBROUTINE mat_vec_mod_m
788 FUNCTION next_int(self, low, high)
RESULT(u)
790 INTEGER,
INTENT(IN) :: low, high
795 cpassert(self%distribution_type ==
uniform)
798 u = low + int(r*real(high - low + 1,
dp))
799 END FUNCTION next_int
807 FUNCTION next_real(self, variance)
RESULT(u)
809 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: variance
812 REAL(kind=
dp) :: f, r, u1, u2, var
814 SELECT CASE (self%distribution_type)
817 IF (
PRESENT(variance)) var = variance
819 IF (self%buffer_filled)
THEN
820 u = sqrt(var)*self%buffer
821 self%buffer_filled = .false.
824 IF (self%extended_precision)
THEN
825 u1 = 2.0_dp*rn53(self) - 1.0_dp
826 u2 = 2.0_dp*rn53(self) - 1.0_dp
828 u1 = 2.0_dp*rn32(self) - 1.0_dp
829 u2 = 2.0_dp*rn32(self) - 1.0_dp
832 IF ((r > 0.0_dp) .AND. (r < 1.0_dp))
EXIT
835 f = sqrt(-2.0_dp*log(r)/r)
839 self%buffer_filled = .true.
842 IF (self%extended_precision)
THEN
848 END FUNCTION next_real
856 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(IN), &
858 REAL(kind=
dp),
DIMENSION(3, 2) :: next_seed
860 IF (
PRESENT(seed))
THEN
861 CALL check_seed(seed)
862 CALL mat_vec_mod_m(a1p127, seed(:, 1), next_seed(:, 1), m1)
863 CALL mat_vec_mod_m(a2p127, seed(:, 2), next_seed(:, 2), m2)
865 next_seed = 12345.0_dp
875 SUBROUTINE fill_1(self, array)
877 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: array
881 DO i = 1,
SIZE(array)
882 array(i) = self%next()
884 END SUBROUTINE fill_1
891 SUBROUTINE fill_2(self, array)
893 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: array
897 DO j = 1,
SIZE(array, 2)
898 DO i = 1,
SIZE(array, 1)
899 array(i, j) = self%next()
902 END SUBROUTINE fill_2
909 SUBROUTINE fill_3(self, array)
911 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(OUT) :: array
915 DO k = 1,
SIZE(array, 3)
916 DO j = 1,
SIZE(array, 2)
917 DO i = 1,
SIZE(array, 1)
918 array(i, j, k) = self%next()
922 END SUBROUTINE fill_3
928 SUBROUTINE reset(self)
939 SUBROUTINE reset_to_substream(self)
943 END SUBROUTINE reset_to_substream
949 SUBROUTINE reset_to_next_substream(self)
952 REAL(kind=
dp),
DIMENSION(3, 2) :: u
956 CALL mat_vec_mod_m(a1p76, self%bg(:, 1), u(:, 1), m1)
957 CALL mat_vec_mod_m(a2p76, self%bg(:, 2), u(:, 2), m2)
961 END SUBROUTINE reset_to_next_substream
968 FUNCTION rn32(rng_stream)
RESULT(u)
973 REAL(kind=
dp) :: p1, p2
977 p1 = a12*rng_stream%cg(2, 1) - a13n*rng_stream%cg(1, 1)
980 IF (p1 < 0.0_dp) p1 = p1 + m1
981 rng_stream%cg(1, 1) = rng_stream%cg(2, 1)
982 rng_stream%cg(2, 1) = rng_stream%cg(3, 1)
983 rng_stream%cg(3, 1) = p1
987 p2 = a21*rng_stream%cg(3, 2) - a23n*rng_stream%cg(1, 2)
990 IF (p2 < 0.0_dp) p2 = p2 + m2
991 rng_stream%cg(1, 2) = rng_stream%cg(2, 2)
992 rng_stream%cg(2, 2) = rng_stream%cg(3, 2)
993 rng_stream%cg(3, 2) = p2
1000 u = (p1 - p2 + m1)*norm
1003 IF (rng_stream%antithetic) u = 1.0_dp - u
1012 FUNCTION rn53(rng_stream)
RESULT(u)
1016 u = rn32(rng_stream)
1020 IF (rng_stream%antithetic)
THEN
1021 u = u + (rn32(rng_stream) - 1.0_dp)*fact
1022 IF (u < 0.0_dp) u = u + 1.0_dp
1024 u = u + rn32(rng_stream)*fact
1025 IF (u >= 1.0_dp) u = u - 1.0_dp
1046 SUBROUTINE set(self, name, distribution_type, bg, cg, ig, &
1047 seed, antithetic, extended_precision, &
1048 buffer, buffer_filled)
1053 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: name
1054 INTEGER,
INTENT(IN),
OPTIONAL :: distribution_type
1055 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(IN), &
1056 OPTIONAL :: bg, cg, ig, seed
1057 LOGICAL,
INTENT(IN),
OPTIONAL :: antithetic, extended_precision
1058 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: buffer
1059 LOGICAL,
INTENT(IN),
OPTIONAL :: buffer_filled
1061 IF (
PRESENT(name)) self%name = name
1062 IF (
PRESENT(distribution_type))
THEN
1063 self%distribution_type = distribution_type
1065 IF (
PRESENT(bg)) self%bg = bg
1066 IF (
PRESENT(cg)) self%cg = cg
1067 IF (
PRESENT(ig)) self%ig = ig
1068 IF (
PRESENT(seed))
THEN
1071 CALL check_seed(seed)
1076 IF (
PRESENT(antithetic)) self%antithetic = antithetic
1077 IF (
PRESENT(extended_precision))
THEN
1078 self%extended_precision = extended_precision
1080 IF (
PRESENT(buffer)) self%buffer = buffer
1081 IF (
PRESENT(buffer_filled)) self%buffer_filled = buffer_filled
1089 INTEGER,
INTENT(IN) :: output_unit
1091 CHARACTER(LEN=40) :: fmtstr
1096 WRITE (unit=output_unit, fmt=
"(/,T2,A)") &
1097 "TRANSFORMATION MATRICES FOR THE PARALLEL (PSEUDO)RANDOM NUMBER "// &
1100 fmtstr =
"(/,T4,A,/,/,(2X,3F14.1))"
1102 WRITE (unit=output_unit, fmt=fmtstr) &
1103 "A1", ((a1p0(i, j), j=1, 3), i=1, 3)
1105 WRITE (unit=output_unit, fmt=fmtstr) &
1106 "A2", ((a2p0(i, j), j=1, 3), i=1, 3)
1108 WRITE (unit=output_unit, fmt=fmtstr) &
1109 "A1**(2**76)", ((a1p76(i, j), j=1, 3), i=1, 3)
1111 WRITE (unit=output_unit, fmt=fmtstr) &
1112 "A2**(2**76)", ((a2p76(i, j), j=1, 3), i=1, 3)
1114 WRITE (unit=output_unit, fmt=fmtstr) &
1115 "A1**(2**127)", ((a1p127(i, j), j=1, 3), i=1, 3)
1117 WRITE (unit=output_unit, fmt=fmtstr) &
1118 "A2**(2**127)", ((a2p127(i, j), j=1, 3), i=1, 3)
1128 SUBROUTINE write (self, output_unit, write_all)
1130 INTEGER,
INTENT(IN) :: output_unit
1131 LOGICAL,
INTENT(IN),
OPTIONAL :: write_all
1133 LOGICAL :: my_write_all
1135 my_write_all = .false.
1137 IF (
PRESENT(write_all))
THEN
1138 my_write_all = write_all
1141 WRITE (unit=output_unit, fmt=
"(/,T2,A,/)") &
1142 "Random number stream <"//trim(self%name)//
">:"
1144 SELECT CASE (self%distribution_type)
1146 WRITE (unit=output_unit, fmt=
"(T4,A)") &
1147 "Distribution type: "// &
1148 "Normal Gaussian distribution with zero mean"
1150 WRITE (unit=output_unit, fmt=
"(T4,A)") &
1151 "Distribution type: "// &
1152 "Uniform distribution [0,1] with 1/2 mean"
1155 IF (self%antithetic)
THEN
1156 WRITE (unit=output_unit, fmt=
"(T4,A)")
"Antithetic: yes"
1158 WRITE (unit=output_unit, fmt=
"(T4,A)")
"Antithetic: no"
1161 IF (self%extended_precision)
THEN
1162 WRITE (unit=output_unit, fmt=
"(T4,A)")
"Precision: 53 Bit"
1164 WRITE (unit=output_unit, fmt=
"(T4,A)")
"Precision: 32 Bit"
1167 IF (my_write_all)
THEN
1169 WRITE (unit=output_unit, fmt=
"(/,T4,A,/,/,(T4,A,3F20.1))") &
1170 "Initial state of the stream:", &
1171 "Component 1:", self%ig(:, 1), &
1172 "Component 2:", self%ig(:, 2)
1174 WRITE (unit=output_unit, fmt=
"(/,T4,A,/,/,(T4,A,3F20.1))") &
1175 "Initial state of the current substream:", &
1176 "Component 1:", self%bg(:, 1), &
1177 "Component 2:", self%bg(:, 2)
1181 WRITE (unit=output_unit, fmt=
"(/,T4,A,/,/,(T4,A,3F20.1))") &
1182 "Current state of the stream:", &
1183 "Component 1:", self%cg(:, 1), &
1184 "Component 2:", self%cg(:, 2)
1185 END SUBROUTINE write
1192 SUBROUTINE shuffle(self, arr)
1194 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: arr
1196 INTEGER :: idxa, idxb, tmp
1198 DO idxa = ubound(arr, 1), lbound(arr, 1) + 1, -1
1199 idxb = self%next(lbound(arr, 1), idxa)
1201 arr(idxa) = arr(idxb)
1204 END SUBROUTINE shuffle
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
subroutine advance(self, e, c)
Advance the state by n steps, i.e. jump n steps forward, if n > 0, or backward if n < 0.
type(rng_stream_type) function, public rng_stream_type_from_record(rng_record)
Create a RNG stream from a record given as an internal file (string).
real(kind=dp) function, dimension(3, 2), public next_rng_seed(seed)
Get the seed for the next RNG stream w.r.t. a given seed.
integer, parameter, public rng_name_length
integer, parameter, public rng_record_length
integer, parameter, public uniform
subroutine, public check_rng(output_unit, ionode)
...
subroutine, public write_rng_matrices(output_unit)
Write the transformation matrices of the two MRG components (raised to the specified output)
integer, parameter, public gaussian
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.