QMCPACK
PrimeNumberSet.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Anouar Benali, benali@anl.gov, Argonne National Laboratory
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 /** @file PrimeNumberSet.h
16  * @brief define a class to generate prime numbers for random number generators
17  */
18 #ifndef QMCPLUSPLUS_PRIME_NUMBER_SET_H
19 #define QMCPLUSPLUS_PRIME_NUMBER_SET_H
20 #include <vector>
21 #include <limits>
22 
23 ///dummy declaration
24 template<typename UIntType>
26 {};
27 
28 ///specialization for uint32_t
29 template<>
30 struct PrimeConstants<uint32_t>
31 {
32  enum
33  {
34  max_prime = 49979687,
35  min_num_primes = 4096,
36  max_prime_offset = 779156
37  };
38 };
39 
40 ///specialization for uint64_t
41 template<>
42 struct PrimeConstants<uint64_t>
43 {
44  enum
45  {
46  max_prime = 3037000501U,
47  min_num_primes = 55108,
48  max_prime_offset = 146138719U
49  };
50 };
51 
52 /** class to generate prime numbers
53  */
54 template<typename UIntType>
55 struct PrimeNumberSet : public PrimeConstants<UIntType>
56 {
57  using result_type = UIntType;
58  std::vector<UIntType> primes;
62 
63  /** default constructor
64  *
65  * Reserve space for primes and construct min_prime-lowest prime numbers
66  * excluding 2
67  */
68  inline PrimeNumberSet()
69  {
70  primes.reserve(2 * min_num_primes);
71  primes.push_back(3);
72  result_type largest = 3;
73  int n = min_num_primes;
74  while (n)
75  {
76  largest += 2;
77  bool is_prime = true;
78  for (int j = 0; j < primes.size(); j++)
79  {
80  if (largest % primes[j] == 0)
81  {
82  is_prime = false;
83  break;
84  }
85  else if (primes[j] * primes[j] > largest)
86  {
87  break;
88  }
89  }
90  if (is_prime)
91  {
92  primes.push_back(largest);
93  n--;
94  }
95  }
96  }
97 
98  inline result_type operator[](size_t i) const { return primes[i]; }
99 
100  inline size_t size() const { return primes.size(); }
101 
102  /** add n new primes starting with an offset
103  * @param offset offset of a set
104  * @param n number of primes requested
105  * @param primes_add contains n prime numbers if successful
106  * @return true, if successful
107  *
108  * For i=[0,n), primes_add[i]=primes[offset+i]
109  */
110  inline bool get(UIntType offset, int n, std::vector<UIntType>& primes_add)
111  {
112  offset = offset % max_prime_offset; //roll back
113  //have enough prime numbers, assign them in an array
114  if (n + offset + 1 < primes.size())
115  {
116  primes_add.insert(primes_add.end(), primes.begin() + offset, primes.begin() + offset + n);
117  return true;
118  }
119  UIntType largest = primes.back();
120  int n2add = offset + n - primes.size();
121  while (n2add > 0 && largest < max_prime)
122  {
123  largest += 2;
124  bool is_prime = true;
125  for (int j = 0; j < primes.size(); j++)
126  {
127  if (largest % primes[j] == 0)
128  {
129  is_prime = false;
130  break;
131  }
132  else if (primes[j] * primes[j] > largest)
133  {
134  break;
135  }
136  }
137  if (is_prime)
138  {
139  primes.push_back(largest);
140  n2add--;
141  }
142  }
143  if (n2add)
144  {
145  std::ostringstream o;
146  o << " PrimeNumberSet::get Failed to generate " << n2add << " prime numbers among " << n << " requested.";
147  APP_ABORT(o.str());
148  return false; //to make compiler happy
149  }
150  primes_add.insert(primes_add.end(), primes.begin() + offset, primes.begin() + offset + n);
151  return true;
152  }
153 };
154 #endif
class to generate prime numbers
PrimeNumberSet()
default constructor
dummy declaration
size_t size() const
result_type operator[](size_t i) const
std::vector< UIntType > primes
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27