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