26#if defined (HAVE_CONFIG_H)
30#include <unordered_map>
84 const std::string& distribution,
bool additional_arg =
false)
88 bool is_single =
false;
90 if (nargin > 0 && args(nargin-1).is_string ())
92 std::string s_arg = args(nargin-1).string_value ();
94 if (s_arg ==
"single")
99 else if (s_arg ==
"double")
106 error (
"%s: at least one argument is required", fcn);
107 else if (args(0).is_string ())
108 additional_arg =
false;
111 a = args(0).xarray_value (
"%s: dimension must be a scalar integer", fcn);
122 unwind_action restore_distribution
123 ([] (
const std::string& old_distribution)
125 rand::distribution (old_distribution);
126 }, rand::distribution ());
128 rand::distribution (distribution);
157 retval = rand::distribution ();
158 else if (s_arg ==
"seed")
159 retval = rand::seed ();
160 else if (s_arg ==
"state" || s_arg ==
"twister")
162 else if (s_arg ==
"uniform")
163 rand::uniform_distribution ();
164 else if (s_arg ==
"normal")
165 rand::normal_distribution ();
166 else if (s_arg ==
"exponential")
167 rand::exponential_distribution ();
168 else if (s_arg ==
"poisson")
169 rand::poisson_distribution ();
170 else if (s_arg ==
"gamma")
171 rand::gamma_distribution ();
173 error (
"%s: unrecognized string argument", fcn);
181 dims(0) = dims(1) = n;
189 if (! r.all_elements_are_ints ())
190 error (
"%s: all elements of range must be integers", fcn);
202 dims(i) = (base >= 0 ? base : 0);
218 error (ee,
"%s: dimensions must be a scalar or array of integers", fcn);
229 dims(i) = (elt >=0 ? elt : 0);
249 if (args(idx+1).is_real_scalar ())
251 double d = args(idx+1).double_value ();
255 else if (args(idx+1).is_string ()
256 && args(idx+1).string_value () ==
"reset")
259 error (
"%s: seed must be a real scalar", fcn);
261 else if (ts ==
"state" || ts ==
"twister")
263 if (args(idx+1).is_string ()
264 && args(idx+1).string_value () ==
"reset")
269 =
ColumnVector (args(idx+1).vector_value (
false,
true));
281 error (
"%s: unrecognized string argument", fcn);
287 for (
int i = 0; i < nargin; i++)
292 dims(i) = (elt >= 0 ? elt : 0);
313 return rand::float_nd_array (dims, a(0));
316 if (a.
dims () != dims)
317 error (
"%s: mismatch in argument size", fcn);
324 v[i] = rand::float_scalar (a(i));
330 return rand::float_nd_array (dims);
337 return rand::nd_array (dims, a(0));
340 if (a.
dims () != dims)
341 error (
"%s: mismatch in argument size", fcn);
354 return rand::nd_array (dims);
449 return do_rand (args, args.length (),
"rand",
"uniform");
584 return do_rand (args, args.length (),
"randn",
"normal");
651 return do_rand (args, args.length (),
"rande",
"exponential");
788 int nargin = args.length ();
791 error (
"randg: insufficient arguments");
793 return do_rand (args, nargin,
"randg",
"gamma",
true);
1013 int nargin = args.length ();
1016 error (
"randp: insufficient arguments");
1018 return do_rand (args, nargin,
"randp",
"poisson",
true);
1107DEFUN (randperm, args, ,
1123 int nargin = args.length ();
1125 if (nargin < 1 || nargin > 2)
1129 octave_idx_type m = (nargin == 2) ? args(1).idx_type_value (
true) : n;
1132 error (
"randperm: M and N must be non-negative");
1135 error (
"randperm: M must be less than or equal to N");
1139 bool short_shuffle = m < n/5;
1151 catch (
const std::bad_alloc&)
1156 short_shuffle =
true;
1167 std::unordered_map<octave_idx_type, octave_idx_type> map (m);
1178 std::swap (ivec[i], ivec[k]);
1182 if (map.find (k) == map.end ())
1185 std::swap (ivec[i], map[k]);
1195 std::swap (ivec[i], ivec[k]);
1201 rvec[i] = ivec[i] + 1;
T & xelem(octave_idx_type n)
Size of the specified dimension.
octave_idx_type numel(void) const
Number of elements in the array.
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
OCTARRAY_API void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
void resize(int n, int fill_value=0)
void chop_trailing_singletons(void)
octave_idx_type idx_type_value(bool req_int=false, bool frc_str_conv=false) const
bool is_scalar_type(void) const
bool is_string(void) const
OCTINTERP_API Array< octave_idx_type > octave_idx_type_vector_value(bool req_int=false, bool frc_str_conv=false, bool frc_vec_conv=false) const
std::string string_value(bool force=false) const
bool is_matrix_type(void) const
octave::range< double > range_value(void) const
bool is_range(void) const
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
void err_wrong_type_arg(const char *name, const char *s)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
class OCTAVE_API ColumnVector
octave_idx_type nint_big(double x)
std::complex< T > floor(const std::complex< T > &x)
static uint32_t state[624]
static bool scalar(const dim_vector &dims)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
static OCTAVE_NAMESPACE_BEGIN octave_value do_rand(const octave_value_list &args, int nargin, const char *fcn, const std::string &distribution, bool additional_arg=false)
static std::string current_distribution