ROMS
Loading...
Searching...
No Matches
ran1.F
Go to the documentation of this file.
1#include "cppdefs.h"
2 SUBROUTINE ran1_s (harvest)
3!
4!git $Id$
5!================================================== Hernan G. Arango ===
6! Copyright (c) 2002-2025 The ROMS Group !
7! Licensed under a MIT/X style license !
8! See License_ROMS.md !
9!=======================================================================
10! !
11! Lagged Fibonacci generator combined with two Marsaglia shift !
12! sequences. On output, returns as HARVEST a uniform random deviate !
13! between 0.0 and 1.0 (exclusive of the endpoint values). This !
14! generator has the same calling and initialization conventions as !
15! Fortran 90 RANDOM_NUMBEER routine. Use RAN_SEED to initialize or !
16! reinitialize a particular sequence. The period of this generator !
17! is about 8.5E+37, and it fully vectorizes. Validy of the integer !
18! model assumend by this generator is tested at initialization. !
19! !
20! Scalar version adapted from Numerical recipes. !
21! !
22! Press, W.H., S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery, !
23! 1996: Numerical Recipes in Fortran 90, The Art of Parallel !
24! Scientific Computing, 2nd Edition, Cambridge Univ. Press. !
25! !
26!=======================================================================
27!
28 USE mod_kinds
29 USE ran_state, ONLY : ran_init
30 USE ran_state, ONLY : iran0, jran0, kran0, nran0, mran0
31 USE ran_state, ONLY : amm, lenran, rans
32!
33! Imported variable declarations.
34!
35 real(r8), intent(out) :: harvest
36!
37!-----------------------------------------------------------------------
38! Compute an uniform random deviate (scalar version).
39!-----------------------------------------------------------------------
40!
41! Initialize.
42!
43 IF (lenran.lt.1) CALL ran_init (1_i8b)
44!
45! Update Fibonacci generator, which has a period p*p+p+1 (p=2^(31)-69).
46!
48 IF (rans.lt.0) rans=rans+2147483579_i8b
52!
53! Update Marsaglia shift sequence.
54!
55 nran0=ieor(nran0,ishft(nran0,13))
56 nran0=ieor(nran0,ishft(nran0,-17))
57 nran0=ieor(nran0,ishft(nran0,5))
58!
59! Once only per cycle, advance sequence by 1, shortening its period to
60! 2^(32)-2.
61!
62 IF (nran0.eq.1) nran0=270369_i8b
63!
64! Update Marsaglia shift sequence with perios 2^(32)-1.
65!
66 mran0=ieor(mran0,ishft(mran0,5))
67 mran0=ieor(mran0,ishft(mran0,-13))
68 mran0=ieor(mran0,ishft(mran0,6))
69!
70! Wrap=around addition.
71!
72 rans=ieor(nran0,rans)+mran0
73!
74! Make the results positive definite (note that AMM is negative).
75!
76 harvest=amm*merge(rans,not(rans), rans<0)
77
78 RETURN
79 END SUBROUTINE ran1_s
80
81 SUBROUTINE ran1_v (harvest)
82!
83!=======================================================================
84! !
85! Lagged Fibonacci generator combined with two Marsaglia shift !
86! sequences. On output, returns as HARVEST a uniform random deviate !
87! between 0.0 and 1.0 (exclusive of the endpoint values). This !
88! generator has the same calling and initialization conventions as !
89! Fortran 90 RANDOM_NUMBEER routine. Use RAN_SEED to initialize or !
90! reinitialize a particular sequence. The period of this generator !
91! is about 8.5E+37, and it fully vectorizes. Validy of the integer !
92! model assumend by this generator is tested at initialization. !
93! !
94! Vector version adapted from Numerical recipes. !
95! !
96! Press, W.H., S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery, !
97! 1996: Numerical Recipes in Fortran 90, The Art of Parallel !
98! Scientific Computing, 2nd Edition, Cambridge Univ. Press. !
99! !
100!=======================================================================
101!
102 USE mod_kinds
103 USE ran_state, ONLY : ran_init
104 USE ran_state, ONLY : iran, jran, kran, nran, mran
105 USE ran_state, ONLY : amm, lenran, ranv
106!
107! Imported variable declarations.
108!
109 real(r8), dimension(:), intent(out) :: harvest
110!
111! Local variable declarations.
112!
113 integer(i8b) :: n
114!
115!-----------------------------------------------------------------------
116! Compute an uniform random deviate (scalar version).
117!-----------------------------------------------------------------------
118!
119! Initialize.
120!
121 n=SIZE(harvest)
122 IF (lenran.lt.n+1) CALL ran_init (n+1_i8b)
123!
124! Update Fibonacci generator, which has a period p*p+p+1 (p=2^(31)-69).
125!
126 ranv(1:n)=iran(1:n)-kran(1:n)
127 WHERE (ranv(1:n).lt.0) &
128 & ranv(1:n)=ranv(1:n)+2147483579_i8b
129 iran(1:n)=jran(1:n)
130 jran(1:n)=kran(1:n)
131 kran(1:n)=ranv(1:n)
132!
133! Update Marsaglia shift sequence.
134!
135 nran(1:n)=ieor(nran(1:n),ishft(nran(1:n),13))
136 nran(1:n)=ieor(nran(1:n),ishft(nran(1:n),-17))
137 nran(1:n)=ieor(nran(1:n),ishft(nran(1:n),5))
138!
139! Once only per cycle, advance sequence by 1, shortening its period to
140! 2^(32)-2.
141!
142 WHERE (nran(1:n).eq.1) &
143 & nran(1:n)=270369_i8b
144!
145! Update Marsaglia shift sequence with perios 2^(32)-1.
146!
147 mran(1:n)=ieor(mran(1:n),ishft(mran(1:n),5))
148 mran(1:n)=ieor(mran(1:n),ishft(mran(1:n),-13))
149 mran(1:n)=ieor(mran(1:n),ishft(mran(1:n),6))
150!
151! Wrap=around addition.
152!
153 ranv(1:n)=ieor(nran(1:n),ranv(1:n))+mran(1:n)
154!
155! Make the results positive definite (note that AMM is negative).
156!
157 harvest=amm*merge(ranv(1:n),not(ranv(1:n)), ranv(1:n)<0 )
158
159 RETURN
160 END SUBROUTINE ran1_v
subroutine ran_init(length)
Definition ran_state.F:65
integer(i8b), dimension(:), pointer, save jran
Definition ran_state.F:48
integer(i8b), dimension(:), pointer, save kran
Definition ran_state.F:49
integer(i8b), dimension(:), pointer, save ranv
Definition ran_state.F:52
integer(i8b), save lenran
Definition ran_state.F:38
integer(i8b), dimension(:), pointer, save iran
Definition ran_state.F:47
integer(i8b), dimension(:), pointer, save mran
Definition ran_state.F:51
integer(i8b), dimension(:), pointer, save nran
Definition ran_state.F:50
real(r8), save amm
Definition ran_state.F:56
integer(i8b), save kran0
Definition ran_state.F:42
integer(i8b), save jran0
Definition ran_state.F:41
integer(i8b), save mran0
Definition ran_state.F:44
integer(i8b), save nran0
Definition ran_state.F:43
integer(i8b), save iran0
Definition ran_state.F:40
integer(i8b), save rans
Definition ran_state.F:45
subroutine ran1_s(harvest)
Definition ran1.F:3
subroutine ran1_v(harvest)
Definition ran1.F:82