-
-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b777c81
commit b3927f4
Showing
3 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/// | ||
/// @file Li.cpp | ||
/// @brief Test the offset logarithmic integral function. | ||
/// Li(x) = li(x) - li(2) | ||
/// | ||
/// Copyright (C) 2024 Kim Walisch, <[email protected]> | ||
/// | ||
/// This file is distributed under the BSD License. See the COPYING | ||
/// file in the top level directory. | ||
/// | ||
|
||
#include <primesieve/nthPrimeApprox.hpp> | ||
|
||
#include <stdint.h> | ||
#include <iostream> | ||
#include <cmath> | ||
#include <cstdlib> | ||
#include <vector> | ||
|
||
using std::max; | ||
using std::size_t; | ||
using namespace primesieve; | ||
|
||
std::vector<uint64_t> Li_table = | ||
{ | ||
5, // Li(10^1) | ||
29, // Li(10^2) | ||
176, // Li(10^3) | ||
1245, // Li(10^4) | ||
9628, // Li(10^5) | ||
78626, // Li(10^6) | ||
664917, // Li(10^7) | ||
5762208, // Li(10^8) | ||
50849233, // Li(10^9) | ||
455055613, // Li(10^10) | ||
4118066399ll, // Li(10^11) | ||
37607950279ll, // Li(10^12) | ||
346065645809ll, // Li(10^13) | ||
3204942065690ll, // Li(10^14) | ||
29844571475286ll // Li(10^15) | ||
}; | ||
|
||
void check(bool OK) | ||
{ | ||
std::cout << " " << (OK ? "OK" : "ERROR") << "\n"; | ||
if (!OK) | ||
std::exit(1); | ||
} | ||
|
||
int main() | ||
{ | ||
uint64_t x = 1; | ||
for (size_t i = 0; i < Li_table.size(); i++) | ||
{ | ||
x *= 10; | ||
std::cout << "Li(" << x << ") = " << Li(x); | ||
check(Li(x) == Li_table[i]); | ||
} | ||
|
||
x = 1; | ||
for (size_t i = 0; i < Li_table.size(); i++) | ||
{ | ||
x *= 10; | ||
std::cout << "Li_inverse(" << Li_table[i] << ") = " << Li_inverse(Li_table[i]); | ||
check(Li_inverse(Li_table[i]) <= x && | ||
Li_inverse(Li_table[i] + 1) > x); | ||
} | ||
|
||
// Sanity checks for small values of Li(x) | ||
for (x = 0; x < 300000; x++) | ||
{ | ||
uint64_t lix = Li(x); | ||
double logx = std::log(max((double) x, 2.0)); | ||
|
||
if ((x >= 11 && lix < x / logx) || | ||
(x >= 2 && lix > x * logx)) | ||
{ | ||
std::cout << "Li(" << x << ") = " << lix << " ERROR" << std::endl; | ||
std::exit(1); | ||
} | ||
} | ||
|
||
// Sanity checks for small values of Li_inverse(x) | ||
for (x = 2; x < 30000; x++) | ||
{ | ||
uint64_t res = Li_inverse(x); | ||
double logx = std::log((double) x); | ||
|
||
if (res < x || | ||
(x >= 4 && res > x * logx * logx)) | ||
{ | ||
std::cout << "Li_inverse(" << x << ") = " << res << " ERROR" << std::endl; | ||
std::exit(1); | ||
} | ||
} | ||
|
||
std::cout << std::endl; | ||
std::cout << "All tests passed successfully!" << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/// | ||
/// @file Ri.cpp | ||
/// @brief Test the Riemann R function. | ||
/// | ||
/// Copyright (C) 2024 Kim Walisch, <[email protected]> | ||
/// | ||
/// This file is distributed under the BSD License. See the COPYING | ||
/// file in the top level directory. | ||
/// | ||
|
||
#include <primesieve/nthPrimeApprox.hpp> | ||
|
||
#include <stdint.h> | ||
#include <iostream> | ||
#include <cstdlib> | ||
#include <cmath> | ||
#include <vector> | ||
|
||
using std::max; | ||
using std::size_t; | ||
using namespace primesieve; | ||
|
||
std::vector<uint64_t> Ri_table = | ||
{ | ||
4, // Ri(10^1) | ||
25, // Ri(10^2) | ||
168, // Ri(10^3) | ||
1226, // Ri(10^4) | ||
9587, // Ri(10^5) | ||
78527, // Ri(10^6) | ||
664667, // Ri(10^7) | ||
5761551, // Ri(10^8) | ||
50847455, // Ri(10^9) | ||
455050683, // Ri(10^10) | ||
4118052494ll, // Ri(10^11) | ||
37607910542ll, // Ri(10^12) | ||
346065531065ll, // Ri(10^13) | ||
3204941731601ll // Ri(10^14) | ||
}; | ||
|
||
void check(bool OK) | ||
{ | ||
std::cout << " " << (OK ? "OK" : "ERROR") << "\n"; | ||
if (!OK) | ||
std::exit(1); | ||
} | ||
|
||
int main() | ||
{ | ||
uint64_t x = 1; | ||
for (size_t i = 0; i < Ri_table.size(); i++) | ||
{ | ||
x *= 10; | ||
std::cout << "Ri(" << x << ") = " << Ri(x); | ||
check(Ri(x) == Ri_table[i]); | ||
} | ||
|
||
x = 1; | ||
for (size_t i = 0; i < Ri_table.size(); i++) | ||
{ | ||
x *= 10; | ||
std::cout << "Ri_inverse(" << Ri_table[i] << ") = " << Ri_inverse(Ri_table[i]); | ||
check(Ri_inverse(Ri_table[i]) < x && | ||
Ri_inverse(Ri_table[i] + 1) >= x); | ||
} | ||
|
||
// Sanity checks for tiny values of Ri(x) | ||
for (x = 0; x < 10000; x++) | ||
{ | ||
uint64_t rix = Ri(x); | ||
double logx = std::log(max((double) x, 2.0)); | ||
|
||
if ((x >= 20 && rix < x / logx) || | ||
(x >= 2 && rix > x * logx)) | ||
{ | ||
std::cout << "Ri(" << x << ") = " << rix << " ERROR" << std::endl; | ||
std::exit(1); | ||
} | ||
} | ||
|
||
// Sanity checks for small values of Ri(x) | ||
for (; x < 100000; x += 101) | ||
{ | ||
uint64_t rix = Ri(x); | ||
double logx = std::log(max((double) x, 2.0)); | ||
|
||
if ((x >= 20 && rix < x / logx) || | ||
(x >= 2 && rix > x * logx)) | ||
{ | ||
std::cout << "Ri(" << x << ") = " << rix << " ERROR" << std::endl; | ||
std::exit(1); | ||
} | ||
} | ||
|
||
// Sanity checks for tiny values of Ri_inverse(x) | ||
for (x = 2; x < 1000; x++) | ||
{ | ||
uint64_t res = Ri_inverse(x); | ||
double logx = std::log((double) x); | ||
|
||
if (res < x || | ||
(x >= 5 && res > x * logx * logx)) | ||
{ | ||
std::cout << "Ri_inverse(" << x << ") = " << res << " ERROR" << std::endl; | ||
std::exit(1); | ||
} | ||
} | ||
|
||
// Sanity checks for small values of Ri_inverse(x) | ||
for (; x < 100000; x += 101) | ||
{ | ||
uint64_t res = Ri_inverse(x); | ||
double logx = std::log((double) x); | ||
|
||
if (res < x || | ||
(x >= 5 && res > x * logx * logx)) | ||
{ | ||
std::cout << "Ri_inverse(" << x << ") = " << res << " ERROR" << std::endl; | ||
std::exit(1); | ||
} | ||
} | ||
|
||
std::cout << std::endl; | ||
std::cout << "All tests passed successfully!" << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/// | ||
/// @file moebius.cpp | ||
/// @brief Test the generate_moebius(n) function | ||
/// @link https://en.wikipedia.org/wiki/Moebius_function | ||
/// | ||
/// Copyright (C) 2024 Kim Walisch, <[email protected]> | ||
/// | ||
/// This file is distributed under the BSD License. See the COPYING | ||
/// file in the top level directory. | ||
/// | ||
|
||
#include <primesieve/nthPrimeApprox.hpp> | ||
|
||
#include <stdint.h> | ||
#include <iostream> | ||
#include <cstdlib> | ||
#include <vector> | ||
|
||
using std::size_t; | ||
using namespace primesieve; | ||
|
||
/// Values of mu(n) for the first 1000 integers | ||
/// https://oeis.org/A008683/b008683.txt | ||
std::vector<int> moebius = | ||
{ | ||
0, 1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, | ||
0, 1, 1, -1, 0, 0, 1, 0, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, 1, 1, | ||
0, -1, -1, -1, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 1, 0, 1, 1, -1, | ||
0, -1, 1, 0, 0, 1, -1, -1, 0, 1, -1, -1, 0, -1, 1, 0, 0, 1, -1, -1, | ||
0, 0, 1, -1, 0, 1, 1, 1, 0, -1, 0, 1, 0, 1, 1, 1, 0, -1, 0, 0, | ||
0, -1, -1, -1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, 1, 0, 0, 1, 1, | ||
0, 0, 1, 1, 0, 0, 0, -1, 0, 1, -1, -1, 0, 1, 1, 0, 0, -1, -1, -1, | ||
0, 1, 1, 1, 0, 1, 1, 0, 0, -1, 0, -1, 0, 0, -1, 1, 0, -1, 1, 1, | ||
0, 1, 0, -1, 0, -1, 1, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, 1, 1, -1, | ||
0, -1, -1, 1, 0, 1, -1, 1, 0, 0, -1, -1, 0, -1, 1, -1, 0, -1, 0, -1, | ||
0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, -1, 0, 1, 1, 1, 0, 1, 1, 1, | ||
0, 1, -1, -1, 0, 0, 1, -1, 0, -1, -1, -1, 0, -1, 0, 1, 0, 1, -1, -1, | ||
0, -1, 0, 0, 0, 0, -1, 1, 0, 1, 0, -1, 0, 1, 1, -1, 0, -1, -1, 1, | ||
0, 0, 1, -1, 0, 1, -1, 1, 0, -1, 0, -1, 0, -1, 1, 0, 0, -1, 1, 0, | ||
0, -1, -1, -1, 0, -1, -1, 1, 0, 0, -1, 1, 0, -1, 0, 1, 0, 0, 1, 1, | ||
0, 1, 1, 1, 0, 1, 0, -1, 0, 1, -1, -1, 0, -1, 1, 0, 0, -1, -1, 1, | ||
0, 1, -1, 1, 0, 0, 1, 1, 0, 1, 1, -1, 0, 0, 1, 1, 0, -1, 0, 1, | ||
0, 1, 0, 0, 0, -1, 1, -1, 0, -1, 0, 0, 0, -1, -1, 1, 0, -1, 1, -1, | ||
0, 0, 1, 0, 0, 1, -1, -1, 0, 0, -1, 1, 0, -1, -1, 0, 0, 1, 0, -1, | ||
0, 1, 1, -1, 0, -1, 1, 0, 0, -1, 1, 1, 0, 1, 1, 1, 0, -1, 1, -1, | ||
0, -1, -1, 1, 0, 0, -1, 1, 0, -1, -1, 1, 0, 1, 0, 1, 0, 1, -1, -1, | ||
0, -1, 1, 0, 0, 0, -1, 1, 0, -1, -1, -1, 0, -1, -1, -1, 0, 1, -1, -1, | ||
0, 0, -1, -1, 0, 1, 1, 1, 0, -1, 0, 1, 0, 1, 1, -1, 0, -1, 1, 0, | ||
0, -1, 1, -1, 0, -1, 1, -1, 0, 1, -1, 1, 0, 1, -1, 0, 0, 0, 1, -1, | ||
0, 1, 1, -1, 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, -1, 0, 0, 1, -1, -1, | ||
0, 1, 1, -1, 0, 1, -1, 0, 0, -1, 1, 1, 0, 0, 1, 1, 0, 1, -1, 1, | ||
0, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 1, -1, 1, 0, 1, 1, 0, | ||
0, -1, 1, 1, 0, 1, 1, -1, 0, 0, 0, 1, 0, 1, 1, -1, 0, -1, 0, 1, | ||
0, -1, 1, -1, 0, 1, 1, 0, 0, -1, 1, -1, 0, 1, -1, 0, 0, -1, 0, 1, | ||
0, 1, -1, 1, 0, 0, 1, -1, 0, 1, -1, 1, 0, -1, 0, -1, 0, 1, -1, -1, | ||
0, -1, -1, 0, 0, 0, -1, -1, 0, -1, -1, 1, 0, -1, 1, -1, 0, -1, -1, -1, | ||
0, 0, 1, 1, 0, 0, 1, -1, 0, 1, 0, -1, 0, 1, 1, 1, 0, 0, -1, 0, | ||
0, -1, -1, -1, 0, -1, -1, -1, 0, 1, 0, -1, 0, -1, -1, 1, 0, 0, -1, -1, | ||
0, -1, 1, -1, 0, -1, 0, 1, 0, 1, -1, 1, 0, -1, 1, 0, 0, -1, -1, 1, | ||
0, 1, -1, -1, 0, 1, 0, 1, 0, 1, 1, -1, 0, 0, 1, 1, 0, 1, 1, 1, | ||
0, -1, 0, 1, 0, -1, 1, 1, 0, -1, -1, 0, 0, 1, 1, -1, 0, 1, 1, -1, | ||
0, 1, 0, 1, 0, 0, 0, -1, 0, 0, -1, 1, 0, -1, 1, 0, 0, 1, 0, -1, | ||
0, -1, -1, -1, 0, 1, 1, 0, 0, 1, 0, -1, 0, 1, -1, 1, 0, -1, 1, -1, | ||
0, -1, -1, 1, 0, 0, 1, 1, 0, -1, 1, 1, 0, -1, 0, 0, 0, -1, 1, 1, | ||
0, 1, -1, 0, 0, 1, -1, -1, 0, 1, -1, 1, 0, 1, 1, -1, 0, -1, 1, 1, | ||
0, 0, 1, 1, 0, -1, -1, 1, 0, -1, 0, -1, 0, 1, -1, 1, 0, 1, 1, 0, | ||
0, -1, -1, -1, 0, 0, -1, -1, 0, -1, -1, 1, 0, 0, -1, 1, 0, 0, 1, -1, | ||
0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, -1, -1, 0, 0, -1, 1, -1, | ||
0, -1, 1, -1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, -1, 0, 0, -1, 1, 1, | ||
0, -1, 0, -1, 0, -1, 1, -1, 0, 1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 1, | ||
0, 1, -1, -1, 0, 1, -1, -1, 0, 0, 1, -1, 0, 1, 1, -1, 0, 1, 0, -1, | ||
0, 1, 1, 1, 0, 0, 1, 0, 0, -1, 1, 0, 0, 1, 1, -1, 0, -1, -1, 1, | ||
0, -1, -1, 1, 0, 0, -1, -1, 0, 1, 0, 1, 0, -1, 0, 1, 0, -1, 1, 1, | ||
0, 0, -1, 0, 0, 1, 1, -1, 0, -1, -1, -1, 0, 1, 1, 0, 0, -1, -1, 1, | ||
0, 0, 1, -1, 0, 1, -1, -1, 0, 1, 0, -1, 0, 1, -1, 1, 0, -1, 1, 0 | ||
}; | ||
|
||
void check(bool OK) | ||
{ | ||
std::cout << " " << (OK ? "OK" : "ERROR") << "\n"; | ||
if (!OK) | ||
std::exit(1); | ||
} | ||
|
||
int main() | ||
{ | ||
auto mu = generate_moebius(moebius.size() - 1); | ||
|
||
for (size_t i = 1; i < mu.size(); i++) | ||
{ | ||
std::cout << "mu(" << i << ") = " << mu[i]; | ||
check(mu[i] == moebius[i]); | ||
} | ||
|
||
std::cout << std::endl; | ||
std::cout << "All tests passed successfully!" << std::endl; | ||
|
||
return 0; | ||
} |