Mercurial > hg > octave-lojdl
comparison src/DLD-FUNCTIONS/rand.cc @ 4543:79df15d4470c
[project @ 2003-10-18 03:53:52 by jwe]
author | jwe |
---|---|
date | Sat, 18 Oct 2003 03:53:53 +0000 |
parents | fd034cd46aea |
children | 7b957b442818 |
comparison
equal
deleted
inserted
replaced
4542:2633831cbeb5 | 4543:79df15d4470c |
---|---|
39 #include "oct-obj.h" | 39 #include "oct-obj.h" |
40 #include "unwind-prot.h" | 40 #include "unwind-prot.h" |
41 #include "utils.h" | 41 #include "utils.h" |
42 | 42 |
43 static octave_value | 43 static octave_value |
44 do_rand (const octave_value_list& args, int nargin) | 44 do_rand (const octave_value_list& args, int nargin, const char *fcn) |
45 { | 45 { |
46 octave_value retval; | 46 octave_value retval; |
47 | 47 |
48 volatile int n = 0; | 48 dim_vector dims; |
49 volatile int m = 0; | 49 |
50 | 50 switch (nargin) |
51 if (nargin == 0) | |
52 { | 51 { |
53 n = 1; | 52 case 0: |
54 m = 1; | 53 { |
55 | 54 dims.resize (2); |
56 goto gen_matrix; | 55 |
56 dims(0) = 1; | |
57 dims(1) = 1; | |
58 | |
59 goto gen_matrix; | |
60 } | |
61 break; | |
62 | |
63 case 1: | |
64 { | |
65 octave_value tmp = args(0); | |
66 | |
67 if (tmp.is_string ()) | |
68 { | |
69 std::string s_arg = tmp.string_value (); | |
70 | |
71 if (s_arg == "dist") | |
72 { | |
73 retval = octave_rand::distribution (); | |
74 } | |
75 else if (s_arg == "seed") | |
76 { | |
77 retval = octave_rand::seed (); | |
78 } | |
79 else if (s_arg == "uniform") | |
80 { | |
81 octave_rand::uniform_distribution (); | |
82 } | |
83 else if (s_arg == "normal") | |
84 { | |
85 octave_rand::normal_distribution (); | |
86 } | |
87 else | |
88 error ("rand: unrecognized string argument"); | |
89 } | |
90 else if (tmp.is_scalar_type ()) | |
91 { | |
92 double dval = tmp.double_value (); | |
93 | |
94 if (xisnan (dval)) | |
95 { | |
96 error ("rand: NaN is invalid a matrix dimension"); | |
97 } | |
98 else | |
99 { | |
100 dims.resize (2); | |
101 | |
102 dims(0) = NINT (tmp.double_value ()); | |
103 dims(1) = NINT (tmp.double_value ()); | |
104 | |
105 if (! error_state) | |
106 goto gen_matrix; | |
107 } | |
108 } | |
109 else if (tmp.is_range ()) | |
110 { | |
111 Range r = tmp.range_value (); | |
112 | |
113 if (r.all_elements_are_ints ()) | |
114 { | |
115 int n = r.nelem (); | |
116 | |
117 dims.resize (n); | |
118 | |
119 int base = NINT (r.base ()); | |
120 int incr = NINT (r.inc ()); | |
121 int lim = NINT (r.limit ()); | |
122 | |
123 if (base < 0 || lim < 0) | |
124 error ("rand: all dimensions must be nonnegative"); | |
125 else | |
126 { | |
127 for (int i = 0; i < n; i++) | |
128 { | |
129 dims(i) = base; | |
130 base += incr; | |
131 } | |
132 | |
133 goto gen_matrix; | |
134 } | |
135 } | |
136 else | |
137 error ("rand: expecting all elements of range to be integers"); | |
138 } | |
139 else if (tmp.is_matrix_type ()) | |
140 { | |
141 Array<int> iv = tmp.int_vector_value (true); | |
142 | |
143 if (! error_state) | |
144 { | |
145 int len = iv.length (); | |
146 | |
147 dims.resize (len); | |
148 | |
149 for (int i = 0; i < len; i++) | |
150 { | |
151 int elt = iv(i); | |
152 | |
153 if (elt < 0) | |
154 { | |
155 error ("rand: all dimensions must be nonnegative"); | |
156 goto done; | |
157 } | |
158 | |
159 dims(i) = iv(i); | |
160 } | |
161 | |
162 goto gen_matrix; | |
163 } | |
164 else | |
165 error ("rand: expecting integer vector"); | |
166 } | |
167 else | |
168 { | |
169 gripe_wrong_type_arg ("rand", tmp); | |
170 return retval; | |
171 } | |
172 } | |
173 break; | |
174 | |
175 default: | |
176 { | |
177 octave_value tmp = args(0); | |
178 | |
179 if (nargin == 2 && tmp.is_string ()) | |
180 { | |
181 if (tmp.string_value () == "seed") | |
182 { | |
183 double d = args(1).double_value (); | |
184 | |
185 if (! error_state) | |
186 octave_rand::seed (d); | |
187 } | |
188 else | |
189 error ("rand: unrecognized string argument"); | |
190 } | |
191 else | |
192 { | |
193 int nargin = args.length (); | |
194 | |
195 dims.resize (nargin); | |
196 | |
197 for (int i = 0; i < nargin; i++) | |
198 { | |
199 dims(i) = args(i).int_value (); | |
200 | |
201 if (error_state) | |
202 { | |
203 error ("rand: expecting integer arguments"); | |
204 goto done; | |
205 } | |
206 } | |
207 | |
208 goto gen_matrix; | |
209 } | |
210 } | |
211 break; | |
57 } | 212 } |
58 else if (nargin == 1) | 213 |
59 { | 214 done: |
60 octave_value tmp = args(0); | |
61 | |
62 if (tmp.is_string ()) | |
63 { | |
64 std::string s_arg = tmp.string_value (); | |
65 | |
66 if (s_arg == "dist") | |
67 { | |
68 retval = octave_rand::distribution (); | |
69 } | |
70 else if (s_arg == "seed") | |
71 { | |
72 retval = octave_rand::seed (); | |
73 } | |
74 else if (s_arg == "uniform") | |
75 { | |
76 octave_rand::uniform_distribution (); | |
77 } | |
78 else if (s_arg == "normal") | |
79 { | |
80 octave_rand::normal_distribution (); | |
81 } | |
82 else | |
83 error ("rand: unrecognized string argument"); | |
84 } | |
85 else if (tmp.is_scalar_type ()) | |
86 { | |
87 double dval = tmp.double_value (); | |
88 | |
89 if (xisnan (dval)) | |
90 { | |
91 error ("rand: NaN is invalid a matrix dimension"); | |
92 } | |
93 else | |
94 { | |
95 m = n = NINT (tmp.double_value ()); | |
96 | |
97 if (! error_state) | |
98 goto gen_matrix; | |
99 } | |
100 } | |
101 else if (tmp.is_range ()) | |
102 { | |
103 Range r = tmp.range_value (); | |
104 n = 1; | |
105 m = r.nelem (); | |
106 goto gen_matrix; | |
107 } | |
108 else if (tmp.is_matrix_type ()) | |
109 { | |
110 // XXX FIXME XXX -- this should probably use the function | |
111 // from data.cc. | |
112 | |
113 Matrix a = args(0).matrix_value (); | |
114 | |
115 if (error_state) | |
116 return retval; | |
117 | |
118 n = a.rows (); | |
119 m = a.columns (); | |
120 | |
121 if (n == 1 && m == 2) | |
122 { | |
123 n = NINT (a (0, 0)); | |
124 m = NINT (a (0, 1)); | |
125 } | |
126 else if (n == 2 && m == 1) | |
127 { | |
128 n = NINT (a (0, 0)); | |
129 m = NINT (a (1, 0)); | |
130 } | |
131 else | |
132 warning ("rand (A): use rand (size (A)) instead"); | |
133 | |
134 goto gen_matrix; | |
135 } | |
136 else | |
137 { | |
138 gripe_wrong_type_arg ("rand", tmp); | |
139 return retval; | |
140 } | |
141 } | |
142 else if (nargin == 2) | |
143 { | |
144 if (args(0).is_string ()) | |
145 { | |
146 if (args(0).string_value () == "seed") | |
147 { | |
148 double d = args(1).double_value (); | |
149 | |
150 if (! error_state) | |
151 octave_rand::seed (d); | |
152 } | |
153 else | |
154 error ("rand: unrecognized string argument"); | |
155 } | |
156 else | |
157 { | |
158 double dval = args(0).double_value (); | |
159 | |
160 if (xisnan (dval)) | |
161 { | |
162 error ("rand: NaN is invalid as a matrix dimension"); | |
163 } | |
164 else | |
165 { | |
166 n = NINT (dval); | |
167 | |
168 if (! error_state) | |
169 { | |
170 m = NINT (args(1).double_value ()); | |
171 | |
172 if (! error_state) | |
173 goto gen_matrix; | |
174 } | |
175 } | |
176 } | |
177 } | |
178 | 215 |
179 return retval; | 216 return retval; |
180 | 217 |
181 gen_matrix: | 218 gen_matrix: |
182 | 219 |
183 return octave_rand::matrix (n, m); | 220 return octave_rand::nd_array (dims); |
184 } | 221 } |
185 | 222 |
186 DEFUN_DLD (rand, args, nargout, | 223 DEFUN_DLD (rand, args, nargout, |
187 "-*- texinfo -*-\n\ | 224 "-*- texinfo -*-\n\ |
188 @deftypefn {Loadable Function} {} rand (@var{x})\n\ | 225 @deftypefn {Loadable Function} {} rand (@var{x})\n\ |
211 { | 248 { |
212 octave_value retval; | 249 octave_value retval; |
213 | 250 |
214 int nargin = args.length (); | 251 int nargin = args.length (); |
215 | 252 |
216 if (nargin > 2 || nargout > 1) | 253 retval = do_rand (args, nargin, "rand"); |
217 print_usage ("rand"); | |
218 else | |
219 retval = do_rand (args, nargin); | |
220 | 254 |
221 return retval; | 255 return retval; |
222 } | 256 } |
223 | 257 |
224 static std::string current_distribution = octave_rand::distribution (); | 258 static std::string current_distribution = octave_rand::distribution (); |
256 { | 290 { |
257 octave_value retval; | 291 octave_value retval; |
258 | 292 |
259 int nargin = args.length (); | 293 int nargin = args.length (); |
260 | 294 |
261 if (nargin > 2 || nargout > 1) | 295 unwind_protect::begin_frame ("randn"); |
262 print_usage ("randn"); | 296 |
263 else | 297 // This relies on the fact that elements are popped from the unwind |
264 { | 298 // stack in the reverse of the order they are pushed |
265 unwind_protect::begin_frame ("randn"); | 299 // (i.e. current_distribution will be reset before calling |
266 | 300 // reset_rand_generator()). |
267 // This relies on the fact that elements are popped from the | 301 |
268 // unwind stack in the reverse of the order they are pushed | 302 unwind_protect::add (reset_rand_generator, 0); |
269 // (i.e. current_distribution will be reset before calling | 303 unwind_protect_str (current_distribution); |
270 // reset_rand_generator()). | 304 |
271 | 305 current_distribution = "normal"; |
272 unwind_protect::add (reset_rand_generator, 0); | 306 |
273 unwind_protect_str (current_distribution); | 307 octave_rand::distribution (current_distribution); |
274 | 308 |
275 current_distribution = "normal"; | 309 retval = do_rand (args, nargin, "randn"); |
276 | 310 |
277 octave_rand::distribution (current_distribution); | 311 unwind_protect::run_frame ("randn"); |
278 | |
279 retval = do_rand (args, nargin); | |
280 | |
281 unwind_protect::run_frame ("randn"); | |
282 } | |
283 | 312 |
284 return retval; | 313 return retval; |
285 } | 314 } |
286 | 315 |
287 /* | 316 /* |