26#if defined (HAVE_CONFIG_H)
50rand *rand::s_instance =
nullptr;
53 : m_current_distribution (uniform_dist), m_use_old_generators (false),
56 initialize_ranlib_generators ();
58 initialize_mersenne_twister ();
68 s_instance =
new rand ();
81 mach_info::float_format
ff = mach_info::native_float_format ();
85 case mach_info::flt_fmt_ieee_big_endian:
98force_to_fit_range (int32_t i, int32_t lo, int32_t hi)
102 i = (i > 0 ? i : -i);
113rand::do_seed (
double s)
115 m_use_old_generators =
true;
122 mach_info::float_format
ff = mach_info::native_float_format ();
126 case mach_info::flt_fmt_ieee_big_endian:
127 i1 = force_to_fit_range (
u.i[0], 1, 2147483563);
128 i0 = force_to_fit_range (
u.i[1], 1, 2147483399);
132 i0 = force_to_fit_range (
u.i[0], 1, 2147483563);
133 i1 = force_to_fit_range (
u.i[1], 1, 2147483399);
143 m_use_old_generators =
true;
144 initialize_ranlib_generators ();
148rand::do_state (
const std::string&
d)
150 return m_rand_states[
d.empty () ? m_current_distribution : get_dist_id (
d)];
156 m_use_old_generators =
false;
158 int old_dist = m_current_distribution;
160 int new_dist = (
d.empty () ? m_current_distribution : get_dist_id (
d));
167 set_internal_state (
s);
169 m_rand_states[
new_dist] = get_internal_state ();
176rand::do_reset (
const std::string&
d)
178 m_use_old_generators =
false;
180 int old_dist = m_current_distribution;
182 int new_dist = (
d.empty () ? m_current_distribution : get_dist_id (
d));
190 m_rand_states[
new_dist] = get_internal_state ();
197rand::do_distribution ()
201 switch (m_current_distribution)
224 (*current_liboctave_error_handler)
225 (
"rand: invalid distribution ID = %d", m_current_distribution);
233rand::do_distribution (
const std::string&
d)
235 int id = get_dist_id (
d);
260 (*current_liboctave_error_handler)
261 (
"rand: invalid distribution ID = %d", id);
267rand::do_uniform_distribution ()
269 switch_to_generator (uniform_dist);
275rand::do_normal_distribution ()
277 switch_to_generator (normal_dist);
283rand::do_exponential_distribution ()
285 switch_to_generator (expon_dist);
291rand::do_poisson_distribution ()
293 switch_to_generator (poisson_dist);
299rand::do_gamma_distribution ()
301 switch_to_generator (gamma_dist);
312 if (m_use_old_generators)
326 if (m_use_old_generators)
340 if (m_use_old_generators)
354 if (m_use_old_generators)
356 if (a < 0.0 || ! math::isfinite (a))
357 retval = numeric_limits<double>::NaN ();
377 if (m_use_old_generators)
379 if (a <= 0.0 || ! math::isfinite (a))
380 retval = numeric_limits<double>::NaN ();
395 if (m_use_old_generators)
408 if (m_use_old_generators)
421 if (m_use_old_generators)
434 if (m_use_old_generators)
436 if (a < 0.0f || ! math::isfinite (a))
437 retval = numeric_limits<float>::NaN ();
459 if (m_use_old_generators)
461 if (a <= 0.0f || ! math::isfinite (a))
462 retval = numeric_limits<float>::NaN ();
478 switch (m_current_distribution)
501 (*current_liboctave_error_handler)
502 (
"rand: invalid distribution ID = %d", m_current_distribution);
506 if (! m_use_old_generators)
528 (*current_liboctave_error_handler) (
"rand: invalid negative argument");
539rand::do_nd_array (
const dim_vector& dims,
double a)
554rand::do_float_nd_array (
const dim_vector& dims,
float a)
574rand::initialize_ranlib_generators ()
580 int hour =
tm.hour () + 1;
582 int second =
tm.sec () + 1;
587 s0 = force_to_fit_range (
s0, 1, 2147483563);
588 s1 = force_to_fit_range (
s1, 1, 2147483399);
595rand::initialize_mersenne_twister ()
600 s = get_internal_state ();
601 m_rand_states[uniform_dist] =
s;
604 s = get_internal_state ();
605 m_rand_states[normal_dist] =
s;
608 s = get_internal_state ();
609 m_rand_states[expon_dist] =
s;
612 s = get_internal_state ();
613 m_rand_states[poisson_dist] =
s;
616 s = get_internal_state ();
617 m_rand_states[gamma_dist] =
s;
621 set_internal_state (m_rand_states[m_current_distribution]);
625rand::get_internal_state ()
637 m_rand_states[m_current_distribution] = get_internal_state ();
641rand::get_dist_id (
const std::string&
d)
643 int retval = unknown_dist;
645 if (
d ==
"uniform" ||
d ==
"rand")
647 else if (
d ==
"normal" ||
d ==
"randn")
649 else if (
d ==
"exponential" ||
d ==
"rande")
651 else if (
d ==
"poisson" ||
d ==
"randp")
653 else if (
d ==
"gamma" ||
d ==
"randg")
657 (
"rand: invalid distribution '%s'",
d.c_str ());
667 const uint32_t *
sdata =
reinterpret_cast <const uint32_t *
> (
s.
data ());
676rand::switch_to_generator (
int dist)
678 if (dist != m_current_distribution)
680 m_current_distribution = dist;
682 set_internal_state (m_rand_states[dist]);
692 switch (m_current_distribution)
695 if (m_use_old_generators)
702 if (m_use_old_generators)
709 if (m_use_old_generators)
716 if (m_use_old_generators)
718 if (a < 0.0 || ! math::isfinite (a))
719 std::fill_n (
v,
len, numeric_limits<double>::NaN ());
733 if (m_use_old_generators)
735 if (a <= 0.0 || ! math::isfinite (a))
736 std::fill_n (
v,
len, numeric_limits<double>::NaN ());
745 (*current_liboctave_error_handler)
746 (
"rand: invalid distribution ID = %d", m_current_distribution);
761 switch (m_current_distribution)
764 if (m_use_old_generators)
771 if (m_use_old_generators)
778 if (m_use_old_generators)
785 if (m_use_old_generators)
787 if (a < 0.0f || ! math::isfinite (a))
788 std::fill_n (
v,
len, numeric_limits<float>::NaN ());
802 if (m_use_old_generators)
804 if (a <= 0.0f || ! math::isfinite (a))
805 std::fill_n (
v,
len, numeric_limits<float>::NaN ());
814 (*current_liboctave_error_handler)
815 (
"rand: invalid distribution ID = %d", m_current_distribution);
824OCTAVE_END_NAMESPACE(octave)
N Dimensional Array with copy-on-write semantics.
const T * data() const
Size of the specified dimension.
T * rwdata()
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
static void uniform_distribution()
static void exponential_distribution()
static bool instance_ok()
static Array< double > vector(octave_idx_type n, double a=1.0)
static void gamma_distribution()
static void normal_distribution()
static void poisson_distribution()
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
subroutine getsd(iseed1, iseed2)
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
#define liboctave_panic_unless(cond)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
void get_mersenne_twister_state(uint32_t *save)
double rand_uniform< double >()
void set_mersenne_twister_state(const uint32_t *save)
void init_mersenne_twister()
double rand_normal< double >()
float rand_normal< float >()
float rand_exponential< float >()
double rand_exponential< double >()
float rand_uniform< float >()
template void rand_poisson< double >(double, octave_idx_type, double *)
template void rand_poisson< float >(float, octave_idx_type, float *)
subroutine setall(iseed1, iseed2)
subroutine setsd(iseed1, iseed2)
subroutine fignpoi(mu, result)
subroutine fgennor(av, sd, result)
subroutine dgenunf(low, high, result)
subroutine fgenexp(av, result)
subroutine dgengam(a, r, result)
subroutine dgenexp(av, result)
subroutine fgengam(a, r, result)
subroutine fgenunf(low, high, result)
subroutine dgennor(av, sd, result)
subroutine dignpoi(mu, result)
F77_RET_T F77_FUNC(xerbla, XERBLA)(F77_CONST_CHAR_ARG_DEF(s_arg