Loading [MathJax]/extensions/tex2jax.js
Parallel numerical verification of the σ_odd problem  October 6, 2018
All Classes Namespaces Files Functions Variables Typedefs Macros
harmonic.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 /** \file common/sigmaodd/harmonic.cpp (February 14, 2018)
3  *
4  * GPLv3 --- Copyright (C) 2017, 2018 Olivier Pirson
5  * http://www.opimedia.be/
6  */
7 
8 // \cond
9 #include <cassert>
10 #include <cfenv>
11 #include <cmath>
12 // \endcond
13 
14 #include "divisors.hpp"
15 #include "harmonic.hpp"
16 
17 
18 namespace sigmaodd {
19 
20  /* *******************
21  * Private constants *
22  *********************/
23 
24  const double alpha = 0.425;
25  const double alpha_bis = 0.7;
26  const double beta = 0.40580406331047491619301581522449851;
27 
28 
29 
30  /* **********
31  * Constant *
32  ************/
33 
34  const double euler_gamma = 0.577215664901532860606512090082402431042;
35 
36 
37 
38  /* ***********
39  * Functions *
40  *************/
41  double
43  assert(a != 0);
44  assert(b != 0);
45 
46  const int round = fegetround();
47 
48  fesetround(FE_UPWARD);
49 
50  // 1/2 ln( (2a+1)^2 / (2(2b+1)) ) + gamma/2 + 1/(24 (a^2 + a + beta)) - 1/(48 (b^2 + b + alpha))
51  const double bound = ((std::log(static_cast<double>(square(a*2 + 1))
52  / static_cast<double>((b*2 + 1)*2))
53  + euler_gamma) / 2
54  - (0.5/(static_cast<double>(square(b) + b) + alpha)
55  - 1.0/(static_cast<double>(square(a) + a) + beta)) / 24.0);
56 
57  fesetround(round);
58 
59  return bound;
60  }
61 
62 
63  double
65  assert(n != 0);
66 
67  const int round = fegetround();
68 
69  fesetround(FE_UPWARD);
70 
71  // 1/2 ln( (2n+1)^2 / (2(n+1)) ) + gamma/2
72  // + 1/(24 (n^2 + n + beta)) - 1/(12 ((n+1)^2 + alpha_bis)) if n even
73  // 1/2 ln( (2n+1)^2 / (2n)) ) + gamma/2
74  // + 1/(24 (n^2 + n + beta)) - 1/(12 (n^2 + alpha_bis)) if n odd
75  const double bound = (is_even(n)
76  ? ((std::log(static_cast<double>(square(n*2 + 1))
77  / static_cast<double>((n + 1)*2))
78  + euler_gamma) / 2
79  - (1.0/(static_cast<double>(square(n + 1)) + alpha_bis)
80  - 0.5/(static_cast<double>(square(n) + n) + beta)) / 12)
81  : ((std::log(static_cast<double>(square(n*2 + 1))
82  / static_cast<double>(n*2))
83  + euler_gamma) / 2
84  - (1.0/(static_cast<double>(square(n)) + alpha_bis)
85  - 0.5/(static_cast<double>(square(n) + n) + beta)) / 12));
86 
87  fesetround(round);
88 
89  return bound;
90  }
91 
92 
93  double
95  assert(a != 0);
96  assert(b != 0);
97 
98  const int round = fegetround();
99 
100  fesetround(FE_UPWARD);
101 
102  // ln((2a + 1)/(2b + 1)) + 1/(24 (a^2 + a + beta)) - 1/(24 (b^2 + b + alpha))
103  const double bound = (std::log(static_cast<double>(a*2 + 1)
104  / static_cast<double>(b*2 + 1))
105  - (1.0/(static_cast<double>(square(b) + b) + alpha)
106  - 1.0/(static_cast<double>(square(a) + a) + beta)) / 24);
107 
108  fesetround(round);
109 
110  return bound;
111  }
112 
113 
114  double
116  assert(n != 0);
117 
118  const int round = fegetround();
119 
120  fesetround(FE_DOWNWARD);
121 
122  // ln(n + 1/2) + gamma + 1/(24 (n^2 + n + alpha))
123  const double bound = (std::log(static_cast<double>(n) + 0.5)
124  + euler_gamma
125  + 1.0/((static_cast<double>(square(n) + n) + alpha)*24));
126 
127  fesetround(round);
128 
129  return bound;
130  }
131 
132 
133  double
135  assert(n != 0);
136 
137  const int round = fegetround();
138 
139  fesetround(FE_UPWARD);
140 
141  // ln(n + 1/2) + gamma + 1/(24 (n^2 + n + beta))
142  const double bound = (std::log(static_cast<double>(n) + 0.5)
143  + euler_gamma
144  + 1.0/((static_cast<double>(square(n) + n) + beta)*24));
145 
146  fesetround(round);
147 
148  return bound;
149  }
150 
151 
152  nat_type
154  nat_type sum = 0;
155 
156  for (nat_type i = 1; i <= to_n; i += 2) {
157  sum += static_cast<nat_type>(std::floor(static_cast<double>(n)/static_cast<double>(i)));
158  }
159 
160  return sum;
161  }
162 
163 } // namespace sigmaodd
uint64_t nat_type
Type for natural number used in all code, on 64 bits.
Definition: helper.hpp:33
double harmonic_lower_bound(nat_type n)
Return a lower bound of H_n.
Definition: harmonic.cpp:115
const double beta
Definition: harmonic.cpp:26
constexpr bool is_even(nat_type n)
Return true iff n is even.
double diff_half_harmonic_upper_bound(nat_type a, nat_type b)
Return an upper bound of H_a - 1/2 H_b.
Definition: harmonic.cpp:42
A lot of functions and stuffs to deal the sigma_odd problem and related stuffs.
Definition: divisors.cpp:22
Function to calculate harmonic number H_n = 1 + 1/2 + 1/3 + 1/4 + ... + 1/n and some variants and upp...
nat_type sum_floor_n_harmonic_odd(nat_type n, nat_type to_n)
Return floor(n/1) + floor(n/3) + floor(n/5) + floor(n/7) + ... + (n/to_n or floor(1/(to_n-1))).
Definition: harmonic.cpp:153
constexpr double square(double x)
Return x*x.
const double alpha
Definition: harmonic.cpp:24
Functions in link with divisor notion: sum of divisors, factorization, GCD, coprime, ...
double harmonic_upper_bound(nat_type n)
Return an upper bound of H_n.
Definition: harmonic.cpp:134
const double euler_gamma
The Euler-Mascheroni constant 0.577215664901532860606512090082402431042... (rounded to an upper bound...
Definition: harmonic.cpp:34
const double alpha_bis
Definition: harmonic.cpp:25
double diff_harmonic_upper_bound(nat_type a, nat_type b)
Return an upper bound of H_a - H_b.
Definition: harmonic.cpp:94