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 /*