// (C) Copyright Nick Thompson 2018. // (C) Copyright Matt Borland 2021. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include <vector> #include <random> #include <type_traits> #include <cstddef> namespace boost { namespace math { // To stress test, set global_seed = 0, global_size = huge. static constexpr std::size_t global_seed = 0; static constexpr std::size_t global_size = 128; template<typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true> std::vector<T> generate_random_vector(std::size_t size, std::size_t seed) { if (seed == 0) { std::random_device rd; seed = rd(); } std::vector<T> v(size); std::mt19937 gen(seed); std::normal_distribution<T> dis(0, 1); for(std::size_t i = 0; i < v.size(); ++i) { v[i] = dis(gen); } return v; } template<typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true> std::vector<T> generate_random_uniform_vector(std::size_t size, std::size_t seed, T lower_bound = T(0), T upper_bound = T(1)) { if (seed == 0) { std::random_device rd; seed = rd(); } std::vector<T> v(size); std::mt19937 gen(seed); std::uniform_real_distribution<T> dis(lower_bound, upper_bound); for (auto& i : v) { i = dis(gen); } return v; } template<typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true> std::vector<T> generate_random_vector(std::size_t size, std::size_t seed, T mean, T stddev) { if (seed == 0) { std::random_device rd; seed = rd(); } std::vector<T> v(size); std::mt19937 gen(seed); std::normal_distribution<T> dis(mean, stddev); for (std::size_t i = 0; i < v.size(); ++i) { v[i] = dis(gen); } return v; } template<typename T, typename std::enable_if<std::is_integral<T>::value, bool>::type = true> std::vector<T> generate_random_vector(std::size_t size, std::size_t seed) { if (seed == 0) { std::random_device rd; seed = rd(); } std::vector<T> v(size); std::mt19937 gen(seed); // Rescaling by larger than 2 is UB! std::uniform_int_distribution<T> dis(std::numeric_limits<T>::lowest()/2, (std::numeric_limits<T>::max)()/2); for (std::size_t i = 0; i < v.size(); ++i) { v[i] = dis(gen); } return v; } }} // Namespaces