Mercurial > hg > octave-lyh
annotate liboctave/oct-rand.cc @ 10010:c5e9931c7ba7
Correctly produce postcript output for geometryimages when QHULL library is not present
author | Rik <rdrider0-list@yahoo.com> |
---|---|
date | Sun, 20 Dec 2009 17:02:57 -0800 |
parents | 54f45f883a53 |
children | 829e69ec3110 |
rev | line source |
---|---|
4308 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2003, 2005, 2006, 2007, 2008 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" |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
8124
diff
changeset
|
41 #include "oct-locbuf.h" |
4308 | 42 |
43 extern "C" | |
44 { | |
4552 | 45 F77_RET_T |
46 F77_FUNC (dgennor, DGENNOR) (const double&, const double&, double&); | |
4308 | 47 |
4552 | 48 F77_RET_T |
49 F77_FUNC (dgenunf, DGENUNF) (const double&, const double&, double&); | |
50 | |
51 F77_RET_T | |
5730 | 52 F77_FUNC (dgenexp, DGENEXP) (const double&, double&); |
53 | |
54 F77_RET_T | |
55 F77_FUNC (dignpoi, DIGNPOI) (const double&, double&); | |
56 | |
57 F77_RET_T | |
58 F77_FUNC (dgengam, DGENGAM) (const double&, const double&, double&); | |
59 | |
60 F77_RET_T | |
5275 | 61 F77_FUNC (setall, SETALL) (const octave_idx_type&, const octave_idx_type&); |
4308 | 62 |
4552 | 63 F77_RET_T |
5275 | 64 F77_FUNC (getsd, GETSD) (octave_idx_type&, octave_idx_type&); |
4308 | 65 |
4552 | 66 F77_RET_T |
5275 | 67 F77_FUNC (setsd, SETSD) (const octave_idx_type&, const octave_idx_type&); |
4308 | 68 |
4552 | 69 F77_RET_T |
5275 | 70 F77_FUNC (setcgn, SETCGN) (const octave_idx_type&); |
4308 | 71 } |
72 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
73 octave_rand *octave_rand::instance = 0; |
6326 | 74 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
75 octave_rand::octave_rand (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
76 : 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
|
77 rand_states () |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
78 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
79 initialize_ranlib_generators (); |
4308 | 80 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
81 initialize_mersenne_twister (); |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
82 } |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
83 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
84 bool |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
85 octave_rand::instance_ok (void) |
4308 | 86 { |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
87 bool retval = true; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
88 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
89 if (! instance) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
90 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
|
91 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
92 if (! instance) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
93 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
94 (*current_liboctave_error_handler) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
95 ("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
|
96 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
97 retval = false; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
98 } |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
99 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
100 return retval; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
101 } |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
102 |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
103 double |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
104 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
|
105 { |
5275 | 106 union d2i { double d; octave_idx_type i[2]; }; |
4308 | 107 union d2i u; |
6435 | 108 |
109 oct_mach_info::float_format ff = oct_mach_info::native_float_format (); | |
110 | |
111 switch (ff) | |
112 { | |
113 case oct_mach_info::flt_fmt_ieee_big_endian: | |
114 F77_FUNC (getsd, GETSD) (u.i[1], u.i[0]); | |
115 break; | |
116 default: | |
117 F77_FUNC (getsd, GETSD) (u.i[0], u.i[1]); | |
118 break; | |
119 } | |
120 | |
4308 | 121 return u.d; |
122 } | |
123 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
124 static octave_idx_type |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
125 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
|
126 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
127 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
|
128 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
129 i = i > 0 ? i : -i; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
130 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
131 if (i < lo) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
132 i = lo; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
133 else if (i > hi) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
134 i = i % hi; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
135 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
136 return i; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
137 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
138 |
4308 | 139 void |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
140 octave_rand::do_seed (double s) |
4308 | 141 { |
5730 | 142 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
|
143 |
6435 | 144 int i0, i1; |
5275 | 145 union d2i { double d; octave_idx_type i[2]; }; |
4308 | 146 union d2i u; |
147 u.d = s; | |
6435 | 148 |
149 oct_mach_info::float_format ff = oct_mach_info::native_float_format (); | |
150 | |
151 switch (ff) | |
152 { | |
153 case oct_mach_info::flt_fmt_ieee_big_endian: | |
154 i1 = force_to_fit_range (u.i[0], 1, 2147483563); | |
155 i0 = force_to_fit_range (u.i[1], 1, 2147483399); | |
156 break; | |
157 default: | |
158 i0 = force_to_fit_range (u.i[0], 1, 2147483563); | |
159 i1 = force_to_fit_range (u.i[1], 1, 2147483399); | |
160 break; | |
161 } | |
162 | |
4308 | 163 F77_FUNC (setsd, SETSD) (i0, i1); |
164 } | |
165 | |
5730 | 166 ColumnVector |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
167 octave_rand::do_state (const std::string& d) |
5730 | 168 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
169 return rand_states[d.empty () ? current_distribution : get_dist_id (d)]; |
5730 | 170 } |
171 | |
172 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
173 octave_rand::do_state (const ColumnVector& s, const std::string& d) |
5730 | 174 { |
175 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
|
176 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
177 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
|
178 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
179 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
|
180 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
181 ColumnVector saved_state; |
5730 | 182 |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
183 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
|
184 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
|
185 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
186 set_internal_state (s); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
187 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
188 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
|
189 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
190 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
|
191 rand_states[old_dist] = saved_state; |
5730 | 192 } |
193 | |
4308 | 194 std::string |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
195 octave_rand::do_distribution (void) |
4308 | 196 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
197 std::string retval; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
198 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
199 switch (current_distribution) |
4308 | 200 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
201 case uniform_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
202 retval = "uniform"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
203 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
204 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
205 case normal_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
206 retval = "normal"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
207 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
208 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
209 case expon_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
210 retval = "exponential"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
211 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
212 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
213 case poisson_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
214 retval = "poisson"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
215 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
216 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
217 case gamma_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
218 retval = "gamma"; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
219 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
220 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
221 default: |
7536 | 222 (*current_liboctave_error_handler) |
223 ("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
|
224 break; |
4308 | 225 } |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
226 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
227 return retval; |
4308 | 228 } |
229 | |
230 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
231 octave_rand::do_distribution (const std::string& d) |
4308 | 232 { |
7536 | 233 int id = get_dist_id (d); |
234 | |
235 switch (id) | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
236 { |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
237 case uniform_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
238 octave_rand::uniform_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
239 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
240 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
241 case normal_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
242 octave_rand::normal_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
243 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
244 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
245 case expon_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
246 octave_rand::exponential_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
247 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
248 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
249 case poisson_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
250 octave_rand::poisson_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
251 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
252 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
253 case gamma_dist: |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
254 octave_rand::gamma_distribution (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
255 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
256 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
257 default: |
7536 | 258 (*current_liboctave_error_handler) |
259 ("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
|
260 break; |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
261 } |
4308 | 262 } |
263 | |
264 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
265 octave_rand::do_uniform_distribution (void) |
4308 | 266 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
267 switch_to_generator (uniform_dist); |
4308 | 268 |
269 F77_FUNC (setcgn, SETCGN) (uniform_dist); | |
270 } | |
271 | |
272 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
273 octave_rand::do_normal_distribution (void) |
4308 | 274 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
275 switch_to_generator (normal_dist); |
4308 | 276 |
277 F77_FUNC (setcgn, SETCGN) (normal_dist); | |
278 } | |
279 | |
5730 | 280 void |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
281 octave_rand::do_exponential_distribution (void) |
5730 | 282 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
283 switch_to_generator (expon_dist); |
5730 | 284 |
285 F77_FUNC (setcgn, SETCGN) (expon_dist); | |
286 } | |
287 | |
288 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
289 octave_rand::do_poisson_distribution (void) |
5730 | 290 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
291 switch_to_generator (poisson_dist); |
5730 | 292 |
293 F77_FUNC (setcgn, SETCGN) (poisson_dist); | |
294 } | |
295 | |
296 void | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
297 octave_rand::do_gamma_distribution (void) |
5730 | 298 { |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
299 switch_to_generator (gamma_dist); |
5730 | 300 |
301 F77_FUNC (setcgn, SETCGN) (gamma_dist); | |
302 } | |
303 | |
304 | |
4308 | 305 double |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
306 octave_rand::do_scalar (double a) |
4308 | 307 { |
308 double retval = 0.0; | |
309 | |
5730 | 310 if (use_old_generators) |
4308 | 311 { |
5730 | 312 switch (current_distribution) |
313 { | |
314 case uniform_dist: | |
315 F77_FUNC (dgenunf, DGENUNF) (0.0, 1.0, retval); | |
316 break; | |
4308 | 317 |
5730 | 318 case normal_dist: |
319 F77_FUNC (dgennor, DGENNOR) (0.0, 1.0, retval); | |
320 break; | |
4308 | 321 |
5730 | 322 case expon_dist: |
323 F77_FUNC (dgenexp, DGENEXP) (1.0, retval); | |
324 break; | |
4308 | 325 |
5730 | 326 case poisson_dist: |
327 if (a < 0.0 || xisnan(a) || xisinf(a)) | |
328 retval = octave_NaN; | |
329 else | |
330 { | |
331 // workaround bug in ignpoi, by calling with different Mu | |
332 F77_FUNC (dignpoi, DIGNPOI) (a + 1, retval); | |
333 F77_FUNC (dignpoi, DIGNPOI) (a, retval); | |
334 } | |
335 break; | |
4308 | 336 |
5730 | 337 case gamma_dist: |
338 if (a <= 0.0 || xisnan(a) || xisinf(a)) | |
339 retval = octave_NaN; | |
340 else | |
341 F77_FUNC (dgengam, DGENGAM) (1.0, a, retval); | |
342 break; | |
4308 | 343 |
5730 | 344 default: |
7536 | 345 (*current_liboctave_error_handler) |
346 ("rand: invalid distribution ID = %d", current_distribution); | |
5730 | 347 break; |
4308 | 348 } |
349 } | |
350 else | |
4543 | 351 { |
352 switch (current_distribution) | |
353 { | |
354 case uniform_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
355 retval = oct_randu (); |
4543 | 356 break; |
357 | |
358 case normal_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
359 retval = oct_randn (); |
5730 | 360 break; |
361 | |
362 case expon_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
363 retval = oct_rande (); |
5730 | 364 break; |
365 | |
366 case poisson_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
367 retval = oct_randp (a); |
5730 | 368 break; |
369 | |
370 case gamma_dist: | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
371 retval = oct_randg (a); |
4543 | 372 break; |
373 | |
374 default: | |
7536 | 375 (*current_liboctave_error_handler) |
376 ("rand: invalid distribution ID = %d", current_distribution); | |
4543 | 377 break; |
378 } | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
379 |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
380 save_state (); |
4543 | 381 } |
382 | |
383 return retval; | |
384 } | |
385 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
386 Matrix |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
387 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
|
388 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
389 Matrix retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
390 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
391 if (n >= 0 && m >= 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
392 { |
9647
54f45f883a53
optimize & extend randperm
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
393 retval.clear (n, m); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
394 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
395 if (n > 0 && m > 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
396 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
|
397 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
398 else |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
399 (*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
|
400 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
401 return retval; |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
404 NDArray |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
405 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
|
406 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
407 NDArray retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
408 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
409 if (! dims.all_zero ()) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
410 { |
9647
54f45f883a53
optimize & extend randperm
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
411 retval.clear (dims); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
412 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
413 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
|
414 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
415 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
416 return retval; |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
419 Array<double> |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
420 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
|
421 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
422 Array<double> retval; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
423 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
424 if (n > 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
425 { |
9647
54f45f883a53
optimize & extend randperm
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
426 retval.clear (n); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
427 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
428 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
|
429 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
430 else if (n < 0) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
431 (*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
|
432 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
433 return retval; |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
436 // 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
|
437 // 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
|
438 // 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
|
439 // 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
|
440 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
441 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
442 octave_rand::initialize_ranlib_generators (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
443 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
444 octave_localtime tm; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
445 int stored_distribution = current_distribution; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
446 F77_FUNC (setcgn, SETCGN) (uniform_dist); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
447 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
448 int hour = tm.hour() + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
449 int minute = tm.min() + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
450 int second = tm.sec() + 1; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
451 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
452 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
|
453 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
|
454 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
455 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
|
456 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
|
457 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
458 F77_FUNC (setall, SETALL) (s0, s1); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
459 F77_FUNC (setcgn, SETCGN) (stored_distribution); |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
462 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
463 octave_rand::initialize_mersenne_twister (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
464 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
465 oct_init_by_entropy (); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
466 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
467 ColumnVector s = get_internal_state (); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
468 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
469 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
|
470 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
471 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
472 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
473 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
|
474 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
475 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
476 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
477 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
|
478 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
479 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
480 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
481 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
|
482 |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
483 oct_init_by_entropy (); |
d227d096d49e
oct-rand.cc (initialize_mersenne_twister): use separate initializations for each generator
Brian Gough
parents:
7537
diff
changeset
|
484 s = get_internal_state (); |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
485 rand_states[gamma_dist] = s; |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
488 ColumnVector |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
489 octave_rand::get_internal_state (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
490 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
491 ColumnVector s (MT_N + 1); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
492 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
493 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
|
494 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
495 oct_get_state (tmp); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
496 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
497 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
|
498 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
|
499 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
500 return s; |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
503 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
504 octave_rand::save_state (void) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
505 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
506 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
|
507 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
508 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
509 int |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
510 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
|
511 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
512 int retval = unknown_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
513 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
514 if (d == "uniform" || d == "rand") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
515 retval = uniform_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
516 else if (d == "normal" || d == "randn") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
517 retval = normal_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
518 else if (d == "exponential" || d == "rande") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
519 retval = expon_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
520 else if (d == "poisson" || d == "randp") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
521 retval = poisson_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
522 else if (d == "gamma" || d == "randg") |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
523 retval = gamma_dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
524 else |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
525 (*current_liboctave_error_handler) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
526 ("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
|
527 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
528 return retval; |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
531 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
532 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
|
533 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
534 octave_idx_type len = s.length (); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
535 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
|
536 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
537 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
|
538 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
539 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
|
540 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
|
541 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
542 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
|
543 oct_set_state (tmp); |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
544 else |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
545 oct_init_by_array (tmp, len); |
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 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
548 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
549 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
|
550 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
551 if (dist != current_distribution) |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
552 { |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
553 current_distribution = dist; |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
554 |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
555 set_internal_state (rand_states[dist]); |
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 } |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
558 |
5730 | 559 #define MAKE_RAND(len) \ |
4308 | 560 do \ |
561 { \ | |
562 double val; \ | |
5730 | 563 for (volatile octave_idx_type i = 0; i < len; i++) \ |
4308 | 564 { \ |
565 OCTAVE_QUIT; \ | |
5730 | 566 RAND_FUNC (val); \ |
567 v[i] = val; \ | |
4308 | 568 } \ |
569 } \ | |
570 while (0) | |
571 | |
7537
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
572 void |
a2950622f070
make octave_rand a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7536
diff
changeset
|
573 octave_rand::fill (octave_idx_type len, double *v, double a) |
5730 | 574 { |
575 if (len < 1) | |
576 return; | |
577 | |
578 switch (current_distribution) | |
579 { | |
580 case uniform_dist: | |
581 if (use_old_generators) | |
582 { | |
583 #define RAND_FUNC(x) F77_FUNC (dgenunf, DGENUNF) (0.0, 1.0, x) | |
584 MAKE_RAND (len); | |
585 #undef RAND_FUNC | |
586 } | |
587 else | |
588 oct_fill_randu (len, v); | |
589 break; | |
590 | |
591 case normal_dist: | |
592 if (use_old_generators) | |
593 { | |
594 #define RAND_FUNC(x) F77_FUNC (dgennor, DGENNOR) (0.0, 1.0, x) | |
595 MAKE_RAND (len); | |
596 #undef RAND_FUNC | |
597 } | |
598 else | |
599 oct_fill_randn (len, v); | |
600 break; | |
601 | |
602 case expon_dist: | |
603 if (use_old_generators) | |
604 { | |
605 #define RAND_FUNC(x) F77_FUNC (dgenexp, DGENEXP) (1.0, x) | |
606 MAKE_RAND (len); | |
607 #undef RAND_FUNC | |
608 } | |
609 else | |
610 oct_fill_rande (len, v); | |
611 break; | |
612 | |
613 case poisson_dist: | |
614 if (use_old_generators) | |
615 { | |
616 if (a < 0.0 || xisnan(a) || xisinf(a)) | |
617 #define RAND_FUNC(x) x = octave_NaN; | |
618 MAKE_RAND (len); | |
619 #undef RAND_FUNC | |
620 else | |
621 { | |
622 // workaround bug in ignpoi, by calling with different Mu | |
623 double tmp; | |
624 F77_FUNC (dignpoi, DIGNPOI) (a + 1, tmp); | |
625 #define RAND_FUNC(x) F77_FUNC (dignpoi, DIGNPOI) (a, x) | |
626 MAKE_RAND (len); | |
627 #undef RAND_FUNC | |
628 } | |
629 } | |
630 else | |
631 oct_fill_randp (a, len, v); | |
632 break; | |
633 | |
634 case gamma_dist: | |
635 if (use_old_generators) | |
636 { | |
637 if (a <= 0.0 || xisnan(a) || xisinf(a)) | |
638 #define RAND_FUNC(x) x = octave_NaN; | |
639 MAKE_RAND (len); | |
640 #undef RAND_FUNC | |
641 else | |
642 #define RAND_FUNC(x) F77_FUNC (dgengam, DGENGAM) (1.0, a, x) | |
643 MAKE_RAND (len); | |
644 #undef RAND_FUNC | |
645 } | |
646 else | |
647 oct_fill_randg (a, len, v); | |
648 break; | |
649 | |
650 default: | |
7536 | 651 (*current_liboctave_error_handler) |
652 ("rand: invalid distribution ID = %d", current_distribution); | |
5730 | 653 break; |
654 } | |
655 | |
7533
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
656 save_state (); |
ff52243af934
save state separately for each MT random number generator
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
657 |
5730 | 658 return; |
659 } | |
660 | |
4308 | 661 /* |
662 ;;; Local Variables: *** | |
663 ;;; mode: C++ *** | |
664 ;;; End: *** | |
665 */ |