@@ -30,6 +30,24 @@ struct uniform_generator : float_number_generator<T> {
3030 T new_float () override { return dis (gen); }
3131};
3232
33+ template <typename T>
34+ struct logspace_generator : float_number_generator<T> {
35+ std::random_device rd;
36+ std::mt19937_64 gen;
37+ std::uniform_int_distribution<int > exp;
38+ std::uniform_real_distribution<T> significand;
39+ explicit logspace_generator ()
40+ : rd(), gen(rd()),
41+ exp(std::numeric_limits<T>::min_exponent + 1 , // +1 skips subnormals
42+ std::numeric_limits<T>::max_exponent),
43+ significand(-1 , 1 ) {}
44+ std::string describe () override {
45+ return " Generate random numbers uniformly in log2 space, i.e. "
46+ " magnitudes uniformly distributed in the interval [-2^max_exponent, 2^max_exponent]" ;
47+ }
48+ T new_float () override { return significand (gen) * std::pow (2.0 , exp (gen)); }
49+ };
50+
3351enum centering { centered, non_centered };
3452template <std::floating_point T, centering C>
3553struct centered_generator : float_number_generator<T> {
@@ -112,29 +130,26 @@ struct one_over_rand : float_number_generator<T> {
112130};
113131
114132constexpr std::array<const char *, 8 > model_names = {
115- " uniform_01" , " uniform_all " , " integer_uniform " ,
116- " centered" , " non_centered" ,
117- " simple_uniform" , " simple_int" ,
118- " one_over_rand"
133+ " uniform_01" , " logspace_all " ,
134+ " centered" , " non_centered" ,
135+ " simple_uniform" , " simple_int" ,
136+ " one_over_rand" , " integer_uniform " ,
119137};
120138
121139template <typename T>
122140inline std::unique_ptr<float_number_generator<T>>
123- get_generator_by_name (std::string name) {
141+ get_generator_by_name (const std::string name) {
124142 std::cout << " available models (-m): " ;
125- for (std::string name : model_names) {
126- std::cout << name << " " ;
143+ for (const auto & model : model_names) {
144+ std::cout << model << " " ;
127145 }
128146 std::cout << std::endl;
129147
130148 // This is naive, but also not very important.
131149 if (name == " uniform_01" )
132150 return std::unique_ptr<float_number_generator<T>>(new uniform_generator<T>());
133- if (name == " uniform_all" ) {
134- return std::unique_ptr<float_number_generator<T>>(
135- new uniform_generator<T>(std::numeric_limits<T>::lowest (),
136- std::numeric_limits<T>::max ())
137- );
151+ if (name == " logspace_all" ) {
152+ return std::unique_ptr<float_number_generator<T>>(new logspace_generator<T>());
138153 }
139154 if (name == " centered" )
140155 return std::unique_ptr<float_number_generator<T>>(new centered_generator<T, centered>());
0 commit comments