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