GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rand.cc
Go to the documentation of this file.
1 
2 /*
3 
4 Copyright (C) 1996-2013 John W. Eaton
5 Copyright (C) 2009 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #include <ctime>
30 #if defined (HAVE_UNORDERED_MAP)
31 #include <unordered_map>
32 #elif defined (HAVE_TR1_UNORDERED_MAP)
33 #include <tr1/unordered_map>
34 #endif
35 #include <string>
36 
37 #include "f77-fcn.h"
38 #include "lo-mappers.h"
39 #include "oct-rand.h"
40 #include "quit.h"
41 
42 #include "defun.h"
43 #include "error.h"
44 #include "gripes.h"
45 #include "oct-obj.h"
46 #include "unwind-prot.h"
47 #include "utils.h"
48 #include "ov-re-mat.h"
49 
50 /*
51 %!shared __random_statistical_tests__
52 %! ## Flag whether the statistical tests should be run in "make check" or not
53 %! __random_statistical_tests__ = 0;
54 */
55 
56 static octave_value
57 do_rand (const octave_value_list& args, int nargin, const char *fcn,
58  const std::string& distribution, bool additional_arg = false)
59 {
60  octave_value retval;
61  NDArray a;
62  int idx = 0;
63  dim_vector dims;
64  bool is_single = false;
65 
66  unwind_protect frame;
67  // Restore current distribution on any exit.
70 
71  octave_rand::distribution (distribution);
72 
73  if (nargin > 0 && args(nargin-1).is_string ())
74  {
75  std::string s_arg = args(nargin-1).string_value ();
76 
77  if (s_arg == "single")
78  {
79  is_single = true;
80  nargin--;
81  }
82  else if (s_arg == "double")
83  nargin--;
84  }
85 
86  if (additional_arg)
87  {
88  if (nargin == 0)
89  {
90  error ("%s: expecting at least one argument", fcn);
91  goto done;
92  }
93  else if (args(0).is_string ())
94  additional_arg = false;
95  else
96  {
97  a = args(0).array_value ();
98  if (error_state)
99  {
100  error ("%s: expecting scalar or matrix arguments", fcn);
101  goto done;
102  }
103  idx++;
104  nargin--;
105  }
106  }
107 
108  switch (nargin)
109  {
110  case 0:
111  {
112  if (additional_arg)
113  dims = a.dims ();
114  else
115  {
116  dims.resize (2);
117 
118  dims(0) = 1;
119  dims(1) = 1;
120  }
121  goto gen_matrix;
122  }
123  break;
124 
125  case 1:
126  {
127  octave_value tmp = args(idx);
128 
129  if (tmp.is_string ())
130  {
131  std::string s_arg = tmp.string_value ();
132 
133  if (s_arg == "dist")
134  {
135  retval = octave_rand::distribution ();
136  }
137  else if (s_arg == "seed")
138  {
139  retval = octave_rand::seed ();
140  }
141  else if (s_arg == "state" || s_arg == "twister")
142  {
143  retval = octave_rand::state (fcn);
144  }
145  else if (s_arg == "uniform")
146  {
148  }
149  else if (s_arg == "normal")
150  {
152  }
153  else if (s_arg == "exponential")
154  {
156  }
157  else if (s_arg == "poisson")
158  {
160  }
161  else if (s_arg == "gamma")
162  {
164  }
165  else
166  error ("%s: unrecognized string argument", fcn);
167  }
168  else if (tmp.is_scalar_type ())
169  {
170  double dval = tmp.double_value ();
171 
172  if (xisnan (dval))
173  {
174  error ("%s: NaN is invalid matrix dimension", fcn);
175  }
176  else
177  {
178  dims.resize (2);
179 
180  dims(0) = NINTbig (tmp.double_value ());
181  dims(1) = NINTbig (tmp.double_value ());
182 
183  if (! error_state)
184  goto gen_matrix;
185  }
186  }
187  else if (tmp.is_range ())
188  {
189  Range r = tmp.range_value ();
190 
191  if (r.all_elements_are_ints ())
192  {
193  octave_idx_type n = r.nelem ();
194 
195  dims.resize (n);
196 
197  octave_idx_type base = NINTbig (r.base ());
198  octave_idx_type incr = NINTbig (r.inc ());
199 
200  for (octave_idx_type i = 0; i < n; i++)
201  {
202  //Negative dimensions are treated as zero for Matlab
203  //compatibility
204  dims(i) = base >= 0 ? base : 0;
205  base += incr;
206  }
207 
208  goto gen_matrix;
209 
210  }
211  else
212  error ("%s: all elements of range must be integers",
213  fcn);
214  }
215  else if (tmp.is_matrix_type ())
216  {
217  Array<int> iv = tmp.int_vector_value (true);
218 
219  if (! error_state)
220  {
221  octave_idx_type len = iv.length ();
222 
223  dims.resize (len);
224 
225  for (octave_idx_type i = 0; i < len; i++)
226  {
227  //Negative dimensions are treated as zero for Matlab
228  //compatibility
229  octave_idx_type elt = iv(i);
230  dims(i) = elt >=0 ? elt : 0;
231  }
232 
233  goto gen_matrix;
234  }
235  else
236  error ("%s: expecting integer vector", fcn);
237  }
238  else
239  {
240  gripe_wrong_type_arg ("rand", tmp);
241  return retval;
242  }
243  }
244  break;
245 
246  default:
247  {
248  octave_value tmp = args(idx);
249 
250  if (nargin == 2 && tmp.is_string ())
251  {
252  std::string ts = tmp.string_value ();
253 
254  if (ts == "seed")
255  {
256  if (args(idx+1).is_real_scalar ())
257  {
258  double d = args(idx+1).double_value ();
259 
260  if (! error_state)
261  octave_rand::seed (d);
262  }
263  else if (args(idx+1).is_string ()
264  && args(idx+1).string_value () == "reset")
266  else
267  error ("%s: seed must be a real scalar", fcn);
268  }
269  else if (ts == "state" || ts == "twister")
270  {
271  if (args(idx+1).is_string ()
272  && args(idx+1).string_value () == "reset")
273  octave_rand::reset (fcn);
274  else
275  {
276  ColumnVector s =
277  ColumnVector (args(idx+1).vector_value(false, true));
278 
279  if (! error_state)
280  octave_rand::state (s, fcn);
281  }
282  }
283  else
284  error ("%s: unrecognized string argument", fcn);
285  }
286  else
287  {
288  dims.resize (nargin);
289 
290  for (int i = 0; i < nargin; i++)
291  {
292  octave_idx_type elt = args(idx+i).int_value ();
293  if (error_state)
294  {
295  error ("%s: expecting integer arguments", fcn);
296  goto done;
297  }
298  //Negative is zero for Matlab compatibility
299  dims(i) = elt >= 0 ? elt : 0;
300  }
301 
302  goto gen_matrix;
303  }
304  }
305  break;
306  }
307 
308 done:
309 
310  return retval;
311 
312 gen_matrix:
313 
314  dims.chop_trailing_singletons ();
315 
316  if (is_single)
317  {
318  if (additional_arg)
319  {
320  if (a.length () == 1)
321  return octave_rand::float_nd_array (dims, a(0));
322  else
323  {
324  if (a.dims () != dims)
325  {
326  error ("%s: mismatch in argument size", fcn);
327  return retval;
328  }
329  octave_idx_type len = a.length ();
330  FloatNDArray m (dims);
331  float *v = m.fortran_vec ();
332  for (octave_idx_type i = 0; i < len; i++)
333  v[i] = octave_rand::float_scalar (a(i));
334  return m;
335  }
336  }
337  else
338  return octave_rand::float_nd_array (dims);
339  }
340  else
341  {
342  if (additional_arg)
343  {
344  if (a.length () == 1)
345  return octave_rand::nd_array (dims, a(0));
346  else
347  {
348  if (a.dims () != dims)
349  {
350  error ("%s: mismatch in argument size", fcn);
351  return retval;
352  }
353  octave_idx_type len = a.length ();
354  NDArray m (dims);
355  double *v = m.fortran_vec ();
356  for (octave_idx_type i = 0; i < len; i++)
357  v[i] = octave_rand::scalar (a(i));
358  return m;
359  }
360  }
361  else
362  return octave_rand::nd_array (dims);
363  }
364 }
365 
366 DEFUN (rand, args, ,
367  "-*- texinfo -*-\n\
368 @deftypefn {Built-in Function} {} rand (@var{n})\n\
369 @deftypefnx {Built-in Function} {} rand (@var{n}, @var{m}, @dots{})\n\
370 @deftypefnx {Built-in Function} {} rand ([@var{n} @var{m} @dots{}])\n\
371 @deftypefnx {Built-in Function} {@var{v} =} rand (\"state\")\n\
372 @deftypefnx {Built-in Function} {} rand (\"state\", @var{v})\n\
373 @deftypefnx {Built-in Function} {} rand (\"state\", \"reset\")\n\
374 @deftypefnx {Built-in Function} {@var{v} =} rand (\"seed\")\n\
375 @deftypefnx {Built-in Function} {} rand (\"seed\", @var{v})\n\
376 @deftypefnx {Built-in Function} {} rand (\"seed\", \"reset\")\n\
377 @deftypefnx {Built-in Function} {} rand (@dots{}, \"single\")\n\
378 @deftypefnx {Built-in Function} {} rand (@dots{}, \"double\")\n\
379 Return a matrix with random elements uniformly distributed on the\n\
380 interval (0, 1). The arguments are handled the same as the arguments\n\
381 for @code{eye}.\n\
382 \n\
383 You can query the state of the random number generator using the\n\
384 form\n\
385 \n\
386 @example\n\
387 v = rand (\"state\")\n\
388 @end example\n\
389 \n\
390 This returns a column vector @var{v} of length 625. Later, you can\n\
391 restore the random number generator to the state @var{v}\n\
392 using the form\n\
393 \n\
394 @example\n\
395 rand (\"state\", v)\n\
396 @end example\n\
397 \n\
398 @noindent\n\
399 You may also initialize the state vector from an arbitrary vector of\n\
400 length @leq{} 625 for @var{v}. This new state will be a hash based on the\n\
401 value of @var{v}, not @var{v} itself.\n\
402 \n\
403 By default, the generator is initialized from @code{/dev/urandom} if it is\n\
404 available, otherwise from CPU time, wall clock time, and the current\n\
405 fraction of a second. Note that this differs from @sc{matlab}, which\n\
406 always initializes the state to the same state at startup. To obtain\n\
407 behavior comparable to @sc{matlab}, initialize with a deterministic state\n\
408 vector in Octave's startup files (@pxref{Startup Files}).\n\
409 \n\
410 To compute the pseudo-random sequence, @code{rand} uses the Mersenne\n\
411 Twister with a period of @math{2^{19937}-1} (See M. Matsumoto and\n\
412 T. Nishimura,\n\
413 @cite{Mersenne Twister: A 623-dimensionally equidistributed uniform\n\
414 pseudorandom number generator}, ACM Trans. on\n\
415 Modeling and Computer Simulation Vol. 8, No. 1, pp. 3-30, January 1998,\n\
416 @url{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html}).\n\
417 Do @strong{not} use for cryptography without securely hashing\n\
418 several returned values together, otherwise the generator state\n\
419 can be learned after reading 624 consecutive values.\n\
420 \n\
421 Older versions of Octave used a different random number generator.\n\
422 The new generator is used by default\n\
423 as it is significantly faster than the old generator, and produces\n\
424 random numbers with a significantly longer cycle time. However, in\n\
425 some circumstances it might be desirable to obtain the same random\n\
426 sequences as used by the old generators. To do this the keyword\n\
427 @qcode{\"seed\"} is used to specify that the old generators should be use,\n\
428 as in\n\
429 \n\
430 @example\n\
431 rand (\"seed\", val)\n\
432 @end example\n\
433 \n\
434 @noindent\n\
435 which sets the seed of the generator to @var{val}. The seed of the\n\
436 generator can be queried with\n\
437 \n\
438 @example\n\
439 s = rand (\"seed\")\n\
440 @end example\n\
441 \n\
442 However, it should be noted that querying the seed will not cause\n\
443 @code{rand} to use the old generators, only setting the seed will.\n\
444 To cause @code{rand} to once again use the new generators, the\n\
445 keyword @qcode{\"state\"} should be used to reset the state of the\n\
446 @code{rand}.\n\
447 \n\
448 The state or seed of the generator can be reset to a new random value\n\
449 using the @qcode{\"reset\"} keyword.\n\
450 \n\
451 The class of the value returned can be controlled by a trailing\n\
452 @qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\
453 classes.\n\
454 @seealso{randn, rande, randg, randp}\n\
455 @end deftypefn")
456 {
457  octave_value retval;
458 
459  int nargin = args.length ();
460 
461  retval = do_rand (args, nargin, "rand", "uniform");
462 
463  return retval;
464 }
465 
466 // FIXME: The old generator (selected when "seed" is set) will not
467 // work properly if compiled to use 64-bit integers.
468 
469 /*
470 %!test # "state" can be a scalar
471 %! rand ("state", 12); x = rand (1,4);
472 %! rand ("state", 12); y = rand (1,4);
473 %! assert (x, y);
474 %!test # "state" can be a vector
475 %! rand ("state", [12,13]); x = rand (1,4);
476 %! rand ("state", [12;13]); y = rand (1,4);
477 %! assert (x, y);
478 %!test # querying "state" doesn't disturb sequence
479 %! rand ("state", 12); rand (1,2); x = rand (1,2);
480 %! rand ("state", 12); rand (1,2);
481 %! s = rand ("state"); y = rand (1,2);
482 %! assert (x, y);
483 %! rand ("state", s); z = rand (1,2);
484 %! assert (x, z);
485 %!test # "seed" must be a scalar
486 %! rand ("seed", 12); x = rand (1,4);
487 %! rand ("seed", 12); y = rand (1,4);
488 %! assert (x, y);
489 %!error <seed must be a real scalar> rand ("seed", [12,13])
490 %!test # querying "seed" returns a value which can be used later
491 %! s = rand ("seed"); x = rand (1,2);
492 %! rand ("seed", s); y = rand (1,2);
493 %! assert (x, y);
494 %!test # querying "seed" doesn't disturb sequence
495 %! rand ("seed", 12); rand (1,2); x = rand (1,2);
496 %! rand ("seed", 12); rand (1,2);
497 %! s = rand ("seed"); y = rand (1,2);
498 %! assert (x, y);
499 %! rand ("seed", s); z = rand (1,2);
500 %! assert (x, z);
501 */
502 
503 /*
504 %!test
505 %! ## Test fixed state
506 %! rand ("state", 1);
507 %! assert (rand (1,6), [0.1343642441124013 0.8474337369372327 0.763774618976614 0.2550690257394218 0.495435087091941 0.4494910647887382], 1e-6);
508 %!test
509 %! ## Test fixed seed
510 %! rand ("seed", 1);
511 %! assert (rand (1,6), [0.8668024251237512 0.9126510815694928 0.09366085007786751 0.1664607301354408 0.7408077004365623 0.7615650338120759], 1e-6);
512 %!test
513 %! if (__random_statistical_tests__)
514 %! ## statistical tests may fail occasionally.
515 %! rand ("state", 12);
516 %! x = rand (100000, 1);
517 %! assert (max (x) < 1); #*** Please report this!!! ***
518 %! assert (min (x) > 0); #*** Please report this!!! ***
519 %! assert (mean (x), 0.5, 0.0024);
520 %! assert (var (x), 1/48, 0.0632);
521 %! assert (skewness (x), 0, 0.012);
522 %! assert (kurtosis (x), -6/5, 0.0094);
523 %! endif
524 %!test
525 %! if (__random_statistical_tests__)
526 %! ## statistical tests may fail occasionally.
527 %! rand ("seed", 12);
528 %! x = rand (100000, 1);
529 %! assert (max (x) < 1); #*** Please report this!!! ***
530 %! assert (min (x) > 0); #*** Please report this!!! ***
531 %! assert (mean (x), 0.5, 0.0024);
532 %! assert (var (x), 1/48, 0.0632);
533 %! assert (skewness (x), 0, 0.012);
534 %! assert (kurtosis (x), -6/5, 0.0094);
535 %! endif
536 */
537 
538 /*
539 %!# Test out-of-range values as rand() seeds. See oct-rand.cc: double2uint32().
540 %!function v = __rand_sample__ (initval)
541 %! rand ("state", initval);
542 %! v = rand (1, 6);
543 %!endfunction
544 %!
545 %!assert (__rand_sample__ (0), __rand_sample__ (2^32))
546 %!assert (__rand_sample__ (-2), __rand_sample__ (2^32-2))
547 %!assert (__rand_sample__ (Inf), __rand_sample__ (NaN))
548 %!assert (! isequal (__rand_sample__ (-1), __rand_sample__ (-2)))
549 */
550 
552 
553 DEFUN (randn, args, ,
554  "-*- texinfo -*-\n\
555 @deftypefn {Built-in Function} {} randn (@var{n})\n\
556 @deftypefnx {Built-in Function} {} randn (@var{n}, @var{m}, @dots{})\n\
557 @deftypefnx {Built-in Function} {} randn ([@var{n} @var{m} @dots{}])\n\
558 @deftypefnx {Built-in Function} {@var{v} =} randn (\"state\")\n\
559 @deftypefnx {Built-in Function} {} randn (\"state\", @var{v})\n\
560 @deftypefnx {Built-in Function} {} randn (\"state\", \"reset\")\n\
561 @deftypefnx {Built-in Function} {@var{v} =} randn (\"seed\")\n\
562 @deftypefnx {Built-in Function} {} randn (\"seed\", @var{v})\n\
563 @deftypefnx {Built-in Function} {} randn (\"seed\", \"reset\")\n\
564 @deftypefnx {Built-in Function} {} randn (@dots{}, \"single\")\n\
565 @deftypefnx {Built-in Function} {} randn (@dots{}, \"double\")\n\
566 Return a matrix with normally distributed random\n\
567 elements having zero mean and variance one. The arguments are\n\
568 handled the same as the arguments for @code{rand}.\n\
569 \n\
570 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
571 to transform from a uniform to a normal distribution.\n\
572 \n\
573 The class of the value returned can be controlled by a trailing\n\
574 @qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\
575 classes.\n\
576 \n\
577 Reference: G. Marsaglia and W.W. Tsang,\n\
578 @cite{Ziggurat Method for Generating Random Variables},\n\
579 J. Statistical Software, vol 5, 2000,\n\
580 @url{http://www.jstatsoft.org/v05/i08/})\n\
581 \n\
582 @seealso{rand, rande, randg, randp}\n\
583 @end deftypefn")
584 {
585  octave_value retval;
586 
587  int nargin = args.length ();
588 
589  retval = do_rand (args, nargin, "randn", "normal");
590 
591  return retval;
592 }
593 
594 /*
595 %!test
596 %! ## Test fixed state
597 %! randn ("state", 1);
598 %! assert (randn (1, 6), [-2.666521678978671 -0.7381719971724564 1.507903992673601 0.6019427189162239 -0.450661261143348 -0.7054431351574116], 1e-6);
599 %!test
600 %! ## Test fixed seed
601 %! randn ("seed", 1);
602 %! assert (randn (1, 6), [-1.039402365684509 -1.25938892364502 0.1968704611063004 0.3874166905879974 -0.5976632833480835 -0.6615074276924133], 1e-6);
603 %!test
604 %! if (__random_statistical_tests__)
605 %! ## statistical tests may fail occasionally.
606 %! randn ("state", 12);
607 %! x = randn (100000, 1);
608 %! assert (mean (x), 0, 0.01);
609 %! assert (var (x), 1, 0.02);
610 %! assert (skewness (x), 0, 0.02);
611 %! assert (kurtosis (x), 0, 0.04);
612 %! endif
613 %!test
614 %! if (__random_statistical_tests__)
615 %! ## statistical tests may fail occasionally.
616 %! randn ("seed", 12);
617 %! x = randn (100000, 1);
618 %! assert (mean (x), 0, 0.01);
619 %! assert (var (x), 1, 0.02);
620 %! assert (skewness (x), 0, 0.02);
621 %! assert (kurtosis (x), 0, 0.04);
622 %! endif
623 */
624 
625 DEFUN (rande, args, ,
626  "-*- texinfo -*-\n\
627 @deftypefn {Built-in Function} {} rande (@var{n})\n\
628 @deftypefnx {Built-in Function} {} rande (@var{n}, @var{m}, @dots{})\n\
629 @deftypefnx {Built-in Function} {} rande ([@var{n} @var{m} @dots{}])\n\
630 @deftypefnx {Built-in Function} {@var{v} =} rande (\"state\")\n\
631 @deftypefnx {Built-in Function} {} rande (\"state\", @var{v})\n\
632 @deftypefnx {Built-in Function} {} rande (\"state\", \"reset\")\n\
633 @deftypefnx {Built-in Function} {@var{v} =} rande (\"seed\")\n\
634 @deftypefnx {Built-in Function} {} rande (\"seed\", @var{v})\n\
635 @deftypefnx {Built-in Function} {} rande (\"seed\", \"reset\")\n\
636 @deftypefnx {Built-in Function} {} rande (@dots{}, \"single\")\n\
637 @deftypefnx {Built-in Function} {} rande (@dots{}, \"double\")\n\
638 Return a matrix with exponentially distributed random elements. The\n\
639 arguments are handled the same as the arguments for @code{rand}.\n\
640 \n\
641 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
642 to transform from a uniform to an exponential distribution.\n\
643 \n\
644 The class of the value returned can be controlled by a trailing\n\
645 @qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\
646 classes.\n\
647 \n\
648 Reference: G. Marsaglia and W.W. Tsang,\n\
649 @cite{Ziggurat Method for Generating Random Variables},\n\
650 J. Statistical Software, vol 5, 2000,\n\
651 @url{http://www.jstatsoft.org/v05/i08/})\n\
652 \n\
653 @seealso{rand, randn, randg, randp}\n\
654 @end deftypefn")
655 {
656  octave_value retval;
657 
658  int nargin = args.length ();
659 
660  retval = do_rand (args, nargin, "rande", "exponential");
661 
662  return retval;
663 }
664 
665 /*
666 %!test
667 %! ## Test fixed state
668 %! rande ("state", 1);
669 %! assert (rande (1, 6), [3.602973885835625 0.1386190677555021 0.6743112889616958 0.4512830847258422 0.7255744741233175 0.3415969205292291], 1e-6);
670 %!test
671 %! ## Test fixed seed
672 %! rande ("seed", 1);
673 %! assert (rande (1, 6), [0.06492075175653866 1.717980206012726 0.4816154008731246 0.5231300676241517 0.103910739364359 1.668931916356087], 1e-6);
674 %!test
675 %! if (__random_statistical_tests__)
676 %! ## statistical tests may fail occasionally
677 %! rande ("state", 1);
678 %! x = rande (100000, 1);
679 %! assert (min (x) > 0); # *** Please report this!!! ***
680 %! assert (mean (x), 1, 0.01);
681 %! assert (var (x), 1, 0.03);
682 %! assert (skewness (x), 2, 0.06);
683 %! assert (kurtosis (x), 6, 0.7);
684 %! endif
685 %!test
686 %! if (__random_statistical_tests__)
687 %! ## statistical tests may fail occasionally
688 %! rande ("seed", 1);
689 %! x = rande (100000, 1);
690 %! assert (min (x)>0); # *** Please report this!!! ***
691 %! assert (mean (x), 1, 0.01);
692 %! assert (var (x), 1, 0.03);
693 %! assert (skewness (x), 2, 0.06);
694 %! assert (kurtosis (x), 6, 0.7);
695 %! endif
696 */
697 
698 DEFUN (randg, args, ,
699  "-*- texinfo -*-\n\
700 @deftypefn {Built-in Function} {} randg (@var{n})\n\
701 @deftypefnx {Built-in Function} {} randg (@var{n}, @var{m}, @dots{})\n\
702 @deftypefnx {Built-in Function} {} randg ([@var{n} @var{m} @dots{}])\n\
703 @deftypefnx {Built-in Function} {@var{v} =} randg (\"state\")\n\
704 @deftypefnx {Built-in Function} {} randg (\"state\", @var{v})\n\
705 @deftypefnx {Built-in Function} {} randg (\"state\", \"reset\")\n\
706 @deftypefnx {Built-in Function} {@var{v} =} randg (\"seed\")\n\
707 @deftypefnx {Built-in Function} {} randg (\"seed\", @var{v})\n\
708 @deftypefnx {Built-in Function} {} randg (\"seed\", \"reset\")\n\
709 @deftypefnx {Built-in Function} {} randg (@dots{}, \"single\")\n\
710 @deftypefnx {Built-in Function} {} randg (@dots{}, \"double\")\n\
711 Return a matrix with @code{gamma (@var{a},1)} distributed random elements.\n\
712 The arguments are handled the same as the arguments for @code{rand},\n\
713 except for the argument @var{a}.\n\
714 \n\
715 This can be used to generate many distributions:\n\
716 \n\
717 @table @asis\n\
718 @item @code{gamma (a, b)} for @code{a > -1}, @code{b > 0}\n\
719 \n\
720 @example\n\
721 r = b * randg (a)\n\
722 @end example\n\
723 \n\
724 @item @code{beta (a, b)} for @code{a > -1}, @code{b > -1}\n\
725 \n\
726 @example\n\
727 @group\n\
728 r1 = randg (a, 1)\n\
729 r = r1 / (r1 + randg (b, 1))\n\
730 @end group\n\
731 @end example\n\
732 \n\
733 @item @code{Erlang (a, n)}\n\
734 \n\
735 @example\n\
736 r = a * randg (n)\n\
737 @end example\n\
738 \n\
739 @item @code{chisq (df)} for @code{df > 0}\n\
740 \n\
741 @example\n\
742 r = 2 * randg (df / 2)\n\
743 @end example\n\
744 \n\
745 @item @code{t (df)} for @code{0 < df < inf} (use randn if df is infinite)\n\
746 \n\
747 @example\n\
748 r = randn () / sqrt (2 * randg (df / 2) / df)\n\
749 @end example\n\
750 \n\
751 @item @code{F (n1, n2)} for @code{0 < n1}, @code{0 < n2}\n\
752 \n\
753 @example\n\
754 @group\n\
755 ## r1 equals 1 if n1 is infinite\n\
756 r1 = 2 * randg (n1 / 2) / n1\n\
757 ## r2 equals 1 if n2 is infinite\n\
758 r2 = 2 * randg (n2 / 2) / n2\n\
759 r = r1 / r2\n\n\
760 @end group\n\
761 @end example\n\
762 \n\
763 @item negative @code{binomial (n, p)} for @code{n > 0}, @code{0 < p <= 1}\n\
764 \n\
765 @example\n\
766 r = randp ((1 - p) / p * randg (n))\n\
767 @end example\n\
768 \n\
769 @item non-central @code{chisq (df, L)}, for @code{df >= 0} and @code{L > 0}\n\
770 (use chisq if @code{L = 0})\n\
771 \n\
772 @example\n\
773 @group\n\
774 r = randp (L / 2)\n\
775 r(r > 0) = 2 * randg (r(r > 0))\n\
776 r(df > 0) += 2 * randg (df(df > 0)/2)\n\
777 @end group\n\
778 @end example\n\
779 \n\
780 @item @code{Dirichlet (a1, @dots{} ak)}\n\
781 \n\
782 @example\n\
783 @group\n\
784 r = (randg (a1), @dots{}, randg (ak))\n\
785 r = r / sum (r)\n\
786 @end group\n\
787 @end example\n\
788 \n\
789 @end table\n\
790 \n\
791 The class of the value returned can be controlled by a trailing\n\
792 @qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\
793 classes.\n\
794 @seealso{rand, randn, rande, randp}\n\
795 @end deftypefn")
796 {
797  octave_value retval;
798 
799  int nargin = args.length ();
800 
801  if (nargin < 1)
802  error ("randg: insufficient arguments");
803  else
804  retval = do_rand (args, nargin, "randg", "gamma", true);
805 
806  return retval;
807 }
808 
809 /*
810 %!test
811 %! randg ("state", 12)
812 %! assert (randg ([-inf, -1, 0, inf, nan]), [nan, nan, nan, nan, nan]); # *** Please report
813 
814 %!test
815 %! ## Test fixed state
816 %! randg ("state", 1);
817 %! assert (randg (0.1, 1, 6), [0.0103951513331241 8.335671459898252e-05 0.00138691397249762 0.000587308416993855 0.495590518784736 2.3921917414795e-12], 1e-6);
818 %!test
819 %! ## Test fixed state
820 %! randg ("state", 1);
821 %! assert (randg (0.95, 1, 6), [3.099382433255327 0.3974529788871218 0.644367450750855 1.143261091802246 1.964111762696822 0.04011915547957939], 1e-6);
822 %!test
823 %! ## Test fixed state
824 %! randg ("state", 1);
825 %! assert (randg (1, 1, 6), [0.2273389379645993 1.288822625058359 0.2406335209340746 1.218869553370733 1.024649860162554 0.09631230343599533], 1e-6);
826 %!test
827 %! ## Test fixed state
828 %! randg ("state", 1);
829 %! assert (randg (10, 1, 6), [3.520369644331133 15.15369864472106 8.332112081991205 8.406211067432674 11.81193475187611 10.88792728177059], 1e-5);
830 %!test
831 %! ## Test fixed state
832 %! randg ("state", 1);
833 %! assert (randg (100, 1, 6), [75.34570255262264 115.4911985594699 95.23493031356388 95.48926019250911 106.2397448229803 103.4813150404118], 1e-4);
834 %!test
835 %! ## Test fixed seed
836 %! randg ("seed", 1);
837 %! assert (randg (0.1, 1, 6), [0.07144210487604141 0.460641473531723 0.4749028384685516 0.06823389977216721 0.000293838675133884 1.802567535340305e-12], 1e-6);
838 %!test
839 %! ## Test fixed seed
840 %! randg ("seed", 1);
841 %! assert (randg (0.95, 1, 6), [1.664905071258545 1.879976987838745 1.905677795410156 0.9948706030845642 0.5606933236122131 0.0766092911362648], 1e-6);
842 %!test
843 %! ## Test fixed seed
844 %! randg ("seed", 1);
845 %! assert (randg (1, 1, 6), [0.03512085229158401 0.6488978862762451 0.8114678859710693 0.1666885763406754 1.60791552066803 1.90356981754303], 1e-6);
846 %!test
847 %! ## Test fixed seed
848 %! randg ("seed", 1);
849 %! assert (randg (10, 1, 6), [6.566435813903809 10.11648464202881 10.73162078857422 7.747178077697754 6.278522491455078 6.240195751190186], 1e-5);
850 %!test
851 %! ## Test fixed seed
852 %! randg ("seed", 1);
853 %! assert (randg (100, 1, 6), [89.40208435058594 101.4734725952148 103.4020004272461 93.62763214111328 88.33104705810547 88.1871337890625], 1e-4);
854 
855 %!test
856 %! if (__random_statistical_tests__)
857 %! ## statistical tests may fail occasionally.
858 %! randg ("state", 12);
859 %! a = 0.1;
860 %! x = randg (a, 100000, 1);
861 %! assert (mean (x), a, 0.01);
862 %! assert (var (x), a, 0.01);
863 %! assert (skewness (x), 2/sqrt (a), 1);
864 %! assert (kurtosis (x), 6/a, 50);
865 %! endif
866 %!test
867 %! if (__random_statistical_tests__)
868 %! ## statistical tests may fail occasionally.
869 %! randg ("state", 12);
870 %! a = 0.95;
871 %! x = randg (a, 100000, 1);
872 %! assert (mean (x), a, 0.01);
873 %! assert (var (x), a, 0.04);
874 %! assert (skewness (x), 2/sqrt (a), 0.2);
875 %! assert (kurtosis (x), 6/a, 2);
876 %! endif
877 %!test
878 %! if (__random_statistical_tests__)
879 %! ## statistical tests may fail occasionally.
880 %! randg ("state", 12);
881 %! a = 1;
882 %! x = randg (a, 100000, 1);
883 %! assert (mean (x), a, 0.01);
884 %! assert (var (x), a, 0.04);
885 %! assert (skewness (x), 2/sqrt (a), 0.2);
886 %! assert (kurtosis (x), 6/a, 2);
887 %! endif
888 %!test
889 %! if (__random_statistical_tests__)
890 %! ## statistical tests may fail occasionally.
891 %! randg ("state", 12);
892 %! a = 10;
893 %! x = randg (a, 100000, 1);
894 %! assert (mean (x), a, 0.1);
895 %! assert (var (x), a, 0.5);
896 %! assert (skewness (x), 2/sqrt (a), 0.1);
897 %! assert (kurtosis (x), 6/a, 0.5);
898 %! endif
899 %!test
900 %! if (__random_statistical_tests__)
901 %! ## statistical tests may fail occasionally.
902 %! randg ("state", 12);
903 %! a = 100;
904 %! x = randg (a, 100000, 1);
905 %! assert (mean (x), a, 0.2);
906 %! assert (var (x), a, 2);
907 %! assert (skewness (x), 2/sqrt (a), 0.05);
908 %! assert (kurtosis (x), 6/a, 0.2);
909 %! endif
910 %!test
911 %! randg ("seed", 12);
912 %!assert (randg ([-inf, -1, 0, inf, nan]), [nan, nan, nan, nan, nan]) # *** Please report
913 %!test
914 %! if (__random_statistical_tests__)
915 %! ## statistical tests may fail occasionally.
916 %! randg ("seed", 12);
917 %! a = 0.1;
918 %! x = randg (a, 100000, 1);
919 %! assert (mean (x), a, 0.01);
920 %! assert (var (x), a, 0.01);
921 %! assert (skewness (x), 2/sqrt (a), 1);
922 %! assert (kurtosis (x), 6/a, 50);
923 %! endif
924 %!test
925 %! if (__random_statistical_tests__)
926 %! ## statistical tests may fail occasionally.
927 %! randg ("seed", 12);
928 %! a = 0.95;
929 %! x = randg (a, 100000, 1);
930 %! assert (mean (x), a, 0.01);
931 %! assert (var (x), a, 0.04);
932 %! assert (skewness (x), 2/sqrt (a), 0.2);
933 %! assert (kurtosis (x), 6/a, 2);
934 %! endif
935 %!test
936 %! if (__random_statistical_tests__)
937 %! ## statistical tests may fail occasionally.
938 %! randg ("seed", 12);
939 %! a = 1;
940 %! x = randg (a, 100000, 1);
941 %! assert (mean (x), a, 0.01);
942 %! assert (var (x), a, 0.04);
943 %! assert (skewness (x), 2/sqrt (a), 0.2);
944 %! assert (kurtosis (x), 6/a, 2);
945 %! endif
946 %!test
947 %! if (__random_statistical_tests__)
948 %! ## statistical tests may fail occasionally.
949 %! randg ("seed", 12);
950 %! a = 10;
951 %! x = randg (a, 100000, 1);
952 %! assert (mean (x), a, 0.1);
953 %! assert (var (x), a, 0.5);
954 %! assert (skewness (x), 2/sqrt (a), 0.1);
955 %! assert (kurtosis (x), 6/a, 0.5);
956 %! endif
957 %!test
958 %! if (__random_statistical_tests__)
959 %! ## statistical tests may fail occasionally.
960 %! randg ("seed", 12);
961 %! a = 100;
962 %! x = randg (a, 100000, 1);
963 %! assert (mean (x), a, 0.2);
964 %! assert (var (x), a, 2);
965 %! assert (skewness (x), 2/sqrt (a), 0.05);
966 %! assert (kurtosis (x), 6/a, 0.2);
967 %! endif
968 */
969 
970 DEFUN (randp, args, ,
971  "-*- texinfo -*-\n\
972 @deftypefn {Built-in Function} {} randp (@var{l}, @var{n})\n\
973 @deftypefnx {Built-in Function} {} randp (@var{l}, @var{n}, @var{m}, @dots{})\n\
974 @deftypefnx {Built-in Function} {} randp (@var{l}, [@var{n} @var{m} @dots{}])\n\
975 @deftypefnx {Built-in Function} {@var{v} =} randp (\"state\")\n\
976 @deftypefnx {Built-in Function} {} randp (\"state\", @var{v})\n\
977 @deftypefnx {Built-in Function} {} randp (\"state\", \"reset\")\n\
978 @deftypefnx {Built-in Function} {@var{v} =} randp (\"seed\")\n\
979 @deftypefnx {Built-in Function} {} randp (\"seed\", @var{v})\n\
980 @deftypefnx {Built-in Function} {} randp (\"seed\", \"reset\")\n\
981 @deftypefnx {Built-in Function} {} randp (@dots{}, \"single\")\n\
982 @deftypefnx {Built-in Function} {} randp (@dots{}, \"double\")\n\
983 Return a matrix with Poisson distributed random elements with mean value\n\
984 parameter given by the first argument, @var{l}. The arguments\n\
985 are handled the same as the arguments for @code{rand}, except for the\n\
986 argument @var{l}.\n\
987 \n\
988 Five different algorithms are used depending on the range of @var{l}\n\
989 and whether or not @var{l} is a scalar or a matrix.\n\
990 \n\
991 @table @asis\n\
992 @item For scalar @var{l} @leq{} 12, use direct method.\n\
993 W.H. Press, et al., @cite{Numerical Recipes in C},\n\
994 Cambridge University Press, 1992.\n\
995 \n\
996 @item For scalar @var{l} > 12, use rejection method.[1]\n\
997 W.H. Press, et al., @cite{Numerical Recipes in C},\n\
998 Cambridge University Press, 1992.\n\
999 \n\
1000 @item For matrix @var{l} @leq{} 10, use inversion method.[2]\n\
1001 E. Stadlober, et al., WinRand source code, available via FTP.\n\
1002 \n\
1003 @item For matrix @var{l} > 10, use patchwork rejection method.\n\
1004 E. Stadlober, et al., WinRand source code, available via FTP, or\n\
1005 H. Zechner, @cite{Efficient sampling from continuous and discrete\n\
1006 unimodal distributions}, Doctoral Dissertation, 156pp., Technical\n\
1007 University Graz, Austria, 1994.\n\
1008 \n\
1009 @item For @var{l} > 1e8, use normal approximation.\n\
1010 L. Montanet, et al., @cite{Review of Particle Properties}, Physical Review\n\
1011 D 50 p1284, 1994.\n\
1012 @end table\n\
1013 \n\
1014 The class of the value returned can be controlled by a trailing\n\
1015 @qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\
1016 classes.\n\
1017 @seealso{rand, randn, rande, randg}\n\
1018 @end deftypefn")
1019 {
1020  octave_value retval;
1021 
1022  int nargin = args.length ();
1023 
1024  if (nargin < 1)
1025  error ("randp: insufficient arguments");
1026  else
1027  retval = do_rand (args, nargin, "randp", "poisson", true);
1028 
1029  return retval;
1030 }
1031 
1032 /*
1033 %!test
1034 %! randp ("state", 12);
1035 %! assert (randp ([-inf, -1, 0, inf, nan]), [nan, nan, 0, nan, nan]); # *** Please report
1036 %!test
1037 %! ## Test fixed state
1038 %! randp ("state", 1);
1039 %! assert (randp (5, 1, 6), [5 5 3 7 7 3])
1040 %!test
1041 %! ## Test fixed state
1042 %! randp ("state", 1);
1043 %! assert (randp (15, 1, 6), [13 15 8 18 18 15])
1044 %!test
1045 %! ## Test fixed state
1046 %! randp ("state", 1);
1047 %! assert (randp (1e9, 1, 6), [999915677 999976657 1000047684 1000019035 999985749 999977692], -1e-6)
1048 %!test
1049 %! ## Test fixed state
1050 %! randp ("seed", 1);
1051 %! %%assert (randp (5, 1, 6), [8 2 3 6 6 8])
1052 %! assert (randp (5, 1, 5), [8 2 3 6 6])
1053 %!test
1054 %! ## Test fixed state
1055 %! randp ("seed", 1);
1056 %! assert (randp (15, 1, 6), [15 16 12 10 10 12])
1057 %!test
1058 %! ## Test fixed state
1059 %! randp ("seed", 1);
1060 %! assert (randp (1e9, 1, 6), [1000006208 1000012224 999981120 999963520 999963072 999981440], -1e-6)
1061 %!test
1062 %! if (__random_statistical_tests__)
1063 %! ## statistical tests may fail occasionally.
1064 %! randp ("state", 12);
1065 %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
1066 %! x = randp (a (1), 100000, 1);
1067 %! assert (min (x) >= 0); # *** Please report this!!! ***
1068 %! assert (mean (x), a(1), a(2));
1069 %! assert (var (x), a(1), 0.02*a(1));
1070 %! assert (skewness (x), 1/sqrt (a(1)), a(3));
1071 %! assert (kurtosis (x), 1/a(1), 3*a(3));
1072 %! endfor
1073 %! endif
1074 %!test
1075 %! if (__random_statistical_tests__)
1076 %! ## statistical tests may fail occasionally.
1077 %! randp ("state", 12);
1078 %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
1079 %! x = randp (a(1)*ones (100000, 1), 100000, 1);
1080 %! assert (min (x) >= 0); # *** Please report this!!! ***
1081 %! assert (mean (x), a(1), a(2));
1082 %! assert (var (x), a(1), 0.02*a(1));
1083 %! assert (skewness (x), 1/sqrt (a(1)), a(3));
1084 %! assert (kurtosis (x), 1/a(1), 3*a(3));
1085 %! endfor
1086 %! endif
1087 %!test
1088 %! randp ("seed", 12);
1089 %! assert (randp ([-inf, -1, 0, inf, nan]), [nan, nan, 0, nan, nan]); # *** Please report
1090 %!test
1091 %! if (__random_statistical_tests__)
1092 %! ## statistical tests may fail occasionally.
1093 %! randp ("seed", 12);
1094 %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
1095 %! x = randp (a(1), 100000, 1);
1096 %! assert (min (x) >= 0); # *** Please report this!!! ***
1097 %! assert (mean (x), a(1), a(2));
1098 %! assert (var (x), a(1), 0.02*a(1));
1099 %! assert (skewness (x), 1/sqrt (a(1)), a(3));
1100 %! assert (kurtosis (x), 1/a(1), 3*a(3));
1101 %! endfor
1102 %! endif
1103 %!test
1104 %! if (__random_statistical_tests__)
1105 %! ## statistical tests may fail occasionally.
1106 %! randp ("seed", 12);
1107 %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
1108 %! x = randp (a(1)*ones (100000, 1), 100000, 1);
1109 %! assert (min (x) >= 0); # *** Please report this!!! ***
1110 %! assert (mean (x), a(1), a(2));
1111 %! assert (var (x), a(1), 0.02*a(1));
1112 %! assert (skewness (x), 1/sqrt (a(1)), a(3));
1113 %! assert (kurtosis (x), 1/a(1), 3*a(3));
1114 %! endfor
1115 %! endif
1116 */
1117 
1118 DEFUN (randperm, args, ,
1119  "-*- texinfo -*-\n\
1120 @deftypefn {Built-in Function} {} randperm (@var{n})\n\
1121 @deftypefnx {Built-in Function} {} randperm (@var{n}, @var{m})\n\
1122 Return a row vector containing a random permutation of @code{1:@var{n}}.\n\
1123 If @var{m} is supplied, return @var{m} unique entries, sampled without\n\
1124 replacement from @code{1:@var{n}}. The complexity is O(@var{n}) in\n\
1125 memory and O(@var{m}) in time, unless @var{m} < @var{n}/5, in which case\n\
1126 O(@var{m}) memory is used as well. The randomization is performed using\n\
1127 rand(). All permutations are equally likely.\n\
1128 @seealso{perms}\n\
1129 @end deftypefn")
1130 {
1131 
1132 #ifdef USE_UNORDERED_MAP_WITH_TR1
1133 using std::tr1::unordered_map;
1134 #else
1135 using std::unordered_map;
1136 #endif
1137 
1138  int nargin = args.length ();
1139  octave_value retval;
1140 
1141  if (nargin == 1 || nargin == 2)
1142  {
1143  octave_idx_type n, m;
1144 
1145  n = args(0).idx_type_value (true);
1146 
1147  if (nargin == 2)
1148  m = args(1).idx_type_value (true);
1149  else
1150  m = n;
1151 
1152  if (m < 0 || n < 0)
1153  error ("randperm: M and N must be non-negative");
1154 
1155  if (m > n)
1156  error ("randperm: M must be less than or equal to N");
1157 
1158  // Quick and dirty heuristic to decide if we allocate or not the
1159  // whole vector for tracking the truncated shuffle.
1160  bool short_shuffle = m < n/5;
1161 
1162  if (! error_state)
1163  {
1164  // Generate random numbers.
1166  double *rvec = r.fortran_vec ();
1167 
1168  octave_idx_type idx_len = short_shuffle ? m : n;
1170  try
1171  {
1172  idx = Array<octave_idx_type> (dim_vector (1, idx_len));
1173  }
1174  catch (std::bad_alloc)
1175  {
1176  // Looks like n is too big and short_shuffle is false.
1177  // Let's try again, but this time with the alternative.
1178  idx_len = m;
1179  short_shuffle = true;
1180  idx = Array<octave_idx_type> (dim_vector (1, idx_len));
1181  }
1182 
1183  octave_idx_type *ivec = idx.fortran_vec ();
1184 
1185  for (octave_idx_type i = 0; i < idx_len; i++)
1186  ivec[i] = i;
1187 
1188  if (short_shuffle)
1189  {
1190  unordered_map<octave_idx_type, octave_idx_type> map (m);
1191 
1192  // Perform the Knuth shuffle only keeping track of moved
1193  // entries in the map
1194  for (octave_idx_type i = 0; i < m; i++)
1195  {
1196  octave_idx_type k = i +
1197  gnulib::floor (rvec[i] * (n - i));
1198 
1199  //For shuffling first m entries, no need to use extra
1200  //storage
1201  if (k < m)
1202  {
1203  std::swap (ivec[i], ivec[k]);
1204  }
1205  else
1206  {
1207  if (map.find (k) == map.end ())
1208  map[k] = k;
1209 
1210  std::swap (ivec[i], map[k]);
1211  }
1212  }
1213  }
1214  else
1215  {
1216 
1217  // Perform the Knuth shuffle of the first m entries
1218  for (octave_idx_type i = 0; i < m; i++)
1219  {
1220  octave_idx_type k = i +
1221  gnulib::floor (rvec[i] * (n - i));
1222  std::swap (ivec[i], ivec[k]);
1223  }
1224  }
1225 
1226  // Convert to doubles, reusing r.
1227  for (octave_idx_type i = 0; i < m; i++)
1228  rvec[i] = ivec[i] + 1;
1229 
1230  if (m < n)
1231  idx.resize (dim_vector (1, m));
1232 
1233  // Now create an array object with a cached idx_vector.
1234  retval = new octave_matrix (r, idx_vector (idx));
1235  }
1236  }
1237  else
1238  print_usage ();
1239 
1240  return retval;
1241 }
1242 
1243 /*
1244 %!assert (sort (randperm (20)), 1:20)
1245 %!assert (length (randperm (20,10)), 10)
1246 
1247 ## Test biggish N (bug #39378)
1248 %!assert (length (randperm (30000^2, 100000)), 100000)
1249 
1250 %!test
1251 %! rand ("seed", 0);
1252 %! for i = 1:100
1253 %! p = randperm (305, 30);
1254 %! assert (length (unique (p)), 30);
1255 %! endfor
1256 */