30 #if defined (HAVE_UNORDERED_MAP)
31 #include <unordered_map>
32 #elif defined (HAVE_TR1_UNORDERED_MAP)
33 #include <tr1/unordered_map>
58 const std::string& distribution,
bool additional_arg =
false)
64 bool is_single =
false;
73 if (nargin > 0 && args(nargin-1).is_string ())
75 std::string s_arg = args(nargin-1).string_value ();
77 if (s_arg ==
"single")
82 else if (s_arg ==
"double")
90 error (
"%s: expecting at least one argument", fcn);
93 else if (args(0).is_string ())
94 additional_arg =
false;
100 error (
"%s: expecting scalar or matrix arguments", fcn);
137 else if (s_arg ==
"seed")
141 else if (s_arg ==
"state" || s_arg ==
"twister")
145 else if (s_arg ==
"uniform")
149 else if (s_arg ==
"normal")
153 else if (s_arg ==
"exponential")
157 else if (s_arg ==
"poisson")
161 else if (s_arg ==
"gamma")
166 error (
"%s: unrecognized string argument", fcn);
174 error (
"%s: NaN is invalid matrix dimension", fcn);
204 dims(i) = base >= 0 ? base : 0;
212 error (
"%s: all elements of range must be integers",
230 dims(i) = elt >=0 ? elt : 0;
236 error (
"%s: expecting integer vector", fcn);
256 if (args(idx+1).is_real_scalar ())
258 double d = args(idx+1).double_value ();
263 else if (args(idx+1).is_string ()
264 && args(idx+1).string_value () ==
"reset")
267 error (
"%s: seed must be a real scalar", fcn);
269 else if (ts ==
"state" || ts ==
"twister")
271 if (args(idx+1).is_string ()
272 && args(idx+1).string_value () ==
"reset")
284 error (
"%s: unrecognized string argument", fcn);
290 for (
int i = 0; i < nargin; i++)
295 error (
"%s: expecting integer arguments", fcn);
299 dims(i) = elt >= 0 ? elt : 0;
324 if (a.
dims () != dims)
326 error (
"%s: mismatch in argument size", fcn);
348 if (a.
dims () != dims)
350 error (
"%s: mismatch in argument size", fcn);
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\
383 You can query the state of the random number generator using the\n\
387 v = rand (\"state\")\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\
395 rand (\"state\", v)\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\
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\
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\
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\
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\
431 rand (\"seed\", val)\n\
435 which sets the seed of the generator to @var{val}. The seed of the\n\
436 generator can be queried with\n\
439 s = rand (\"seed\")\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\
448 The state or seed of the generator can be reset to a new random value\n\
449 using the @qcode{\"reset\"} keyword.\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\
454 @seealso{randn, rande, randg, randp}\n\
459 int nargin = args.
length ();
461 retval =
do_rand (args, nargin,
"rand",
"uniform");
553 DEFUN (randn, args, ,
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\
570 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
571 to transform from a uniform to a normal distribution.\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\
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\
582 @seealso{rand, rande, randg, randp}\n\
587 int nargin = args.
length ();
589 retval =
do_rand (args, nargin,
"randn",
"normal");
625 DEFUN (rande, args, ,
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\
641 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
642 to transform from a uniform to an exponential distribution.\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\
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\
653 @seealso{rand, randn, randg, randp}\n\
658 int nargin = args.
length ();
660 retval =
do_rand (args, nargin,
"rande",
"exponential");
698 DEFUN (randg, args, ,
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\
715 This can be used to generate many distributions:\n\
718 @item @code{gamma (a, b)} for @code{a > -1}, @code{b > 0}\n\
724 @item @code{beta (a, b)} for @code{a > -1}, @code{b > -1}\n\
729 r = r1 / (r1 + randg (b, 1))\n\
733 @item @code{Erlang (a, n)}\n\
739 @item @code{chisq (df)} for @code{df > 0}\n\
742 r = 2 * randg (df / 2)\n\
745 @item @code{t (df)} for @code{0 < df < inf} (use randn if df is infinite)\n\
748 r = randn () / sqrt (2 * randg (df / 2) / df)\n\
751 @item @code{F (n1, n2)} for @code{0 < n1}, @code{0 < n2}\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\
763 @item negative @code{binomial (n, p)} for @code{n > 0}, @code{0 < p <= 1}\n\
766 r = randp ((1 - p) / p * randg (n))\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\
775 r(r > 0) = 2 * randg (r(r > 0))\n\
776 r(df > 0) += 2 * randg (df(df > 0)/2)\n\
780 @item @code{Dirichlet (a1, @dots{} ak)}\n\
784 r = (randg (a1), @dots{}, randg (ak))\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\
794 @seealso{rand, randn, rande, randp}\n\
799 int nargin = args.
length ();
802 error (
"randg: insufficient arguments");
804 retval =
do_rand (args, nargin,
"randg",
"gamma",
true);
970 DEFUN (randp, args, ,
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\
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\
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\
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\
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\
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\
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\
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\
1017 @seealso{rand, randn, rande, randg}\n\
1022 int nargin = args.
length ();
1025 error (
"randp: insufficient arguments");
1027 retval =
do_rand (args, nargin,
"randp",
"poisson",
true);
1118 DEFUN (randperm, args, ,
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\
1132 #ifdef USE_UNORDERED_MAP_WITH_TR1
1133 using std::tr1::unordered_map;
1135 using std::unordered_map;
1138 int nargin = args.length ();
1141 if (nargin == 1 || nargin == 2)
1145 n = args(0).idx_type_value (
true);
1148 m = args(1).idx_type_value (
true);
1153 error (
"randperm: M and N must be non-negative");
1156 error (
"randperm: M must be less than or equal to N");
1160 bool short_shuffle = m < n/5;
1174 catch (std::bad_alloc)
1179 short_shuffle =
true;
1190 unordered_map<octave_idx_type, octave_idx_type> map (m);
1203 std::swap (ivec[i], ivec[k]);
1207 if (map.find (k) == map.end ())
1210 std::swap (ivec[i], map[k]);
1222 std::swap (ivec[i], ivec[k]);
1228 rvec[i] = ivec[i] + 1;