Driver for showing how to use the core functionalities of the Number Theory module by itself as well as with the openGPMP ThreadPool. This features functions related to primes specifically generation and testing.
#include <chrono>
#include <cmath>
#include <iostream>
#include <vector>
std::chrono::steady_clock::time_point start_time =
std::chrono::steady_clock::now();
std::cout << "Miller-Rabin sequentially without ThreadPool" << std::endl;
for (uint64_t n : nums) {
std::cout << n << " is prime" << std::endl;
else
std::cout << n << " is composite" << std::endl;
}
std::chrono::steady_clock::time_point end_time =
std::chrono::steady_clock::now();
std::cout << "Time elapsed: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
end_time - start_time)
.count()
<< " ms" << std::endl;
}
std::chrono::steady_clock::time_point start_time =
std::chrono::steady_clock::now();
std::vector<std::future<bool>> miller_results;
for (auto n : nums) {
miller_results.emplace_back(pool->
enqueue(
[&
prim, n]() { return prim.miller_rabin_prime(n, 120000); }));
}
std::cout << "\nResults:\n";
std::cout << "Miller-Rabin with ThreadPool" << std::endl;
for (size_t i = 0; i < miller_results.size(); i++) {
bool is_prime = miller_results[i].get();
std::cout << nums[i] << " is " << (is_prime ? "prime" : "composite")
<< "\n";
}
delete pool;
std::chrono::steady_clock::time_point end_time =
std::chrono::steady_clock::now();
std::cout << "Time elapsed: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
end_time - start_time)
.count()
<< " ms" << std::endl;
}
std::chrono::steady_clock::time_point start_time =
std::chrono::steady_clock::now();
auto start = std::chrono::high_resolution_clock::now();
std::vector<std::future<bool>> miller_results;
for (auto n : nums) {
*pool,
n,
120000));
}
std::cout << "\nResults:\n";
std::cout << "Miller-Rabin with ThreadPool using ThreadDispatch.dispatch()"
<< std::endl;
for (size_t i = 0; i < miller_results.size(); i++) {
bool is_prime = miller_results[i].get();
std::cout << nums[i] << " is " << (is_prime ? "prime" : "composite")
<< "\n";
}
delete pool;
std::chrono::steady_clock::time_point end_time =
std::chrono::steady_clock::now();
std::cout << "Time elapsed: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
end_time - start_time)
.count()
<< " ms" << std::endl;
}
std::cout << "BASIC NUMBER THEORY OPERATIONS\n" << std::endl;
std::cout << "<--------- IS IT PRIME? --------->\n";
int a = 9;
std::cout << a << " is prime? : ";
is_it ? std::cout << "true\n" : std::cout << "false\n" << std::endl;
int b = 2;
std::cout << b << " is prime? : ";
is_it2 ? std::cout << "true\n" : std::cout << "false\n" << std::endl;
std::cout << "\n";
std::cout << "<--------- MILLER-RABIN METHOD --------->\n";
int min_num = 1;
int max_num = 100;
int iters = 4;
std::cout << "\n";
std::cout << "<--------- CARMICHAEL NUMBERS --------->\n";
int cm_test = 500;
int cm_test1 = 561;
int cm_test2 = 1105;
std::cout << cm_test << " is a carmichael number : ";
carm_num ? std::cout << "true\n" : std::cout << "false\n";
std::cout << cm_test1 << " is a carmichael number : ";
carm_num1 ? std::cout << "true\n" : std::cout << "false\n";
std::cout << cm_test2 << " is a carmichael number : ";
carm_num2 ? std::cout << "true\n" : std::cout << "false\n";
std::cout << "\n";
int pow_a = 3;
int pow_b = 2;
int pow_c = 2;
int pow_res = p.
mod_pow(pow_a, pow_b, pow_c);
printf("%d ^ %d %% %d = %d\n", pow_a, pow_b, pow_c, pow_res);
int pow_d = 5;
int pow_e = 2;
int pow_f = 7;
int pow_res_1 = p.
mod_pow(pow_d, pow_e, pow_f);
printf("%d ^ %d %% %d = %d\n", pow_d, pow_e, pow_f, pow_res_1);
int pow_g = 8;
int pow_h = 9;
int pow_i = 3;
int pow_res_2 = p.
mod_pow(pow_g, pow_h, pow_i);
printf("%d ^ %d %% %d = %d\n", pow_g, pow_h, pow_i, pow_res_2);
std::cout << "miller_rabin_prime: " << cmp << "\n";
std::cout << "\n";
int ss_0 = 15;
printf("%d is prime\n", ss_0);
else
printf("%d is composite\n", ss_0);
std::cout << "\n";
std::vector<int64_t> nums = {
9223372036854775803, 9223372036854775807, 9223372036854775303,
4567890123456789LL, 5678901234567890LL, 6789012345678901LL,
7890123456789012LL, 8901234567890123LL, 9999999967LL,
12345678901234567LL, 987654321987654321LL, 2147483647LL,
9223372036854775783LL, 1311768467463790320LL, 7237005577332262210LL,
3037000499LL, 2305843009213693951LL, 2305843009213693967LL,
2305843009213693971LL, 2305843009213693973LL, 2305843009213693977LL,
2305843009213693989LL};
std::cout << "<--------- USING THREADPOOL --------->\n";
return 0;
}
bool miller_rabin_prime(uint64_t n, uint64_t iters)
Modified primes algorithm.
bool carmichael_num(uint64_t n)
void miller_rabin(uint64_t iters, uint64_t min_val, uint64_t max_val)
Miller-Rabin driver, prints values that satisfy conditions.
uint64_t mod_pow(uint64_t a, uint64_t b, uint64_t m)
bool is_prime(uint64_t n)
Determine if an integer is prime.
bool solovoy_strassen(uint64_t p, uint64_t iters)
A class that provides a function to dispatch a function call to a thread pool and return a future obj...
auto enqueue(F &&f, Args &&...args) -> std::future< typename std::invoke_result< F, Args... >::type >
Enqueues a task to the thread pool.
void testing_miller(std::vector< int64_t > nums)
void testing_new_miller(std::vector< int64_t > nums)
void testing_miller_thread(std::vector< int64_t > nums)