generator.hpp 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. // Copyright 2019 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <array>
  7. #include <random>
  8. using uniform = std::uniform_real_distribution<>;
  9. using uniform_int = std::uniform_int_distribution<>;
  10. using normal = std::normal_distribution<>;
  11. template <class Distribution, class... Ts>
  12. Distribution init(Ts...);
  13. template <>
  14. uniform init<uniform>() {
  15. return uniform{0.0, 1.0};
  16. }
  17. template <>
  18. normal init<normal>() {
  19. return normal{0.5, 0.3};
  20. }
  21. template <>
  22. uniform_int init<uniform_int, int>(int n) {
  23. return uniform_int{0, n};
  24. }
  25. template <class Distribution, std::size_t N = 1 << 15>
  26. struct generator : std::array<double, N> {
  27. using base_t = std::array<double, N>;
  28. template <class... Ts>
  29. generator(Ts... ts) {
  30. std::default_random_engine rng(1);
  31. auto dis = init<Distribution>(ts...);
  32. std::generate(base_t::begin(), base_t::end(), [&] { return dis(rng); });
  33. }
  34. const double& operator()() {
  35. ++ptr_;
  36. if (ptr_ == base_t::data() + N) ptr_ = base_t::data();
  37. return *ptr_;
  38. }
  39. const double* ptr_ = base_t::data() - 1;
  40. };