CORSIKA  @c8_version@
The framework to simulate particle cascades for astroparticle physics
Squares4_64.hpp
1 /*
2  * (c) Copyright 2021 CORSIKA Project, corsika-project@lists.kit.edu
3  *
4  * This software is distributed under the terms of the GNU General Public
5  * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
6  * the license.
7  */
8 
9 /*
10  * Squares4.hpp
11  *
12  * Created on: 25/02/2021
13  * Author: Antonio Augusto Alves Junior
14  */
15 
16 #pragma once
17 
18 #include <stdint.h>
19 #include "SquaresKeys.hpp"
20 
21 namespace random_iterator {
22 
23  namespace detail {
24 
25  class Squares4_64 {
26 
27  public:
28  typedef uint64_t init_type;
29  typedef uint64_t state_type;
30  typedef uint64_t seed_type;
31  typedef uint64_t advance_type;
32  typedef uint32_t result_type;
33 
34  Squares4_64() = delete;
35 
36  Squares4_64(seed_type s, uint32_t)
37  : state_(0)
38  , seed_(seed_type{splitmix<seed_type>(s)}) {}
39 
40  Squares4_64(Squares4_64 const& other)
41  : state_(other.getState())
42  , seed_(other.getSeed()) {}
43 
44  inline Squares4_64& operator=(Squares4_64 const& other) {
45  if (this == &other) return *this;
46 
47  state_ = other.getState();
48  seed_ = other.getSeed();
49 
50  return *this;
51  }
52 
53  inline result_type operator()(void) {
54  uint64_t x, y, z;
55 
56  y = x = seed_ * state_;
57  z = y + seed_;
58 
59  x = x * x + y;
60  x = (x >> 32) | (x << 32); /* round 1 */
61 
62  x = x * x + z;
63  x = (x >> 32) | (x << 32); /* round 2 */
64 
65  x = x * x + y;
66  x = (x >> 32) | (x << 32); /* round 3 */
67 
68  ++state_; /* advance state */
69 
70  return (x * x + z) >> 32; /* round 4 */
71  }
72 
73  inline void reset(void) { state_ = 0; }
74 
75  inline void discard(advance_type n) { state_ += n; }
76 
77  inline seed_type getSeed() const { return seed_; }
78 
79  inline void setSeed(seed_type seed) { seed_ = seed; }
80 
81  inline state_type getState() const { return state_; }
82 
83  inline void setState(state_type state) { state_ = state; }
84 
85  inline static uint64_t generateSeed(size_t i) { return keys[i]; }
86 
87  static constexpr result_type min() { return 0; }
88 
89  static constexpr result_type max() {
90  return std::numeric_limits<result_type>::max();
91  }
92 
93  friend inline std::ostream& operator<<(std::ostream& os, const Squares4_64& be) {
94  return os << "state: " << be.getState() << " seed: " << be.getSeed();
95  }
96 
97  private:
98  state_type state_;
99  seed_type seed_;
100  };
101 
102  } // namespace detail
103 
104 } // namespace random_iterator