Mercurial > octave
annotate liboctave/oct-rand.cc @ 8124:d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
author | Brian Gough |
---|---|
date | Mon, 22 Sep 2008 13:17:39 -0400 |
parents | a2950622f070 |
children | 25bc2d31e1bf |
rev | line source |
---|---|
4308 | 1 /* |
2 | |
7017 | 3 Copyright (C) 2003, 2005, 2006, 2007 John W. Eaton |
4308 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
4308 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
4308 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
26 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
27 #include <map> |
5730 | 28 #include <vector> |
4308 | 29 |
30 #include "f77-fcn.h" | |
5730 | 31 #include "lo-ieee.h" |
4308 | 32 #include "lo-error.h" |
5730 | 33 #include "lo-mappers.h" |
4308 | 34 #include "oct-rand.h" |
4415 | 35 #include "oct-time.h" |
5730 | 36 #include "data-conv.h" |
37 #include "randmtzig.h" | |
38 #include "randpoisson.h" | |
39 #include "randgamma.h" | |
6435 | 40 #include "mach-info.h" |
4308 | 41 |
42 extern "C" | |
43 { | |
4552 | 44 F77_RET_T |
45 F77_FUNC (dgennor, DGENNOR) (const double&, const double&, double&); | |
4308 | 46 |
4552 | 47 F77_RET_T |
48 F77_FUNC (dgenunf, DGENUNF) (const double&, const double&, double&); | |
49 | |
50 F77_RET_T | |
5730 | 51 F77_FUNC (dgenexp, DGENEXP) (const double&, double&); |
52 | |
53 F77_RET_T | |
54 F77_FUNC (dignpoi, DIGNPOI) (const double&, double&); | |
55 | |
56 F77_RET_T | |
57 F77_FUNC (dgengam, DGENGAM) (const double&, const double&, double&); | |
58 | |
59 F77_RET_T | |
5275 | 60 F77_FUNC (setall, SETALL) (const octave_idx_type&, const octave_idx_type&); |
4308 | 61 |
4552 | 62 F77_RET_T |
5275 | 63 F77_FUNC (getsd, GETSD) (octave_idx_type&, octave_idx_type&); |
4308 | 64 |
4552 | 65 F77_RET_T |
5275 | 66 F77_FUNC (setsd, SETSD) (const octave_idx_type&, const octave_idx_type&); |
4308 | 67 |
4552 | 68 F77_RET_T |
5275 | 69 F77_FUNC (setcgn, SETCGN) (const octave_idx_type&); |
4308 | 70 } |
71 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
72 octave_rand *octave_rand::instance = 0; |
6326 | 73 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
74 octave_rand::octave_rand (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
75 : current_distribution (uniform_dist), use_old_generators (false), |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
76 rand_states () |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
77 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
78 initialize_ranlib_generators (); |
4308 | 79 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
80 initialize_mersenne_twister (); |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
81 } |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
82 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
83 bool |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
84 octave_rand::instance_ok (void) |
4308 | 85 { |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
86 bool retval = true; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
87 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
88 if (! instance) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
89 instance = new octave_rand (); |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
90 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
91 if (! instance) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
92 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
93 (*current_liboctave_error_handler) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
94 ("unable to create octave_rand object!"); |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
95 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
96 retval = false; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
97 } |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
98 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
99 return retval; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
100 } |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
101 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
102 double |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
103 octave_rand::do_seed (void) |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
104 { |
5275 | 105 union d2i { double d; octave_idx_type i[2]; }; |
4308 | 106 union d2i u; |
6435 | 107 |
108 oct_mach_info::float_format ff = oct_mach_info::native_float_format (); | |
109 | |
110 switch (ff) | |
111 { | |
112 case oct_mach_info::flt_fmt_ieee_big_endian: | |
113 F77_FUNC (getsd, GETSD) (u.i[1], u.i[0]); | |
114 break; | |
115 default: | |
116 F77_FUNC (getsd, GETSD) (u.i[0], u.i[1]); | |
117 break; | |
118 } | |
119 | |
4308 | 120 return u.d; |
121 } | |
122 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
123 static octave_idx_type |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
124 force_to_fit_range (octave_idx_type i, octave_idx_type lo, octave_idx_type hi) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
125 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
126 assert (hi > lo && lo >= 0 && hi > lo); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
127 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
128 i = i > 0 ? i : -i; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
129 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
130 if (i < lo) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
131 i = lo; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
132 else if (i > hi) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
133 i = i % hi; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
134 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
135 return i; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
136 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
137 |
4308 | 138 void |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
139 octave_rand::do_seed (double s) |
4308 | 140 { |
5730 | 141 use_old_generators = true; |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
142 |
6435 | 143 int i0, i1; |
5275 | 144 union d2i { double d; octave_idx_type i[2]; }; |
4308 | 145 union d2i u; |
146 u.d = s; | |
6435 | 147 |
148 oct_mach_info::float_format ff = oct_mach_info::native_float_format (); | |
149 | |
150 switch (ff) | |
151 { | |
152 case oct_mach_info::flt_fmt_ieee_big_endian: | |
153 i1 = force_to_fit_range (u.i[0], 1, 2147483563); | |
154 i0 = force_to_fit_range (u.i[1], 1, 2147483399); | |
155 break; | |
156 default: | |
157 i0 = force_to_fit_range (u.i[0], 1, 2147483563); | |
158 i1 = force_to_fit_range (u.i[1], 1, 2147483399); | |
159 break; | |
160 } | |
161 | |
4308 | 162 F77_FUNC (setsd, SETSD) (i0, i1); |
163 } | |
164 | |
5730 | 165 ColumnVector |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
166 octave_rand::do_state (const std::string& d) |
5730 | 167 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
168 return rand_states[d.empty () ? current_distribution : get_dist_id (d)]; |
5730 | 169 } |
170 | |
171 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
172 octave_rand::do_state (const ColumnVector& s, const std::string& d) |
5730 | 173 { |
174 use_old_generators = false; | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
175 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
176 int old_dist = current_distribution; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
177 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
178 int new_dist = d.empty () ? current_distribution : get_dist_id (d); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
179 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
180 ColumnVector saved_state; |
5730 | 181 |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
182 if (old_dist != new_dist) |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
183 saved_state = get_internal_state (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
184 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
185 set_internal_state (s); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
186 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
187 rand_states[new_dist] = get_internal_state (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
188 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
189 if (old_dist != new_dist) |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
190 rand_states[old_dist] = saved_state; |
5730 | 191 } |
192 | |
4308 | 193 std::string |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
194 octave_rand::do_distribution (void) |
4308 | 195 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
196 std::string retval; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
197 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
198 switch (current_distribution) |
4308 | 199 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
200 case uniform_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
201 retval = "uniform"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
202 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
203 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
204 case normal_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
205 retval = "normal"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
206 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
207 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
208 case expon_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
209 retval = "exponential"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
210 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
211 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
212 case poisson_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
213 retval = "poisson"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
214 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
215 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
216 case gamma_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
217 retval = "gamma"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
218 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
219 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
220 default: |
7536 | 221 (*current_liboctave_error_handler) |
222 ("rand: invalid distribution ID = %d", current_distribution); | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
223 break; |
4308 | 224 } |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
225 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
226 return retval; |
4308 | 227 } |
228 | |
229 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
230 octave_rand::do_distribution (const std::string& d) |
4308 | 231 { |
7536 | 232 int id = get_dist_id (d); |
233 | |
234 switch (id) | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
235 { |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
236 case uniform_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
237 octave_rand::uniform_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
238 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
239 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
240 case normal_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
241 octave_rand::normal_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
242 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
243 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
244 case expon_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
245 octave_rand::exponential_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
246 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
247 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
248 case poisson_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
249 octave_rand::poisson_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
250 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
251 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
252 case gamma_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
253 octave_rand::gamma_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
254 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
255 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
256 default: |
7536 | 257 (*current_liboctave_error_handler) |
258 ("rand: invalid distribution ID = %d", id); | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
259 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
260 } |
4308 | 261 } |
262 | |
263 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
264 octave_rand::do_uniform_distribution (void) |
4308 | 265 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
266 switch_to_generator (uniform_dist); |
4308 | 267 |
268 F77_FUNC (setcgn, SETCGN) (uniform_dist); | |
269 } | |
270 | |
271 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
272 octave_rand::do_normal_distribution (void) |
4308 | 273 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
274 switch_to_generator (normal_dist); |
4308 | 275 |
276 F77_FUNC (setcgn, SETCGN) (normal_dist); | |
277 } | |
278 | |
5730 | 279 void |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
280 octave_rand::do_exponential_distribution (void) |
5730 | 281 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
282 switch_to_generator (expon_dist); |
5730 | 283 |
284 F77_FUNC (setcgn, SETCGN) (expon_dist); | |
285 } | |
286 | |
287 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
288 octave_rand::do_poisson_distribution (void) |
5730 | 289 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
290 switch_to_generator (poisson_dist); |
5730 | 291 |
292 F77_FUNC (setcgn, SETCGN) (poisson_dist); | |
293 } | |
294 | |
295 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
296 octave_rand::do_gamma_distribution (void) |
5730 | 297 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
298 switch_to_generator (gamma_dist); |
5730 | 299 |
300 F77_FUNC (setcgn, SETCGN) (gamma_dist); | |
301 } | |
302 | |
303 | |
4308 | 304 double |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
305 octave_rand::do_scalar (double a) |
4308 | 306 { |
307 double retval = 0.0; | |
308 | |
5730 | 309 if (use_old_generators) |
4308 | 310 { |
5730 | 311 switch (current_distribution) |
312 { | |
313 case uniform_dist: | |
314 F77_FUNC (dgenunf, DGENUNF) (0.0, 1.0, retval); | |
315 break; | |
4308 | 316 |
5730 | 317 case normal_dist: |
318 F77_FUNC (dgennor, DGENNOR) (0.0, 1.0, retval); | |
319 break; | |
4308 | 320 |
5730 | 321 case expon_dist: |
322 F77_FUNC (dgenexp, DGENEXP) (1.0, retval); | |
323 break; | |
4308 | 324 |
5730 | 325 case poisson_dist: |
326 if (a < 0.0 || xisnan(a) || xisinf(a)) | |
327 retval = octave_NaN; | |
328 else | |
329 { | |
330 // workaround bug in ignpoi, by calling with different Mu | |
331 F77_FUNC (dignpoi, DIGNPOI) (a + 1, retval); | |
332 F77_FUNC (dignpoi, DIGNPOI) (a, retval); | |
333 } | |
334 break; | |
4308 | 335 |
5730 | 336 case gamma_dist: |
337 if (a <= 0.0 || xisnan(a) || xisinf(a)) | |
338 retval = octave_NaN; | |
339 else | |
340 F77_FUNC (dgengam, DGENGAM) (1.0, a, retval); | |
341 break; | |
4308 | 342 |
5730 | 343 default: |
7536 | 344 (*current_liboctave_error_handler) |
345 ("rand: invalid distribution ID = %d", current_distribution); | |
5730 | 346 break; |
4308 | 347 } |
348 } | |
349 else | |
4543 | 350 { |
351 switch (current_distribution) | |
352 { | |
353 case uniform_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
354 retval = oct_randu (); |
4543 | 355 break; |
356 | |
357 case normal_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
358 retval = oct_randn (); |
5730 | 359 break; |
360 | |
361 case expon_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
362 retval = oct_rande (); |
5730 | 363 break; |
364 | |
365 case poisson_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
366 retval = oct_randp (a); |
5730 | 367 break; |
368 | |
369 case gamma_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
370 retval = oct_randg (a); |
4543 | 371 break; |
372 | |
373 default: | |
7536 | 374 (*current_liboctave_error_handler) |
375 ("rand: invalid distribution ID = %d", current_distribution); | |
4543 | 376 break; |
377 } | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
378 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
379 save_state (); |
4543 | 380 } |
381 | |
382 return retval; | |
383 } | |
384 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
385 Matrix |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
386 octave_rand::do_matrix (octave_idx_type n, octave_idx_type m, double a) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
387 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
388 Matrix retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
389 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
390 if (n >= 0 && m >= 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
391 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
392 retval.resize (n, m); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
393 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
394 if (n > 0 && m > 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
395 fill (retval.capacity(), retval.fortran_vec(), a); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
396 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
397 else |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
398 (*current_liboctave_error_handler) ("rand: invalid negative argument"); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
399 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
400 return retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
401 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
402 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
403 NDArray |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
404 octave_rand::do_nd_array (const dim_vector& dims, double a) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
405 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
406 NDArray retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
407 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
408 if (! dims.all_zero ()) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
409 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
410 retval.resize (dims); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
411 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
412 fill (retval.capacity(), retval.fortran_vec(), a); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
413 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
414 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
415 return retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
416 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
417 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
418 Array<double> |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
419 octave_rand::do_vector (octave_idx_type n, double a) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
420 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
421 Array<double> retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
422 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
423 if (n > 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
424 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
425 retval.resize (n); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
426 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
427 fill (retval.capacity (), retval.fortran_vec (), a); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
428 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
429 else if (n < 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
430 (*current_liboctave_error_handler) ("rand: invalid negative argument"); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
431 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
432 return retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
433 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
434 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
435 // Make the random number generator give us a different sequence every |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
436 // time we start octave unless we specifically set the seed. The |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
437 // technique used below will cycle monthly, but it it does seem to |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
438 // work ok to give fairly different seeds each time Octave starts. |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
439 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
440 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
441 octave_rand::initialize_ranlib_generators (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
442 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
443 octave_localtime tm; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
444 int stored_distribution = current_distribution; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
445 F77_FUNC (setcgn, SETCGN) (uniform_dist); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
446 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
447 int hour = tm.hour() + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
448 int minute = tm.min() + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
449 int second = tm.sec() + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
450 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
451 octave_idx_type s0 = tm.mday() * hour * minute * second; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
452 octave_idx_type s1 = hour * minute * second; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
453 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
454 s0 = force_to_fit_range (s0, 1, 2147483563); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
455 s1 = force_to_fit_range (s1, 1, 2147483399); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
456 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
457 F77_FUNC (setall, SETALL) (s0, s1); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
458 F77_FUNC (setcgn, SETCGN) (stored_distribution); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
459 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
460 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
461 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
462 octave_rand::initialize_mersenne_twister (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
463 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
464 oct_init_by_entropy (); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
465 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
466 ColumnVector s = get_internal_state (); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
467 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
468 rand_states[uniform_dist] = s; |
8124
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
469 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
470 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
471 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
472 rand_states[normal_dist] = s; |
8124
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
473 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
474 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
475 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
476 rand_states[expon_dist] = s; |
8124
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
477 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
478 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
479 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
480 rand_states[poisson_dist] = s; |
8124
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
481 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
482 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
483 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
484 rand_states[gamma_dist] = s; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
485 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
486 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
487 ColumnVector |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
488 octave_rand::get_internal_state (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
489 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
490 ColumnVector s (MT_N + 1); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
491 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
492 OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
493 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
494 oct_get_state (tmp); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
495 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
496 for (octave_idx_type i = 0; i <= MT_N; i++) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
497 s.elem (i) = static_cast<double> (tmp [i]); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
498 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
499 return s; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
500 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
501 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
502 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
503 octave_rand::save_state (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
504 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
505 rand_states[current_distribution] = get_internal_state ();; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
506 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
507 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
508 int |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
509 octave_rand::get_dist_id (const std::string& d) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
510 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
511 int retval = unknown_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
512 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
513 if (d == "uniform" || d == "rand") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
514 retval = uniform_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
515 else if (d == "normal" || d == "randn") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
516 retval = normal_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
517 else if (d == "exponential" || d == "rande") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
518 retval = expon_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
519 else if (d == "poisson" || d == "randp") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
520 retval = poisson_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
521 else if (d == "gamma" || d == "randg") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
522 retval = gamma_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
523 else |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
524 (*current_liboctave_error_handler) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
525 ("rand: invalid distribution `%s'", d.c_str ()); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
526 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
527 return retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
528 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
529 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
530 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
531 octave_rand::set_internal_state (const ColumnVector& s) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
532 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
533 octave_idx_type len = s.length (); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
534 octave_idx_type n = len < MT_N + 1 ? len : MT_N + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
535 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
536 OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
537 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
538 for (octave_idx_type i = 0; i < n; i++) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
539 tmp[i] = static_cast<uint32_t> (s.elem(i)); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
540 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
541 if (len == MT_N + 1 && tmp[MT_N] <= MT_N && tmp[MT_N] > 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
542 oct_set_state (tmp); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
543 else |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
544 oct_init_by_array (tmp, len); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
545 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
546 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
547 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
548 octave_rand::switch_to_generator (int dist) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
549 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
550 if (dist != current_distribution) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
551 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
552 current_distribution = dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
553 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
554 set_internal_state (rand_states[dist]); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
555 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
556 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
557 |
5730 | 558 #define MAKE_RAND(len) \ |
4308 | 559 do \ |
560 { \ | |
561 double val; \ | |
5730 | 562 for (volatile octave_idx_type i = 0; i < len; i++) \ |
4308 | 563 { \ |
564 OCTAVE_QUIT; \ | |
5730 | 565 RAND_FUNC (val); \ |
566 v[i] = val; \ | |
4308 | 567 } \ |
568 } \ | |
569 while (0) | |
570 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
571 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
572 octave_rand::fill (octave_idx_type len, double *v, double a) |
5730 | 573 { |
574 if (len < 1) | |
575 return; | |
576 | |
577 switch (current_distribution) | |
578 { | |
579 case uniform_dist: | |
580 if (use_old_generators) | |
581 { | |
582 #define RAND_FUNC(x) F77_FUNC (dgenunf, DGENUNF) (0.0, 1.0, x) | |
583 MAKE_RAND (len); | |
584 #undef RAND_FUNC | |
585 } | |
586 else | |
587 oct_fill_randu (len, v); | |
588 break; | |
589 | |
590 case normal_dist: | |
591 if (use_old_generators) | |
592 { | |
593 #define RAND_FUNC(x) F77_FUNC (dgennor, DGENNOR) (0.0, 1.0, x) | |
594 MAKE_RAND (len); | |
595 #undef RAND_FUNC | |
596 } | |
597 else | |
598 oct_fill_randn (len, v); | |
599 break; | |
600 | |
601 case expon_dist: | |
602 if (use_old_generators) | |
603 { | |
604 #define RAND_FUNC(x) F77_FUNC (dgenexp, DGENEXP) (1.0, x) | |
605 MAKE_RAND (len); | |
606 #undef RAND_FUNC | |
607 } | |
608 else | |
609 oct_fill_rande (len, v); | |
610 break; | |
611 | |
612 case poisson_dist: | |
613 if (use_old_generators) | |
614 { | |
615 if (a < 0.0 || xisnan(a) || xisinf(a)) | |
616 #define RAND_FUNC(x) x = octave_NaN; | |
617 MAKE_RAND (len); | |
618 #undef RAND_FUNC | |
619 else | |
620 { | |
621 // workaround bug in ignpoi, by calling with different Mu | |
622 double tmp; | |
623 F77_FUNC (dignpoi, DIGNPOI) (a + 1, tmp); | |
624 #define RAND_FUNC(x) F77_FUNC (dignpoi, DIGNPOI) (a, x) | |
625 MAKE_RAND (len); | |
626 #undef RAND_FUNC | |
627 } | |
628 } | |
629 else | |
630 oct_fill_randp (a, len, v); | |
631 break; | |
632 | |
633 case gamma_dist: | |
634 if (use_old_generators) | |
635 { | |
636 if (a <= 0.0 || xisnan(a) || xisinf(a)) | |
637 #define RAND_FUNC(x) x = octave_NaN; | |
638 MAKE_RAND (len); | |
639 #undef RAND_FUNC | |
640 else | |
641 #define RAND_FUNC(x) F77_FUNC (dgengam, DGENGAM) (1.0, a, x) | |
642 MAKE_RAND (len); | |
643 #undef RAND_FUNC | |
644 } | |
645 else | |
646 oct_fill_randg (a, len, v); | |
647 break; | |
648 | |
649 default: | |
7536 | 650 (*current_liboctave_error_handler) |
651 ("rand: invalid distribution ID = %d", current_distribution); | |
5730 | 652 break; |
653 } | |
654 | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
655 save_state (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
656 |
5730 | 657 return; |
658 } | |
659 | |
4308 | 660 /* |
661 ;;; Local Variables: *** | |
662 ;;; mode: C++ *** | |
663 ;;; End: *** | |
664 */ |