Skip to content

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kimwalisch committed Jan 8, 2024
1 parent b777c81 commit b3927f4
Show file tree
Hide file tree
Showing 3 changed files with 327 additions and 0 deletions.
101 changes: 101 additions & 0 deletions test/Li.cpp
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;
}
127 changes: 127 additions & 0 deletions test/Ri.cpp
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;
}
99 changes: 99 additions & 0 deletions test/moebius.cpp
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;
}

0 comments on commit b3927f4

Please sign in to comment.