Loading [MathJax]/extensions/tex2jax.js
Parallel numerical verification of the σ_odd problem  October 6, 2018
All Classes Namespaces Files Functions Variables Typedefs Macros
primes.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 /** \file common/sigmaodd/primes.cpp (January 5, 2018)
3  *
4  * GPLv3 --- Copyright (C) 2017, 2018 Olivier Pirson
5  * http://www.opimedia.be/
6  */
7 
8 // \cond
9 #include <cstdlib>
10 
11 #include <fstream>
12 #include <utility>
13 // \endcond
14 
15 #include "primes.hpp"
16 #include "../helper/helper.hpp"
17 
18 
19 namespace sigmaodd {
20 
21  /* ***********
22  * Constants *
23  *************/
24 
25 #ifdef PRIME16
26  // See in ../../miscellaneous/offsets/
27  const nat_type array_potential_prime_offsets_[array_potential_prime_offsets_nb_] = {
28  10, 2, 4, 2, 4, 6, 2, 6, 4, 2,
29  4, 6, 6, 2, 6, 4, 2, 6, 4, 6,
30  8, 4, 2, 4, 2, 4, 8, 6, 4, 6,
31  2, 4, 6, 2, 6, 6, 4, 2, 4, 6,
32  2, 6, 4, 2, 4, 2, 10, 2};
33 #endif
34 
35  const std::string prime_filename = "big_data/prime28.bin";
36 
37 
38 
39  /* **********
40  * Variable *
41  ************/
42  // http://primes.utm.edu/nthprime/
43 #ifdef PRIME16
45 #include "primes_table16.txt"
46  };
47 #else
48  prime_type* array_odd_primes_ = nullptr;
49 #endif
50 
51 
52 
53  /* ***********
54  * Functions *
55  *************/
56 
57  std::vector<FactorExp>
59  assert(n != 0);
60  assert(n <= MAX_POSSIBLE_N);
61 #ifdef PRIME16
62  assert(n < 65536);
63 #endif
64 
65  std::vector<FactorExp> list;
66  nat_type sqrt_n = floor_square_root(n);
67  const prime_type* p = odd_primes_table_ptr() - 1;
68 
69  {
70  std::pair<nat_type, unsigned int> n_exp = divide_until_odd_nb(n);
71 
72  if (n_exp.second > 0) {
73  list.push_back({2, n_exp.second});
74  n = n_exp.first;
75  }
76  }
77 
78 
79  while (*(++p) <= sqrt_n) {
80  assert(*p != 0);
81 
82  unsigned int alpha = 0;
83 
84  while (is_divide(*p, n)) {
85  n /= *p;
86  ++alpha;
87  }
88 
89  if (alpha > 0) {
90  list.push_back({*p, alpha});
91  sqrt_n = floor_square_root(n);
92  }
93  }
94 
95  // Remain n_divided is prime
96  if (n > 1) {
97  list.push_back({n, 1});
98  }
99 
100  return list;
101  }
102 
103 
104  nat_type
105  factorization_to_n(std::vector<FactorExp> prime_exps) {
106  nat_type n = 1;
107 
108  for (FactorExp prime_exp : prime_exps) {
109  n *= pow_nat(prime_exp.factor, prime_exp.exp);
110  }
111 
112  return n;
113  }
114 
115 
116  nat_type
117  factorization_to_nu(std::vector<FactorExp> prime_exps) {
118  nat_type nu = 1;
119 
120  for (FactorExp prime_exp : prime_exps) {
121  nu *= prime_exp.exp + 1;
122  }
123 
124  return nu;
125  }
126 
127 
128  nat_type
129  factorization_to_nu_odd(std::vector<FactorExp> prime_exps) {
130  nat_type nu = 1;
131 
132  for (FactorExp prime_exp : prime_exps) {
133  if (prime_exp.factor != 2) {
134  nu *= prime_exp.exp + 1;
135  }
136  }
137 
138  return nu;
139  }
140 
141 
142  nat_type
143  factorization_to_sigma(std::vector<FactorExp> prime_exps) {
144  nat_type sigma = 1;
145 
146  for (FactorExp prime_exp : prime_exps) {
147  sigma *= sum_geometric_progression_strict(prime_exp.factor, prime_exp.exp);
148  }
149 
150  return sigma;
151  }
152 
153 
154  nat_type
155  factorization_to_sigma_odd(std::vector<FactorExp> prime_exps) {
156  nat_type sigma = 1;
157 
158  for (FactorExp prime_exp : prime_exps) {
159  if (prime_exp.factor != 2) {
160  sigma *= sum_geometric_progression_strict(prime_exp.factor, prime_exp.exp);
161  }
162  }
163 
164  return sigma;
165  }
166 
167 
168  bool
170  if (is_even(n) || (n <= 1)) {
171  return (n == 2);
172  }
173  else if (n <= odd_primes_table_last()) {
174  // Search prime present in the precalculated table
176  }
177  else {
178  const nat_type sqrt_n = floor_square_root(n);
179 
180  // Search prime divisor present in the precalculated table
181  for (unsigned int i = 0; i < odd_primes_table_nb(); ++i) {
182  const nat_type prime = odd_primes_table_by_index(i);
183 
184  if (is_divide(prime, n)) {
185  return (prime == n);
186  }
187  else if (prime > sqrt_n) { // n is prime
188  return true;
189  }
190  }
191 
192 #ifdef PRIME16
193  // Search other prime divisor by iteration on potential primes
194  assert(odd_primes_table_last() % potential_prime_offsets_table_modulo() == 1);
195 
197 
198  while (p < sqrt_n) {
199  for (unsigned int i = 0; i < potential_prime_offsets_table_nb(); ++i) {
200  p += potential_prime_offsets_table_by_index(i);
201 
202  if (is_divide(p, n)) {
203  return (p == n);
204  }
205  }
206  }
207 #endif
208 
209  return true;
210  }
211  }
212 
213 
214  bool
216  assert(sizeof(int32_t) == sizeof(prime_type));
217 
218  // Binary search in the table
219  prime_type key = static_cast<prime_type>(n);
220 
221  return (nullptr
222  != std::bsearch(&key, array_odd_primes_, odd_primes_table_nb(), sizeof(prime_type),
223  [](const void *ptr_a, const void *ptr_b) -> int {
224  const prime_type a = *static_cast<const prime_type*>(ptr_a);
225  const prime_type b = *static_cast<const prime_type*>(ptr_b);
226 
227  return (a > b
228  ? 1
229  : (a < b
230  ? -1
231  : 0));
232  }));
233  }
234 
235 
236 #ifdef PRIME16
237  bool
238  read_primes_table() {}
239 #else
240  bool
242  if (array_odd_primes_ != nullptr) {
243  free(array_odd_primes_);
244  array_odd_primes_ = nullptr;
245  }
246 
247  if (sizeof(prime_type) != 4) {
248  return false;
249  }
250 
251  std::string filename = prime_filename;
252 
253  // Search the file from prime_filename
254  for (unsigned int i = 0; i < 5; ++i) {
255  if (helper::is_file_exists(filename)) {
256  break;
257  }
258 
259  filename = helper::concat_path("..", filename);
260  }
261 
262  if (!helper::is_file_exists(filename)) {
263  return false;
264  }
265 
266  const std::size_t size = (odd_primes_table_nb() + 1)*4;
267 
268  array_odd_primes_ = reinterpret_cast<prime_type*>(malloc(size));
269 
270  if (array_odd_primes_ == nullptr) {
271  return false;
272  }
273 
274  std::ifstream infile(filename, std::ios::in | std::ios::binary);
275 
276  infile.read(reinterpret_cast<char*>(array_odd_primes_), 4); // skip the first prime 2
277  infile.read(reinterpret_cast<char*>(array_odd_primes_), size); // read primes
278  array_odd_primes_[odd_primes_table_nb()] = 0;
279 
280  infile.close();
281 
282  if (infile.fail()) {
283  free(array_odd_primes_);
284  array_odd_primes_ = nullptr;
285  }
286 
287  return (array_odd_primes_ != nullptr);
288  }
289 #endif
290 
291 } // namespace sigmaodd
unsigned long nat_type
Type for natural number used in all code, on 64 bits.
Definition: sigmaodd.cl:22
constexpr nat_type sum_geometric_progression_strict(nat_type r, unsigned int k)
Return sum_geometric_progression(r, k) but only for r > 1.
nat_type floor_square_root(nat_type n)
Return the square root of n rounded to below.
Definition: helper.cpp:76
uint64_t nat_type
Type for natural number used in all code, on 64 bits.
Definition: helper.hpp:33
Structure to represent a factor with its exponent.
Definition: divisors.hpp:33
prime_type odd_primes_table_last()
Return the last odd prime number in the precalculated table.
nat_type factorization_to_nu_odd(std::vector< FactorExp > prime_exps)
Return the number of odd divisors of the number corresponding to the factorization.
Definition: primes.cpp:129
const std::string prime_filename
Default filename for the binary file "big_data/prime28.bin".
Definition: primes.cpp:35
bool is_prime(nat_type n)
Return true iff n is a prime number.
Definition: primes.cpp:169
std::pair< nat_type, unsigned int > divide_until_odd_nb(nat_type n)
Divide n by 2 until the result is odd, and return (result, number of divisions).
constexpr bool is_even(nat_type n)
Return true iff n is even.
uint32_t prime_type
Type for prime number, particularly for the table of primes.
Definition: primes.hpp:49
bool read_primes_table()
Read the binary file prime_filename to fill the table with all primes < 2^28. This table must be read...
Definition: primes.cpp:241
A lot of functions and stuffs to deal the sigma_odd problem and related stuffs.
Definition: divisors.cpp:22
constexpr nat_type MAX_POSSIBLE_N
Lower bound of the bigger number such that it is possible to compute the result of the sigma function...
Definition: helper.hpp:54
bool is_file_exists(std::string filename)
Return true iff the file (or directory) exists.
Definition: helper.cpp:140
constexpr bool is_divide(nat_type d, nat_type n)
Return true iff d divide n, i.e. if n is divisible by d.
constexpr nat_type pow_nat(nat_type n, unsigned int k)
Return x^k, x power k.
Functions to access to tables of precaculated prime numbers and offsets to iterate on possible prime ...
bool is_prime_in_odd_primes_table(nat_type n)
Return true iff n is a prime number present in the precalculated table.
Definition: primes.cpp:215
const prime_type * odd_primes_table_ptr()
Return a pointer to the first number in the precalculated table.
std::vector< FactorExp > factorize(nat_type n)
Return a list of prime factors with their exponents.
Definition: primes.cpp:58
nat_type factorization_to_n(std::vector< FactorExp > prime_exps)
Return the number corresponding to the factorization.
Definition: primes.cpp:105
prime_type odd_primes_table_by_index(unsigned int i)
Return the (i + 1)th odd prime number from the precalculated table.
std::string concat_path(std::string path1, std::string path2)
Return the path composed by path1/path2.
Definition: helper.cpp:29
nat_type factorization_to_sigma_odd(std::vector< FactorExp > prime_exps)
Return the sum of odd divisors of the number corresponding to the factorization.
Definition: primes.cpp:155
nat_type factorization_to_sigma(std::vector< FactorExp > prime_exps)
Return the sum of all divisors of the number corresponding to the factorization.
Definition: primes.cpp:143
constexpr unsigned int array_odd_primes_nb_
Number of odd prime numbers in the table array_odd_primes_.
Definition: primes.hpp:85
constexpr unsigned int odd_primes_table_nb()
Return the number of odd prime numbers in the precalculated table.
const double alpha
Definition: harmonic.cpp:24
nat_type factorization_to_nu(std::vector< FactorExp > prime_exps)
Return the number of all divisors of the number corresponding to the factorization.
Definition: primes.cpp:117
prime_type * array_odd_primes_
Array of all odd prime numbers < 2^28 with a final 0. (Or < 2^16 if the macro PRIME16 is defined...
Definition: primes.cpp:48