Loading [MathJax]/extensions/tex2jax.js
Parallel numerical verification of the σ_odd problem  October 6, 2018
All Classes Namespaces Files Functions Variables Typedefs Macros
sequential.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 /** \file sequential/sequential/sequential.cpp (February 2nd, 2018)
3  *
4  * GPLv3 --- Copyright (C) 2017, 2018 Olivier Pirson
5  * http://www.opimedia.be/
6  */
7 
8 // \cond
9 #include <cassert>
10 #include <cstdlib>
11 
12 #include <algorithm>
13 #include <iostream>
14 // \endcond
15 
16 #include "../../common/sigmaodd/divisors.hpp"
17 #include "../../common/sigmaodd/sigmaodd.hpp"
18 
19 #include "sequential.hpp"
20 
21 
22 namespace sequential {
23 
24  /* ***********
25  * Functions *
26  *************/
27 
28  std::set<nat_type>
30  bool print_bad) {
31  assert(sigmaodd::is_odd(first_n));
32  assert(3 <= first_n);
33  assert(first_n <= last_n);
34  assert(last_n <= sigmaodd::MAX_POSSIBLE_N);
35 #ifdef PRIME16
36  assert(last_n < 65536);
37 #endif
38 
39  std::set<nat_type> bad_table;
40 
41  for (nat_type n = first_n; n <= last_n; n += 2) {
44  bad_table,
45  first_n)) { // bad number identified
46  bad_table.insert(n);
47  if (print_bad) {
48  std::cout << n << std::endl;
49  }
50  }
51  }
52  if (print_bad) {
53  std::cout.flush();
54  }
55 
56  return bad_table;
57  }
58 
59 
60  std::set<nat_type>
62  const std::set<nat_type> &bad_table,
63  nat_type bad_first_n, nat_type bad_last_n,
64  bool print_bad) {
65  assert(sigmaodd::is_odd(first_n));
66  assert(3 <= first_n);
67  assert(first_n <= last_n);
68  assert(last_n <= sigmaodd::MAX_POSSIBLE_N);
69 #ifdef PRIME16
70  assert(last_n < 65536);
71 #endif
72 
73  std::set<nat_type> new_bad_table;
74 
75  for (nat_type n = first_n; n <= last_n; n += 2) {
78  bad_table,
79  bad_first_n, bad_last_n)) { // bad number identified
80  new_bad_table.insert(n);
81  if (print_bad) {
82  std::cout << n << std::endl;
83  }
84  }
85  }
86  if (print_bad) {
87  std::cout.flush();
88  }
89 
90  return new_bad_table;
91  }
92 
93 
94  void
96  bool print_bad,
97  bool print_all,
98  bool print_category,
99  bool print_lower,
100  bool print_length,
101  bool print_path) {
102  assert(sigmaodd::is_odd(first_n));
103  assert(3 <= first_n);
104  assert(first_n <= last_n);
105  assert(last_n <= sigmaodd::MAX_POSSIBLE_N);
106 #ifdef PRIME16
107  assert(last_n < 65536);
108 #endif
109 
110  for (nat_type n = first_n; n <= last_n; n += 2) {
111  if (!sigmaodd::is_first_mersenne_prime_unitary_divide(n)) { // not useless to check
112  const std::vector<nat_type> path = sequential_iterate_varsigma_odd_until_lower(n);
113 
115  print_bad, print_all,
116  print_category,
117  print_lower, print_length, print_path);
118  }
119  }
120  }
121 
122 
123  void
125  bool print,
126  bool print_lower,
127  bool print_length,
128  bool print_path) {
129  assert(sigmaodd::is_odd(n));
130  assert(sigmaodd::is_square(n));
131  assert(3 <= n);
132  assert(n <= sigmaodd::MAX_POSSIBLE_N);
133 #ifdef PRIME16
134  assert(n < 65536);
135 #endif
136 
137  const std::vector<nat_type> path
139 
141  print, print,
142  false,
143  print_lower, print_length, print_path);
144  }
145 
146 
147  void
149  bool check_useless,
150  bool print_bad,
151  bool print_all,
152  bool print_category,
153  bool print_lower,
154  bool print_length,
155  bool print_path) {
156  assert(sigmaodd::is_odd(first_n));
157  assert(3 <= first_n);
158  assert(first_n <= last_n);
159  assert(last_n <= sigmaodd::MAX_POSSIBLE_N);
160 #ifdef PRIME16
161  assert(last_n < 65536);
162 #endif
163 
164  for (nat_type n = first_n; n <= last_n; n += 2) {
165  if (check_useless ||
166  !sigmaodd::is_first_mersenne_prime_unitary_divide(n)) { // not useless to check
167  const std::vector<nat_type> path = sequential_iterate_varsigma_odd_until_1(n);
168 
170  print_bad, print_all,
171  print_category,
172  print_lower, print_length, print_path);
173  }
174  }
175  }
176 
177 
178  void
180  bool print,
181  bool print_lower,
182  bool print_length,
183  bool print_path) {
184  assert(sigmaodd::is_odd(n));
185  assert(sigmaodd::is_square(n));
186  assert(3 <= n);
187  assert(n <= sigmaodd::MAX_POSSIBLE_N);
188 #ifdef PRIME16
189  assert(n < 65536);
190 #endif
191 
192  const std::vector<nat_type> path = sequential_iterate_varsigma_odd_perfect_square_until_1(n);
193 
195  print, print,
196  false,
197  print_lower, print_length, print_path);
198  }
199 
200 
201  bool
203  const std::set<nat_type> &bad_table,
204  nat_type bad_first_n) {
205  assert(sigmaodd::is_odd(n));
206  assert(3 <= n);
207  assert(n <= sigmaodd::MAX_POSSIBLE_N);
208 #ifdef PRIME16
209  assert(n < 65536);
210 #endif
211 
212  assert(sigmaodd::array_odd_primes_ != nullptr);
213 
214  nat_type n_divided = n;
215  nat_type sqrt_n_divided = sigmaodd::floor_square_root(n_divided);
217  const prime_type* prime_ptr = sigmaodd::odd_primes_table_ptr() - 1;
218  nat_type prime;
219 
220  while ((prime = *(++prime_ptr)) <= sqrt_n_divided) {
221  assert(prime != 0);
222 
223  unsigned int alpha = 0;
224 
225  while (sigmaodd::is_divide(prime, n_divided)) {
226  n_divided /= prime;
227  ++alpha;
228  }
229 
230  if (alpha > 0) {
231  varsigma_odd
233 
234  sqrt_n_divided = sigmaodd::floor_square_root(n_divided);
235  if (varsigma_odd
236  * sequential_sigma_odd_upper_bound_with_sqrt(n_divided, bad_table, bad_first_n,
237  sqrt_n_divided) < n) {
238  return true;
239  }
240  }
241  }
242 
243  // Remain n_divided is prime
244  if (n_divided > 1) {
245  varsigma_odd *= sigmaodd::divide_until_odd(n_divided + 1);
246  }
247 
248  return (varsigma_odd < n);
249  }
250 
251 
252  bool
254  const std::set<nat_type> &bad_table,
255  nat_type bad_first_n, nat_type bad_last_n) {
256  assert(sigmaodd::is_odd(n));
257  assert(3 <= n);
258  assert(n <= sigmaodd::MAX_POSSIBLE_N);
259 #ifdef PRIME16
260  assert(n < 65536);
261 #endif
262 
263  assert(sigmaodd::array_odd_primes_ != nullptr);
264 
265  nat_type n_divided = n;
266  nat_type sqrt_n_divided = sigmaodd::floor_square_root(n_divided);
268  const prime_type* prime_ptr = sigmaodd::odd_primes_table_ptr() - 1;
269  nat_type prime;
270 
271  while ((prime = *(++prime_ptr)) <= sqrt_n_divided) {
272  assert(prime != 0);
273 
274  unsigned int alpha = 0;
275 
276  while (sigmaodd::is_divide(prime, n_divided)) {
277  n_divided /= prime;
278  ++alpha;
279  }
280 
281  if (alpha > 0) {
282  varsigma_odd
284 
285  sqrt_n_divided = sigmaodd::floor_square_root(n_divided);
286  if (varsigma_odd
287  * sequential_sigma_odd_upper_bound_with_sqrt(n_divided, bad_table, bad_first_n, bad_last_n,
288  sqrt_n_divided) < n) {
289  return true;
290  }
291  }
292  }
293 
294  // Remain n_divided is prime
295  if (n_divided > 1) {
296  varsigma_odd *= sigmaodd::divide_until_odd(n_divided + 1);
297  }
298 
299  return (varsigma_odd < n);
300  }
301 
302 
303  std::vector<nat_type>
305  assert(sigmaodd::is_odd(start_n));
306  assert(3 <= start_n);
307  assert(start_n <= sigmaodd::MAX_POSSIBLE_N);
308 #ifdef PRIME16
309  assert(start_n < 65536);
310 #endif
311 
312  nat_type n = start_n;
313  std::set<nat_type> already;
314  std::vector<nat_type> path;
315 
316  already.insert(n);
317  path.push_back(n);
318 
319  do {
321  if (already.find(n) != already.end()) {
322  std::cout << "! Found not trivial cycle ";
323  sigmaodd::print_path(path);
324  std::cout << std::endl;
325 
326  exit(EXIT_FAILURE);
327  }
328  else if (n > sigmaodd::MAX_POSSIBLE_N) {
329  std::cout << "! Impossible to check ";
330  sigmaodd::print_path(path);
331  std::cout << std::endl;
332 
333  exit(EXIT_FAILURE);
334  }
335 
336  already.insert(n);
337  path.push_back(n);
338  } while (n > 1);
339 
340  return path;
341  }
342 
343 
344  std::vector<nat_type>
346  assert(sigmaodd::is_odd(start_n));
347  assert(sigmaodd::is_square(start_n));
348  assert(3 <= start_n);
349  assert(start_n <= sigmaodd::MAX_POSSIBLE_N);
350 #ifdef PRIME16
351  assert(start_n < 65536);
352 #endif
353 
354  nat_type n = start_n;
355  std::set<nat_type> already;
356  std::vector<nat_type> path;
357 
358  already.insert(n);
359  path.push_back(n);
360 
362  already.insert(n);
363  path.push_back(n);
364 
365  do {
366  if (n > sigmaodd::MAX_POSSIBLE_N) {
367  std::cout << "! Impossible to check ";
368  sigmaodd::print_path(path);
369  std::cout << std::endl;
370 
371  exit(EXIT_FAILURE);
372  }
373 
375  if (already.find(n) != already.end()) {
376  std::cout << "! Found not trivial cycle ";
377  sigmaodd::print_path(path);
378  std::cout << std::endl;
379 
380  exit(EXIT_FAILURE);
381  }
382 
383  already.insert(n);
384  path.push_back(n);
385  } while (n > 1);
386 
387  return path;
388  }
389 
390 
391  std::vector<nat_type>
393  assert(sigmaodd::is_odd(start_n));
394  assert(3 <= start_n);
395  assert(start_n <= sigmaodd::MAX_POSSIBLE_N);
396 #ifdef PRIME16
397  assert(start_n < 65536);
398 #endif
399 
400  nat_type n = start_n;
401  std::set<nat_type> already;
402  std::vector<nat_type> path;
403 
404  already.insert(n);
405  path.push_back(n);
406 
407  do {
409  if (already.find(n) != already.end()) {
410  std::cout << "! Found not trivial cycle ";
411  sigmaodd::print_path(path);
412  std::cout << std::endl;
413 
414  exit(EXIT_FAILURE);
415  }
416  else if (n > sigmaodd::MAX_POSSIBLE_N) {
417  std::cout << "! Impossible to check ";
418  sigmaodd::print_path(path);
419  std::cout << std::endl;
420 
421  exit(EXIT_FAILURE);
422  }
423 
424  already.insert(n);
425  path.push_back(n);
426  } while (n > start_n);
427 
428  return path;
429  }
430 
431 
432  std::vector<nat_type>
434  assert(sigmaodd::is_odd(start_n));
435  assert(sigmaodd::is_square(start_n));
436  assert(3 <= start_n);
437  assert(start_n <= sigmaodd::MAX_POSSIBLE_N);
438 #ifdef PRIME16
439  assert(start_n < 65536);
440 #endif
441 
442  nat_type n = start_n;
443  std::set<nat_type> already;
444  std::vector<nat_type> path;
445 
446  already.insert(n);
447  path.push_back(n);
448 
450  already.insert(n);
451  path.push_back(n);
452 
453  do {
454  if (n > sigmaodd::MAX_POSSIBLE_N) {
455  std::cout << "! Impossible to check ";
456  sigmaodd::print_path(path);
457  std::cout << std::endl;
458 
459  exit(EXIT_FAILURE);
460  }
461 
463  if (already.find(n) != already.end()) {
464  std::cout << "! Found not trivial cycle ";
465  sigmaodd::print_path(path);
466  std::cout << std::endl;
467 
468  exit(EXIT_FAILURE);
469  }
470 
471  already.insert(n);
472  path.push_back(n);
473  } while (n > start_n);
474 
475  return path;
476  }
477 
478 
479  std::vector<nat_type>
480  sequential_print_in_order(const std::set<nat_type> &ns) {
481  std::vector<nat_type> list;
482 
483  list.insert(list.begin(), ns.cbegin(), ns.cend());
484  sort(list.begin(), list.end());
485  for (nat_type n : ns) {
486  std::cout << n << std::endl;
487  }
488 
489  return list;
490  }
491 
492 
493  nat_type
495  assert(sigmaodd::is_odd(n));
496  assert(n <= sigmaodd::MAX_POSSIBLE_N);
497 #ifdef PRIME16
498  assert(n < 65536);
499 #endif
500 
501  assert(sigmaodd::array_odd_primes_ != nullptr);
502 
503  nat_type n_divided = n;
504  nat_type sqrt_n_divided = sigmaodd::floor_square_root(n_divided);
506  const prime_type* prime_ptr = sigmaodd::odd_primes_table_ptr() - 1;
507  nat_type prime;
508 
509  while ((prime = *(++prime_ptr)) <= sqrt_n_divided) {
510  assert(prime != 0);
511 
512  unsigned int alpha = 0;
513 
514  while (sigmaodd::is_divide(prime, n_divided)) {
515  n_divided /= prime;
516  ++alpha;
517  }
518 
519  if (alpha > 0) {
520  varsigma_odd
522  sqrt_n_divided = sigmaodd::floor_square_root(n_divided);
523  }
524  }
525 
526  // Remain n_divided is prime
527  if (n_divided > 1) {
528  varsigma_odd *= sigmaodd::divide_until_odd(n_divided + 1);
529  }
530 
531  return varsigma_odd;
532  }
533 
534 
535  nat_type
537  assert(sigmaodd::is_odd(n));
538  assert(sigmaodd::is_square(n));
539  assert(n <= sigmaodd::MAX_POSSIBLE_N);
540 #ifdef PRIME16
541  assert(n < 65536);
542 #endif
543 
544  assert(sigmaodd::array_odd_primes_ != nullptr);
545 
546  nat_type n_divided = n;
547  nat_type sqrt4_n = sigmaodd::floor_fourth_root(n_divided);
550 
551  while (*(++p) <= sqrt4_n) {
552  assert(*p != 0);
553 
554  unsigned int alpha = 0;
555 
556  while (sigmaodd::is_divide(*p, n_divided)) {
557  assert(sigmaodd::is_divide((*p)*(*p), n_divided));
558 
559  n_divided /= sigmaodd::square(static_cast<nat_type>(*p));
560  alpha += 2;
561  }
562 
563  if (alpha > 0) {
564  sqrt4_n = sigmaodd::floor_fourth_root(n);
565  varsigma_odd
567  }
568  }
569 
570  // Remain n_divided is an even power of a prime
571  if (n_divided > 1) {
572  unsigned int alpha = 0;
573 
574  do {
575  alpha += 2;
576  n_divided = sigmaodd::floor_square_root(n_divided);
577  } while (sigmaodd::is_square(n_divided));
578 
579  varsigma_odd
581  }
582 
583  return varsigma_odd;
584  }
585 
586 
587  std::set<nat_type>
588  sequential_varsigma_odd_greater_set(const std::vector<nat_type> &ns,
589  const std::set<nat_type> &bad_table,
590  nat_type bad_first_n, nat_type bad_last_n) {
591  assert(sigmaodd::array_odd_primes_ != nullptr);
592  std::set<nat_type> new_bad_table;
593 
594  for (nat_type n : ns) {
595  assert(sigmaodd::is_odd(n));
596  assert(3 <= n);
597  assert(n <= sigmaodd::MAX_POSSIBLE_N);
598 #ifdef PRIME16
599  assert(n < 65536);
600 #endif
601 
602  if (!sequential_is_varsigma_odd_lower(n, bad_table, bad_first_n, bad_last_n)) {
603  new_bad_table.insert(n);
604  }
605  }
606 
607  return new_bad_table;
608  }
609 
610 } // namespace sequential
std::vector< nat_type > sequential_print_in_order(const std::set< nat_type > &ns)
Print number from ns, in increasing order and return a list of these number in the same order...
Definition: sequential.cpp:480
std::set< nat_type > sequential_check_gentle_varsigma_odd(nat_type first_n, nat_type last_n, bool print_bad)
Check in the order all odd gentle numbers between first_n and last_n, and if print_bad then print all...
Definition: sequential.cpp:29
constexpr nat_type sum_geometric_progression_strict(nat_type r, unsigned int k)
Return sum_geometric_progression(r, k) but only for r > 1.
void sequential_check_varsigma_odd_perfect_square(nat_type n, bool print, bool print_lower, bool print_length, bool print_path)
Return sequential_check_varsigma_odd(), but only for n perfect square.
Definition: sequential.cpp:124
nat_type floor_square_root(nat_type n)
Return the square root of n rounded to below.
Definition: helper.cpp:76
sigmaodd::nat_type nat_type
Definition: sequential.hpp:26
void print_path_infos(const std::vector< nat_type > &path, bool print_bad, bool print_all, bool print_category, bool print_lower, bool print_length, bool print_path, std::ostream &out)
Send (if the below condition is true) to the stream a string representation of the path with some inf...
Definition: sigmaodd.cpp:279
constexpr bool is_odd(nat_type n)
Return true iff n is odd.
sigmaodd::prime_type prime_type
Definition: sequential.hpp:27
std::vector< nat_type > sequential_iterate_varsigma_odd_perfect_square_until_1(nat_type start_n)
Return sequential_iterate_varsigma_odd_until_1(), but only for n perfect square.
Definition: sequential.cpp:345
std::vector< nat_type > sequential_iterate_varsigma_odd_until_lower(nat_type start_n)
Iterate sequential_varsigma_odd(start_n) until to be have a result < start_n. Return this partial pat...
Definition: sequential.cpp:392
void sequential_check_varsigma_odd_complete(nat_type first_n, nat_type last_n, bool check_useless, bool print_bad, bool print_all, bool print_category, bool print_lower, bool print_length, bool print_path)
Check completely (until 1) in the order all odd numbers between first_n and last_n. The consequence of the result is that: all odd numbers checked between first_n and last_n (included) respect the conjecture.
Definition: sequential.cpp:148
nat_type divide_until_odd(nat_type n)
Return n divided by 2 until the result is odd.
bool sequential_is_varsigma_odd_lower(nat_type n, const std::set< nat_type > &bad_table, nat_type bad_first_n)
Return true iff varsigma_odd(n) < n.
Definition: sequential.cpp:202
bool is_square(nat_type n)
Return true iff n is a perfect square.
Definition: divisors.cpp:267
std::set< nat_type > sequential_varsigma_odd_greater_set(const std::vector< nat_type > &ns, const std::set< nat_type > &bad_table, nat_type bad_first_n, nat_type bad_last_n)
Return the set of n from ns such that varsigma_odd(n) > n.
Definition: sequential.cpp:588
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
constexpr bool is_divide(nat_type d, nat_type n)
Return true iff d divide n, i.e. if n is divisible by d.
const prime_type * odd_primes_table_ptr()
Return a pointer to the first number in the precalculated table.
nat_type sequential_varsigma_odd_perfect_square(nat_type n)
Return sequential_varsigma_odd(), but only for n perfect square.
Definition: sequential.cpp:536
void sequential_check_varsigma_odd_perfect_square_complete(nat_type n, bool print, bool print_lower, bool print_length, bool print_path)
Return sequential_check_varsigma_odd_complete(), but only for n perfect square.
Definition: sequential.cpp:179
nat_type floor_fourth_root(nat_type n)
Return the fourth root of n rounded to below.
Definition: helper.cpp:52
Implementation of the sequential algorithms presented in the report. (Some functions are not use in t...
constexpr nat_type sequential_sigma_odd_upper_bound_with_sqrt(nat_type n, const std::set< nat_type > &bad_table, nat_type bad_first_n, nat_type sqrt_n)
Return an upper bound of varsigma_odd(n).
std::vector< nat_type > sequential_iterate_varsigma_odd_until_1(nat_type start_n)
Iterate sequential_varsigma_odd(start_n) until to reach 1. Return this complete path.
Definition: sequential.cpp:304
constexpr bool is_first_mersenne_prime_unitary_divide_or_square(nat_type n)
Return true iff is_first_mersenne_prime_unitary_divide(n) or is_square(n).
void print_path(const std::vector< nat_type > &path, std::ostream &out)
Send to the stream a string representation of the path. All numbers are separated by the correspondin...
Definition: sigmaodd.cpp:251
constexpr bool is_first_mersenne_prime_unitary_divide(nat_type n)
Return true iff at least one of 3, 7, 31 or 127 is an unitary divisor of n.
std::vector< nat_type > sequential_iterate_varsigma_odd_perfect_square_until_lower(nat_type start_n)
Return sequential_iterate_varsigma_odd_until_lower(), but only for n perfect square.
Definition: sequential.cpp:433
constexpr double square(double x)
Return x*x.
const double alpha
Definition: harmonic.cpp:24
nat_type sequential_varsigma_odd(nat_type n)
Return varsigma_odd(n), i.e. the sum of all odd divisors of n, divided by 2 until to be odd...
Definition: sequential.cpp:494
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
void sequential_check_varsigma_odd(nat_type first_n, nat_type last_n, bool print_bad, bool print_all, bool print_category, bool print_lower, bool print_length, bool print_path)
Check in the order all odd numbers between first_n and last_n. The consequence of the result is that:...
Definition: sequential.cpp:95
nat_type varsigma_odd(__global const prime_type *primes, nat_type n)
Return varsigma_odd(n), i.e. the sum of all odd divisors of n, divided by 2 until to be odd...
Definition: sigmaodd.cl:497