random_vector.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // (C) Copyright Nick Thompson 2018.
  2. // (C) Copyright Matt Borland 2021.
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <cstddef>
  7. #include <random>
  8. #include <type_traits>
  9. #include <vector>
  10. namespace boost { namespace math {
  11. // To stress test, set global_seed = 0, global_size = huge.
  12. static constexpr std::size_t global_seed = 0;
  13. static constexpr std::size_t global_size = 128;
  14. template<typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true>
  15. std::vector<T> generate_random_vector(std::size_t size, std::size_t seed)
  16. {
  17. if (seed == 0)
  18. {
  19. std::random_device rd;
  20. seed = rd();
  21. }
  22. std::vector<T> v(size);
  23. std::mt19937_64 gen(seed);
  24. std::normal_distribution<T> dis(0, 1);
  25. for (auto& x : v)
  26. {
  27. x = dis(gen);
  28. }
  29. return v;
  30. }
  31. template<typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true>
  32. 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))
  33. {
  34. if (seed == 0)
  35. {
  36. std::random_device rd;
  37. seed = rd();
  38. }
  39. std::vector<T> v(size);
  40. std::mt19937 gen(seed);
  41. std::uniform_real_distribution<T> dis(lower_bound, upper_bound);
  42. for (auto& x : v)
  43. {
  44. x = dis(gen);
  45. }
  46. return v;
  47. }
  48. template<typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true>
  49. std::vector<T> generate_random_vector(std::size_t size, std::size_t seed, T mean, T stddev)
  50. {
  51. if (seed == 0)
  52. {
  53. std::random_device rd;
  54. seed = rd();
  55. }
  56. std::vector<T> v(size);
  57. std::mt19937 gen(seed);
  58. std::normal_distribution<T> dis(mean, stddev);
  59. for (auto& x : v)
  60. {
  61. x = dis(gen);
  62. }
  63. return v;
  64. }
  65. template<typename T, typename std::enable_if<std::is_integral<T>::value, bool>::type = true>
  66. std::vector<T> generate_random_vector(std::size_t size, std::size_t seed)
  67. {
  68. if (seed == 0)
  69. {
  70. std::random_device rd;
  71. seed = rd();
  72. }
  73. std::vector<T> v(size);
  74. std::mt19937_64 gen(seed);
  75. // Rescaling by larger than 2 is UB!
  76. std::uniform_int_distribution<T> dis(std::numeric_limits<T>::lowest()/2, (std::numeric_limits<T>::max)()/2);
  77. for (auto& x : v)
  78. {
  79. x = dis(gen);
  80. }
  81. return v;
  82. }
  83. }} // Namespaces