Mercurial > octave
comparison src/DLD-FUNCTIONS/rand.cc @ 14655:43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
* oct-rand.cc (octave_rand:do_matrix): Remove method.
(octave_rand::do_float_scalar, octave_rand::do_float_nd_array,
octave_rand::do_float_vector): New methods.
* oct-rand.h (octave_rand:do_matrix, octave_rand::matrix): Remove methods.
(octave_rand::do_float_scalar, octave_rand::do_float_nd_array,
octave_rand::do_float_vector, octave_rand::float_scalar,
octave_rand::do_nd_array, octave_rand::float_vector): Declare new methods.
* randgamma.c (oct_fill_float_randg, oct_float_randg): New functions.
* randgamma.h (oct_fill_float_randg, oct_float_randg): Declare new functions.
* randpoisson.c (oct_fill_float_randp, oct_float_randp): New functions.
(poisson_cdf_lookup_float, poisson_rejection_float): New static functions.
* randpoisson.h (oct_fill_float_randp, oct_float_randp): Declare new functions.
* randmtzig.c (randu64) : Remove static function.
(ALLBITS): Remove compile flag logic.
(randu32): Change return type to float.
(oct_float_randu, oct_float_randn, oct_float_rande, oct_fill_float_randu,
oct_fill_float_randn, oct_fill_float_rande): New functions.
(create_ziggurat_float_tables): New static function.
* randmtzig.h (oct_float_randu, oct_float_randn, oct_float_rande,
oct_fill_float_randu, oct_fill_float_randn, oct_fill_float_rande):
Declare new functions.
* rand.cc (do_rand): Add logic to parse "double" or "single" as final argument.
author | David Bateman <dbateman@free.fr> |
---|---|
date | Sat, 19 May 2012 00:14:59 +0200 |
parents | cd375519eab0 |
children | 52c5fb67fa5f |
comparison
equal
deleted
inserted
replaced
14654:389f49a88656 | 14655:43db83eff9db |
---|---|
1 | |
1 /* | 2 /* |
2 | 3 |
3 Copyright (C) 1996-2012 John W. Eaton | 4 Copyright (C) 1996-2012 John W. Eaton |
4 Copyright (C) 2009 VZLU Prague | 5 Copyright (C) 2009 VZLU Prague |
5 | 6 |
58 { | 59 { |
59 octave_value retval; | 60 octave_value retval; |
60 NDArray a; | 61 NDArray a; |
61 int idx = 0; | 62 int idx = 0; |
62 dim_vector dims; | 63 dim_vector dims; |
64 bool is_single = false; | |
63 | 65 |
64 unwind_protect frame; | 66 unwind_protect frame; |
65 // Restore current distribution on any exit. | 67 // Restore current distribution on any exit. |
66 frame.add_fcn (octave_rand::distribution, | 68 frame.add_fcn (octave_rand::distribution, |
67 octave_rand::distribution ()); | 69 octave_rand::distribution ()); |
68 | 70 |
69 octave_rand::distribution (distribution); | 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 } | |
70 | 85 |
71 if (additional_arg) | 86 if (additional_arg) |
72 { | 87 { |
73 if (nargin == 0) | 88 if (nargin == 0) |
74 { | 89 { |
296 | 311 |
297 gen_matrix: | 312 gen_matrix: |
298 | 313 |
299 dims.chop_trailing_singletons (); | 314 dims.chop_trailing_singletons (); |
300 | 315 |
301 if (additional_arg) | 316 if (is_single) |
302 { | 317 { |
303 if (a.length() == 1) | 318 if (additional_arg) |
304 return octave_rand::nd_array (dims, a(0)); | 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 } | |
305 else | 337 else |
306 { | 338 return octave_rand::float_nd_array (dims); |
307 if (a.dims() != dims) | |
308 { | |
309 error ("%s: mismatch in argument size", fcn); | |
310 return retval; | |
311 } | |
312 octave_idx_type len = a.length (); | |
313 NDArray m (dims); | |
314 double *v = m.fortran_vec (); | |
315 for (octave_idx_type i = 0; i < len; i++) | |
316 v[i] = octave_rand::scalar (a(i)); | |
317 return m; | |
318 } | |
319 } | 339 } |
320 else | 340 else |
321 return octave_rand::nd_array (dims); | 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 } | |
322 } | 364 } |
323 | 365 |
324 DEFUN_DLD (rand, args, , | 366 DEFUN_DLD (rand, args, , |
325 "-*- texinfo -*-\n\ | 367 "-*- texinfo -*-\n\ |
326 @deftypefn {Loadable Function} {} rand (@var{n})\n\ | 368 @deftypefn {Loadable Function} {} rand (@var{n})\n\ |
330 @deftypefnx {Loadable Function} {} rand (\"state\", @var{v})\n\ | 372 @deftypefnx {Loadable Function} {} rand (\"state\", @var{v})\n\ |
331 @deftypefnx {Loadable Function} {} rand (\"state\", \"reset\")\n\ | 373 @deftypefnx {Loadable Function} {} rand (\"state\", \"reset\")\n\ |
332 @deftypefnx {Loadable Function} {@var{v} =} rand (\"seed\")\n\ | 374 @deftypefnx {Loadable Function} {@var{v} =} rand (\"seed\")\n\ |
333 @deftypefnx {Loadable Function} {} rand (\"seed\", @var{v})\n\ | 375 @deftypefnx {Loadable Function} {} rand (\"seed\", @var{v})\n\ |
334 @deftypefnx {Loadable Function} {} rand (\"seed\", \"reset\")\n\ | 376 @deftypefnx {Loadable Function} {} rand (\"seed\", \"reset\")\n\ |
377 @deftypefnx {Loadable Function} {} rand (@dots{}, \"single\")\n\ | |
378 @deftypefnx {Loadable Function} {} rand (@dots{}, \"double\")\n\ | |
335 Return a matrix with random elements uniformly distributed on the\n\ | 379 Return a matrix with random elements uniformly distributed on the\n\ |
336 interval (0, 1). The arguments are handled the same as the arguments\n\ | 380 interval (0, 1). The arguments are handled the same as the arguments\n\ |
337 for @code{eye}.\n\ | 381 for @code{eye}.\n\ |
338 \n\ | 382 \n\ |
339 You can query the state of the random number generator using the\n\ | 383 You can query the state of the random number generator using the\n\ |
400 To cause @code{rand} to once again use the new generators, the\n\ | 444 To cause @code{rand} to once again use the new generators, the\n\ |
401 keyword \"state\" should be used to reset the state of the @code{rand}.\n\ | 445 keyword \"state\" should be used to reset the state of the @code{rand}.\n\ |
402 \n\ | 446 \n\ |
403 The state or seed of the generator can be reset to a new random value\n\ | 447 The state or seed of the generator can be reset to a new random value\n\ |
404 using the \"reset\" keyword.\n\ | 448 using the \"reset\" keyword.\n\ |
449 \n\ | |
450 The class of the value returned can be controlled by a trailing \"double\"\n\ | |
451 or \"single\" argument. These are the only valid classes.\n\ | |
405 @seealso{randn, rande, randg, randp}\n\ | 452 @seealso{randn, rande, randg, randp}\n\ |
406 @end deftypefn") | 453 @end deftypefn") |
407 { | 454 { |
408 octave_value retval; | 455 octave_value retval; |
409 | 456 |
497 @deftypefnx {Loadable Function} {} randn (\"state\", @var{v})\n\ | 544 @deftypefnx {Loadable Function} {} randn (\"state\", @var{v})\n\ |
498 @deftypefnx {Loadable Function} {} randn (\"state\", \"reset\")\n\ | 545 @deftypefnx {Loadable Function} {} randn (\"state\", \"reset\")\n\ |
499 @deftypefnx {Loadable Function} {@var{v} =} randn (\"seed\")\n\ | 546 @deftypefnx {Loadable Function} {@var{v} =} randn (\"seed\")\n\ |
500 @deftypefnx {Loadable Function} {} randn (\"seed\", @var{v})\n\ | 547 @deftypefnx {Loadable Function} {} randn (\"seed\", @var{v})\n\ |
501 @deftypefnx {Loadable Function} {} randn (\"seed\", \"reset\")\n\ | 548 @deftypefnx {Loadable Function} {} randn (\"seed\", \"reset\")\n\ |
549 @deftypefnx {Loadable Function} {} randn (@dots{}, \"single\")\n\ | |
550 @deftypefnx {Loadable Function} {} randn (@dots{}, \"double\")\n\ | |
502 Return a matrix with normally distributed random\n\ | 551 Return a matrix with normally distributed random\n\ |
503 elements having zero mean and variance one. The arguments are\n\ | 552 elements having zero mean and variance one. The arguments are\n\ |
504 handled the same as the arguments for @code{rand}.\n\ | 553 handled the same as the arguments for @code{rand}.\n\ |
505 \n\ | 554 \n\ |
506 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\ | 555 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\ |
507 to transform from a uniform to a normal distribution.\n\ | 556 to transform from a uniform to a normal distribution.\n\ |
557 \n\ | |
558 The class of the value returned can be controlled by a trailing \"double\"\n\ | |
559 or \"single\" argument. These are the only valid classes.\n\ | |
508 \n\ | 560 \n\ |
509 Reference: G. Marsaglia and W.W. Tsang,\n\ | 561 Reference: G. Marsaglia and W.W. Tsang,\n\ |
510 @cite{Ziggurat Method for Generating Random Variables},\n\ | 562 @cite{Ziggurat Method for Generating Random Variables},\n\ |
511 J. Statistical Software, vol 5, 2000,\n\ | 563 J. Statistical Software, vol 5, 2000,\n\ |
512 @url{http://www.jstatsoft.org/v05/i08/})\n\ | 564 @url{http://www.jstatsoft.org/v05/i08/})\n\ |
563 @deftypefnx {Loadable Function} {} rande (\"state\", @var{v})\n\ | 615 @deftypefnx {Loadable Function} {} rande (\"state\", @var{v})\n\ |
564 @deftypefnx {Loadable Function} {} rande (\"state\", \"reset\")\n\ | 616 @deftypefnx {Loadable Function} {} rande (\"state\", \"reset\")\n\ |
565 @deftypefnx {Loadable Function} {@var{v} =} rande (\"seed\")\n\ | 617 @deftypefnx {Loadable Function} {@var{v} =} rande (\"seed\")\n\ |
566 @deftypefnx {Loadable Function} {} rande (\"seed\", @var{v})\n\ | 618 @deftypefnx {Loadable Function} {} rande (\"seed\", @var{v})\n\ |
567 @deftypefnx {Loadable Function} {} rande (\"seed\", \"reset\")\n\ | 619 @deftypefnx {Loadable Function} {} rande (\"seed\", \"reset\")\n\ |
620 @deftypefnx {Loadable Function} {} rande (@dots{}, \"single\")\n\ | |
621 @deftypefnx {Loadable Function} {} rande (@dots{}, \"double\")\n\ | |
568 Return a matrix with exponentially distributed random elements. The\n\ | 622 Return a matrix with exponentially distributed random elements. The\n\ |
569 arguments are handled the same as the arguments for @code{rand}.\n\ | 623 arguments are handled the same as the arguments for @code{rand}.\n\ |
570 \n\ | 624 \n\ |
571 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\ | 625 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\ |
572 to transform from a uniform to an exponential distribution.\n\ | 626 to transform from a uniform to an exponential distribution.\n\ |
627 \n\ | |
628 The class of the value returned can be controlled by a trailing \"double\"\n\ | |
629 or \"single\" argument. These are the only valid classes.\n\ | |
573 \n\ | 630 \n\ |
574 Reference: G. Marsaglia and W.W. Tsang,\n\ | 631 Reference: G. Marsaglia and W.W. Tsang,\n\ |
575 @cite{Ziggurat Method for Generating Random Variables},\n\ | 632 @cite{Ziggurat Method for Generating Random Variables},\n\ |
576 J. Statistical Software, vol 5, 2000,\n\ | 633 J. Statistical Software, vol 5, 2000,\n\ |
577 @url{http://www.jstatsoft.org/v05/i08/})\n\ | 634 @url{http://www.jstatsoft.org/v05/i08/})\n\ |
630 @deftypefnx {Loadable Function} {} randg (\"state\", @var{v})\n\ | 687 @deftypefnx {Loadable Function} {} randg (\"state\", @var{v})\n\ |
631 @deftypefnx {Loadable Function} {} randg (\"state\", \"reset\")\n\ | 688 @deftypefnx {Loadable Function} {} randg (\"state\", \"reset\")\n\ |
632 @deftypefnx {Loadable Function} {@var{v} =} randg (\"seed\")\n\ | 689 @deftypefnx {Loadable Function} {@var{v} =} randg (\"seed\")\n\ |
633 @deftypefnx {Loadable Function} {} randg (\"seed\", @var{v})\n\ | 690 @deftypefnx {Loadable Function} {} randg (\"seed\", @var{v})\n\ |
634 @deftypefnx {Loadable Function} {} randg (\"seed\", \"reset\")\n\ | 691 @deftypefnx {Loadable Function} {} randg (\"seed\", \"reset\")\n\ |
692 @deftypefnx {Loadable Function} {} randg (@dots{}, \"single\")\n\ | |
693 @deftypefnx {Loadable Function} {} randg (@dots{}, \"double\")\n\ | |
635 Return a matrix with @code{gamma(@var{a},1)} distributed random elements.\n\ | 694 Return a matrix with @code{gamma(@var{a},1)} distributed random elements.\n\ |
636 The arguments are handled the same as the arguments for @code{rand},\n\ | 695 The arguments are handled the same as the arguments for @code{rand},\n\ |
637 except for the argument @var{a}.\n\ | 696 except for the argument @var{a}.\n\ |
638 \n\ | 697 \n\ |
639 This can be used to generate many distributions:\n\ | 698 This can be used to generate many distributions:\n\ |
709 r = r / sum (r)\n\ | 768 r = r / sum (r)\n\ |
710 @end group\n\ | 769 @end group\n\ |
711 @end example\n\ | 770 @end example\n\ |
712 \n\ | 771 \n\ |
713 @end table\n\ | 772 @end table\n\ |
773 \n\ | |
774 The class of the value returned can be controlled by a trailing \"double\"\n\ | |
775 or \"single\" argument. These are the only valid classes.\n\ | |
714 @seealso{rand, randn, rande, randp}\n\ | 776 @seealso{rand, randn, rande, randp}\n\ |
715 @end deftypefn") | 777 @end deftypefn") |
716 { | 778 { |
717 octave_value retval; | 779 octave_value retval; |
718 | 780 |
896 @deftypefnx {Loadable Function} {} randp (\"state\", @var{v})\n\ | 958 @deftypefnx {Loadable Function} {} randp (\"state\", @var{v})\n\ |
897 @deftypefnx {Loadable Function} {} randp (\"state\", \"reset\")\n\ | 959 @deftypefnx {Loadable Function} {} randp (\"state\", \"reset\")\n\ |
898 @deftypefnx {Loadable Function} {@var{v} =} randp (\"seed\")\n\ | 960 @deftypefnx {Loadable Function} {@var{v} =} randp (\"seed\")\n\ |
899 @deftypefnx {Loadable Function} {} randp (\"seed\", @var{v})\n\ | 961 @deftypefnx {Loadable Function} {} randp (\"seed\", @var{v})\n\ |
900 @deftypefnx {Loadable Function} {} randp (\"seed\", \"reset\")\n\ | 962 @deftypefnx {Loadable Function} {} randp (\"seed\", \"reset\")\n\ |
963 @deftypefnx {Loadable Function} {} randp (@dots{}, \"single\")\n\ | |
964 @deftypefnx {Loadable Function} {} randp (@dots{}, \"double\")\n\ | |
901 Return a matrix with Poisson distributed random elements with mean value\n\ | 965 Return a matrix with Poisson distributed random elements with mean value\n\ |
902 parameter given by the first argument, @var{l}. The arguments\n\ | 966 parameter given by the first argument, @var{l}. The arguments\n\ |
903 are handled the same as the arguments for @code{rand}, except for the\n\ | 967 are handled the same as the arguments for @code{rand}, except for the\n\ |
904 argument @var{l}.\n\ | 968 argument @var{l}.\n\ |
905 \n\ | 969 \n\ |
926 \n\ | 990 \n\ |
927 @item For @var{l} > 1e8, use normal approximation.\n\ | 991 @item For @var{l} > 1e8, use normal approximation.\n\ |
928 L. Montanet, et al., @cite{Review of Particle Properties}, Physical Review\n\ | 992 L. Montanet, et al., @cite{Review of Particle Properties}, Physical Review\n\ |
929 D 50 p1284, 1994.\n\ | 993 D 50 p1284, 1994.\n\ |
930 @end table\n\ | 994 @end table\n\ |
995 \n\ | |
996 The class of the value returned can be controlled by a trailing \"double\"\n\ | |
997 or \"single\" argument. These are the only valid classes.\n\ | |
931 @seealso{rand, randn, rande, randg}\n\ | 998 @seealso{rand, randn, rande, randg}\n\ |
932 @end deftypefn") | 999 @end deftypefn") |
933 { | 1000 { |
934 octave_value retval; | 1001 octave_value retval; |
935 | 1002 |