Mercurial > hg > octave-lyh
diff liboctave/oct-rand.h @ 7537:a2950622f070
make octave_rand a proper singleton class
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 27 Feb 2008 04:33:39 -0500 |
parents | ff52243af934 |
children | eb63fbe60fab |
line wrap: on
line diff
--- a/liboctave/oct-rand.h +++ b/liboctave/oct-rand.h @@ -23,59 +23,209 @@ #if !defined (octave_rand_h) #define octave_rand_h 1 +#include <map> #include <string> #include "dColVector.h" #include "dMatrix.h" #include "dNDArray.h" +#include "lo-ieee.h" -struct +class OCTAVE_API octave_rand { +protected: + + octave_rand (void); + +public: + + ~octave_rand (void) { } + + static bool instance_ok (void); + // Return the current seed. - static double seed (void); + static double seed (void) + { + return instance_ok () ? instance->do_seed () : octave_NaN; + } // Set the seed. - static void seed (double s); + static void seed (double s) + { + if (instance_ok ()) + instance->do_seed (s); + } // Return the current state. - static ColumnVector state (const std::string& d = std::string ()); + static ColumnVector state (const std::string& d = std::string ()) + { + return instance_ok () ? instance->do_state (d) : ColumnVector (); + } // Set the current state/ static void state (const ColumnVector &s, - const std::string& d = std::string ()); + const std::string& d = std::string ()) + { + if (instance_ok ()) + instance->do_state (s, d); + } // Return the current distribution. - static std::string distribution (void); + static std::string distribution (void) + { + return instance_ok () ? instance->do_distribution () : std::string (); + } // Set the current distribution. May be either "uniform" (the // default), "normal", "exponential", "poisson", or "gamma". - static void distribution (const std::string& d); + static void distribution (const std::string& d) + { + if (instance_ok ()) + instance->do_distribution (d); + } - static void uniform_distribution (void); + static void uniform_distribution (void) + { + if (instance_ok ()) + instance->do_uniform_distribution (); + } - static void normal_distribution (void); + static void normal_distribution (void) + { + if (instance_ok ()) + instance->do_normal_distribution (); + } - static void exponential_distribution (void); + static void exponential_distribution (void) + { + if (instance_ok ()) + instance->do_exponential_distribution (); + } - static void poisson_distribution (void); + static void poisson_distribution (void) + { + if (instance_ok ()) + instance->do_poisson_distribution (); + } - static void gamma_distribution (void); + static void gamma_distribution (void) + { + if (instance_ok ()) + instance->do_gamma_distribution (); + } // Return the next number from the sequence. - static double scalar (double a = 1.); + static double scalar (double a = 1.0) + { + return instance_ok () ? instance->do_scalar (a) : octave_NaN; + } // Return a matrix of numbers from the sequence, filled in column // major order. - static Matrix matrix (octave_idx_type r, octave_idx_type c, double a = 1.); + static Matrix matrix (octave_idx_type r, octave_idx_type c, double a = 1.0) + { + return instance_ok () ? instance->do_matrix (r, c, a) : Matrix (); + } // Return an N-dimensional array of numbers from the sequence, // filled in column major order. - static NDArray nd_array (const dim_vector& dims, double a = 1.); + static NDArray nd_array (const dim_vector& dims, double a = 1.0) + { + return instance_ok () ? instance->do_nd_array (dims, a) : NDArray (); + } // Return an array of numbers from the sequence. - static Array<double> vector (octave_idx_type n, double a = 1.); + static Array<double> vector (octave_idx_type n, double a = 1.0) + { + return instance_ok () ? instance->do_vector (n, a) : Array<double> (); + } + +private: + + static octave_rand *instance; + + enum + { + unknown_dist, + uniform_dist, + normal_dist, + expon_dist, + poisson_dist, + gamma_dist + }; + + // Current distribution of random numbers. + int current_distribution; + + // If TRUE, use old RANLIB generators. Otherwise, use Mersenne + // Twister generator. + bool use_old_generators; + + // Saved MT states. + std::map<int, ColumnVector> rand_states; + + // Return the current seed. + double do_seed (void); + + // Set the seed. + void do_seed (double s); + + // Return the current state. + ColumnVector do_state (const std::string& d); + + // Set the current state/ + void do_state (const ColumnVector &s, const std::string& d); + + // Return the current distribution. + std::string do_distribution (void); + + // Set the current distribution. May be either "uniform" (the + // default), "normal", "exponential", "poisson", or "gamma". + void do_distribution (const std::string& d); + + void do_uniform_distribution (void); + + void do_normal_distribution (void); + + void do_exponential_distribution (void); + + void do_poisson_distribution (void); + + void do_gamma_distribution (void); + + // Return the next number from the sequence. + double do_scalar (double a = 1.); + + // Return a matrix of numbers from the sequence, filled in column + // major order. + Matrix do_matrix (octave_idx_type r, octave_idx_type c, double a = 1.); + + // Return an N-dimensional array of numbers from the sequence, + // filled in column major order. + NDArray do_nd_array (const dim_vector& dims, double a = 1.); + + // Return an array of numbers from the sequence. + Array<double> do_vector (octave_idx_type n, double a = 1.); + + // Some helper functions. + + void initialize_ranlib_generators (void); + + void initialize_mersenne_twister (void); + + ColumnVector get_internal_state (void); + + void save_state (void); + + int get_dist_id (const std::string& d); + + void set_internal_state (const ColumnVector& s); + + void switch_to_generator (int dist); + + void fill (octave_idx_type len, double *v, double a); }; #endif