brew install cmake
brew install primesieve
brew install boost
brew install mpfr
cmake .
Created
February 3, 2019 17:49
-
-
Save pstoll/9bf1b7f967b98985f845c493ef660d0a to your computer and use it in GitHub Desktop.
hex sum 1.0.4 source setup.
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
# Try to find the MPFR library | |
# See http://www.mpfr.org/ | |
# | |
# This module supports requiring a minimum version, e.g. you can do | |
# find_package(MPFR 2.3.0) | |
# to require version 2.3.0 to newer of MPFR. | |
# | |
# Once done this will define | |
# | |
# MPFR_FOUND - system has MPFR lib with correct version | |
# MPFR_INCLUDES - the MPFR include directory | |
# MPFR_LIBRARIES - the MPFR library | |
# MPFR_VERSION - MPFR version | |
# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org> | |
# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr> | |
# Copyright (c) 2010 Jitse Niesen, <jitse@maths.leeds.ac.uk> | |
# Redistribution and use is allowed according to the terms of the BSD license. | |
# Set MPFR_INCLUDES | |
find_path(MPFR_INCLUDES | |
NAMES | |
mpfr.h | |
PATHS | |
$ENV{GMPDIR} | |
${INCLUDE_INSTALL_DIR} | |
) | |
# Set MPFR_FIND_VERSION to 1.0.0 if no minimum version is specified | |
if(NOT MPFR_FIND_VERSION) | |
if(NOT MPFR_FIND_VERSION_MAJOR) | |
set(MPFR_FIND_VERSION_MAJOR 1) | |
endif(NOT MPFR_FIND_VERSION_MAJOR) | |
if(NOT MPFR_FIND_VERSION_MINOR) | |
set(MPFR_FIND_VERSION_MINOR 0) | |
endif(NOT MPFR_FIND_VERSION_MINOR) | |
if(NOT MPFR_FIND_VERSION_PATCH) | |
set(MPFR_FIND_VERSION_PATCH 0) | |
endif(NOT MPFR_FIND_VERSION_PATCH) | |
set(MPFR_FIND_VERSION "${MPFR_FIND_VERSION_MAJOR}.${MPFR_FIND_VERSION_MINOR}.${MPFR_FIND_VERSION_PATCH}") | |
endif(NOT MPFR_FIND_VERSION) | |
if(MPFR_INCLUDES) | |
# Set MPFR_VERSION | |
file(READ "${MPFR_INCLUDES}/mpfr.h" _mpfr_version_header) | |
string(REGEX MATCH "define[ \t]+MPFR_VERSION_MAJOR[ \t]+([0-9]+)" _mpfr_major_version_match "${_mpfr_version_header}") | |
set(MPFR_MAJOR_VERSION "${CMAKE_MATCH_1}") | |
string(REGEX MATCH "define[ \t]+MPFR_VERSION_MINOR[ \t]+([0-9]+)" _mpfr_minor_version_match "${_mpfr_version_header}") | |
set(MPFR_MINOR_VERSION "${CMAKE_MATCH_1}") | |
string(REGEX MATCH "define[ \t]+MPFR_VERSION_PATCHLEVEL[ \t]+([0-9]+)" _mpfr_patchlevel_version_match "${_mpfr_version_header}") | |
set(MPFR_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}") | |
set(MPFR_VERSION ${MPFR_MAJOR_VERSION}.${MPFR_MINOR_VERSION}.${MPFR_PATCHLEVEL_VERSION}) | |
# Check whether found version exceeds minimum version | |
if(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION}) | |
set(MPFR_VERSION_OK FALSE) | |
message(STATUS "MPFR version ${MPFR_VERSION} found in ${MPFR_INCLUDES}, " | |
"but at least version ${MPFR_FIND_VERSION} is required") | |
else(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION}) | |
set(MPFR_VERSION_OK TRUE) | |
endif(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION}) | |
endif(MPFR_INCLUDES) | |
# Set MPFR_LIBRARIES | |
find_library(MPFR_LIBRARIES mpfr PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR}) | |
# Epilogue | |
include(FindPackageHandleStandardArgs) | |
find_package_handle_standard_args(MPFR DEFAULT_MSG | |
MPFR_INCLUDES MPFR_LIBRARIES MPFR_VERSION_OK) | |
mark_as_advanced(MPFR_INCLUDES MPFR_LIBRARIES) |
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
cmake_minimum_required(VERSION 3.5) | |
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) | |
find_package(primesieve "7.0" REQUIRED ) | |
#if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") | |
# set(CMAKE_C_COMPILER "emcc") | |
# set(CMAKE_CXX_COMPILER "emcc") | |
#endif () | |
if(USE_QUAD_FLOAT) | |
add_library(quadmath STATIC IMPORTED) | |
find_library(quadmath_lib NAMES quadmath.a) | |
endif() | |
find_package(MPFR REQUIRED) | |
include_directories(${MPFR_INCLUDES}) | |
if(NOT MPFR_FOUND) | |
message(FATAL_ERROR "Could not find MPFR!") | |
endif(NOT MPFR_FOUND) | |
find_package(Boost 1.65.0) | |
if(Boost_FOUND) | |
include_directories(${Boost_INCLUDE_DIRS}) | |
endif() | |
set(Boost_USE_STATIC_LIBS ON) # only find static libs | |
set(Boost_USE_MULTITHREADED ON) | |
set(Boost_USE_STATIC_RUNTIME ON) | |
add_executable (hex_sums hex_sums.cpp) | |
target_link_libraries(hex_sums primesieve::primesieve ${QUAD_FLOAT_LIBS} ${MPFR_LIBRARIES}) | |
#if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") | |
# set_target_properties(client PROPERTIES LINK_FLAGS "-o hexsum.js -s WASM=1 -s DEMANGLE_SUPPORT=1 --bind") | |
#set_target_properties(hex_sums PROPERTIES LINK_FLAGS "-o hexsum.js -s WASM=1 -O2 -std=c++11") | |
#set_target_properties(hex_sums_mod PROPERTIES LINK_FLAGS "-o hexsum.js -s WASM=1 -O2 -std=c++11") | |
#else () | |
#target_link_libraries(hex_sums) | |
#endif () | |
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
// | |
// cmake -DCMAKE_C_COMPILER=/usr/local/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/local/bin/g++-7 -DBUILD_EXAMPLES=ON .. | |
// | |
// using prime iterator to do prime hexagon calculations | |
// | |
#include <primesieve.hpp> | |
#include <iostream> | |
#if USE_QUAD_FLOAT | |
#include <boost/multiprecision/float128.hpp> | |
#endif | |
#include <boost/lexical_cast.hpp> | |
#include <boost/multiprecision/mpfr.hpp> | |
#include <boost/math/constants/constants.hpp> | |
namespace bmp = boost::multiprecision; | |
#include <chrono> | |
typedef std::chrono::high_resolution_clock Clock; | |
typedef uint64_t prime_value_t; | |
#include <string> | |
#include <cstdlib> | |
#include <cxxabi.h> | |
#include <map> | |
#include <iostream> | |
#include <csignal> | |
static const char my_version[] = "1.0.4"; | |
static const int kMagicHexValue = 6; | |
static const int kDefaultModNegativeValue = 5; | |
template<typename T> | |
std::string type_name() | |
{ | |
int status; | |
std::string tname = typeid(T).name(); | |
char *demangled_name = abi::__cxa_demangle(tname.c_str(), NULL, NULL, &status); | |
if(status == 0) { | |
tname = demangled_name; | |
std::free(demangled_name); | |
} | |
return tname; | |
} | |
#define HEXDEBUG(x) if (0) do x while(0) | |
// type is to hold a sum of prime fractions, which we are varying precision on | |
template <class TS, class TV=uint64_t> // template class sum (TS) and template class value (TV) | |
class prime_result_t { | |
public: | |
TV start_, end_, cur_num_; | |
int32_t start_sign_; | |
TS start_int_sum_, start_prime_sum_; | |
TS neg_int_sum_, pos_int_sum_; | |
TS neg_prime_sum_, pos_prime_sum_; | |
TS sum_exponent_; | |
TV mod_negative_value_; | |
prime_result_t( TV start, TV end, int32_t start_sign, TS sum_exponent, TV mod_neg_val): | |
start_(start), end_(end), cur_num_(0),start_sign_(start_sign), | |
start_int_sum_(0), start_prime_sum_(0), sum_exponent_(sum_exponent), | |
neg_int_sum_(0), pos_int_sum_(0), neg_prime_sum_(0), pos_prime_sum_(0), | |
mod_negative_value_(mod_neg_val) | |
{ | |
instance_ = this; | |
init_sums(); | |
}; | |
prime_result_t( TV end, TS sum_exponent, TV mod_neg_val): | |
start_(4), end_(end), cur_num_(0),start_sign_(1), | |
start_int_sum_(0), start_prime_sum_(0), sum_exponent_(sum_exponent), | |
neg_int_sum_(0), pos_int_sum_(0), neg_prime_sum_(0), pos_prime_sum_(0), | |
mod_negative_value_(mod_neg_val) | |
{ | |
instance_ = this; | |
init_sums(); | |
}; | |
void init_sums() { | |
const TS one = 1, | |
two = 2, | |
three = 3 , | |
four = 4; | |
const TS exp = sum_exponent_; | |
start_int_sum_ = one + pow(one/two, exp) + pow(one/three, exp) + pow(one/four, exp); | |
start_prime_sum_ = pow(one/two, exp) + pow(one/three, exp); | |
} | |
const void report_computation() | |
{ | |
const TS total_int_sum = start_int_sum_ + pos_int_sum_ - neg_int_sum_; | |
const TS total_prime_sum = start_prime_sum_ + pos_prime_sum_ - neg_prime_sum_; | |
const TS total_ratio = total_int_sum / total_prime_sum; | |
//std::cout.precision(std::numeric_limits<T>::max_digits10); | |
std::cout.precision(50); | |
long precision = std::numeric_limits<TS>::digits10; | |
long bytes = sizeof(TS); | |
// dynamic types have zero here. so ask it... | |
if (precision == 0) { | |
long bits = mpfr_get_default_prec(); | |
long digits = bmp::detail::digits2_2_10(bits); | |
precision = digits; | |
bytes = mpfr_custom_get_size(bits); | |
} | |
// type_name<TS>() | |
std::cout << "Sum Range primes " << "(" << start_ << "-" << end_ << ", @" << cur_num_ << ")" | |
<< " with sum_exponent= " << sum_exponent_ << std::endl | |
<< " with mod_negative_value= " << mod_negative_value_ << std::endl | |
<< " using floating point with " << precision << " digits" | |
<< " and " << bytes << " bytes" << std::endl | |
<< "Net ∑ Integers: " << total_int_sum << std::endl | |
<< "Net ∑ Primes : " << total_prime_sum << std::endl | |
<< "Ratio : " << total_ratio << std::endl | |
<< "Neg ∑ Ints : " << neg_int_sum_ << std::endl | |
<< "Pos ∑ Ints : " << (start_int_sum_ + pos_int_sum_) << std::endl | |
<< "Delta ∑ Ints : " << (start_int_sum_ + pos_int_sum_ - neg_int_sum_) << std::endl | |
<< "Pos ∑/Neg ∑ : " << (start_int_sum_ + pos_int_sum_)/(neg_int_sum_) << std::endl | |
<< "Neg ∑ Prime : " << neg_prime_sum_ << std::endl | |
<< "Pos ∑ Prime : " << (start_prime_sum_ + pos_prime_sum_) << std::endl | |
<< "Delta ∑ Prime : " << (start_prime_sum_ + pos_prime_sum_ - neg_prime_sum_) << std::endl | |
<< "Pos ∑/Neg ∑ : " << (start_prime_sum_ + pos_prime_sum_)/(neg_prime_sum_) << std::endl; | |
} | |
void sig_handler(int signum) { | |
std::cout << "Instance signal called for (" << signum << "). \n"; | |
report_computation(); | |
} | |
// static void static_sig_handler(int signum) { | |
// std::cout << "Static signal handler called for(" << signum << "). \n"; | |
// instance_->sig_handler(signum); | |
// } | |
prime_result_t<TS,TV> *instance_; | |
}; | |
template <class T> int compute_prime_sums(uint64_t prime_start, uint64_t prime_end, int32_t start_sign, prime_result_t<T>& res ); | |
typedef double my_double; | |
#ifdef USE_QUAD_FLOAT | |
typedef bmp::number<bmp::arithmetic_backend<bmp::float128>, bmp::et_off> my_quad; | |
typedef bmp::float128 my_float128; | |
#endif | |
typedef bmp::number<bmp::mpfr_float_backend<64, bmp::allocate_stack> > my_f64; | |
typedef bmp::number<bmp::mpfr_float_backend<128, bmp::allocate_stack> > my_f128; | |
typedef bmp::number<bmp::mpfr_float_backend<256, bmp::allocate_stack> > my_f256; | |
typedef bmp::number<bmp::mpfr_float_backend<512, bmp::allocate_stack> > my_f512; | |
typedef bmp::number<bmp::mpfr_float_backend<1024, bmp::allocate_stack> > my_f1024; | |
typedef bmp::mpfr_float my_f_any; | |
template<typename T> void my_signal_wrapper(int signum) {}; | |
// Wrapper function uses a global to remember the object: | |
prime_result_t<double>* res_double_ptr = NULL; | |
template<> void my_signal_wrapper<double>(int signum) | |
{ | |
if (res_double_ptr) { res_double_ptr->sig_handler(signum); } | |
} | |
#ifdef USE_QUAD_FLOAT | |
prime_result_t<my_float128>* res_float128_ptr = NULL; | |
template<> void my_signal_wrapper<my_float128>(int signum) | |
{ | |
if (res_float128_ptr) { res_float128_ptr->sig_handler(signum); } | |
} | |
#endif | |
prime_result_t<my_f64>* res_f64_ptr = NULL; | |
template<> void my_signal_wrapper<my_f64>(int signum) | |
{ | |
if (res_f64_ptr) { res_f64_ptr->sig_handler(signum); } | |
} | |
prime_result_t<my_f128>* res_f128_ptr = NULL; | |
template<> void my_signal_wrapper<my_f128>(int signum) | |
{ | |
if (res_f128_ptr) { res_f128_ptr->sig_handler(signum); } | |
} | |
prime_result_t<my_f256>* res_f256_ptr = NULL; | |
template<> void my_signal_wrapper<my_f256>(int signum) | |
{ | |
if (res_f256_ptr) { res_f256_ptr->sig_handler(signum); } | |
} | |
prime_result_t<my_f512>* res_f512_ptr = NULL; | |
template<> void my_signal_wrapper<my_f512>(int signum) | |
{ | |
if (res_f512_ptr) { res_f512_ptr->sig_handler(signum); } | |
} | |
prime_result_t<my_f1024>* res_f1024_ptr = NULL; | |
template<> void my_signal_wrapper<my_f1024>(int signum) | |
{ | |
if (res_f1024_ptr) { res_f1024_ptr->sig_handler(signum); } | |
} | |
prime_result_t<my_f_any>* res_f_any_ptr = NULL; | |
template<> void my_signal_wrapper<my_f_any>(int signum) | |
{ | |
if (res_f_any_ptr) { res_f_any_ptr->sig_handler(signum); } | |
} | |
template <typename T> | |
void time_one_sum(prime_result_t<T> &res) | |
{ | |
auto t1 = Clock::now(); | |
compute_prime_sums( res.start_, res.end_, res.start_sign_, res.sum_exponent_, res.mod_negative_value_, res ); | |
auto t2 = Clock::now(); | |
res.report_computation(); | |
std::cout << " (computed in " | |
<< std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() | |
<< " ms)" << std::endl; | |
} | |
// | |
// compute special sums of primes | |
// | |
template <class T> | |
int compute_prime_sums(const uint64_t prime_start, const uint64_t prime_end, | |
const int32_t start_sign, const T sum_exponent, const int32_t mod_neg_target, | |
prime_result_t<T>& res ) { | |
primesieve::iterator it(prime_start); // Generate primes > start | |
bool positive = (start_sign > 0); | |
T neg_int_sum = 0.0, | |
pos_int_sum = 0.0, | |
*int_sum_ptr; | |
T neg_prime_sum = 0.0, | |
pos_prime_sum = 0.0, | |
*prime_sum_ptr; | |
prime_value_t cur_prime, next_prime; | |
prime_value_t ii = 0; | |
prime_value_t start = it.next_prime(); | |
HEXDEBUG( std::cout << "start_prime = " << prime_start | |
<< ", start=" << start | |
<< ", end=" << prime_end << std::endl; ); | |
// iterate over the primes | |
for (cur_prime = start, next_prime = it.next_prime(); next_prime < prime_end; next_prime = it.next_prime()) { | |
HEXDEBUG( std::cout << "cur_prime = " << cur_prime << std::endl; ); | |
if (mod_neg_target < 0) { | |
// swap sign of summing every prime | |
positive = !positive; | |
} else { | |
// set sign of summing based on modular math of the current prime | |
int mod_val = cur_prime % kMagicHexValue; | |
if (mod_val == mod_neg_target) { | |
positive = 0; | |
} else { | |
positive = 1; | |
} | |
} | |
prime_sum_ptr = (positive ? &res.pos_prime_sum_ : &res.neg_prime_sum_); | |
{ | |
T v1 = (T)1/(T)cur_prime; | |
T v2 = pow(v1, sum_exponent); | |
*prime_sum_ptr += v2; | |
} | |
//res.report_computation(); | |
int_sum_ptr = (positive ? &res.pos_int_sum_ : &res.neg_int_sum_); | |
// iterate over ints from current prime to next prime | |
for (ii = cur_prime; ii < next_prime; ++ii) { | |
res.cur_num_ = ii; | |
T v1 = (T)1/(T)ii; | |
T v2 = pow(v1, sum_exponent); | |
*int_sum_ptr += v2; | |
HEXDEBUG( std::cout << "cur_int = " << ii << std::endl; ); | |
//res.report_computation(); | |
} | |
// save prime for next loop | |
cur_prime = next_prime; | |
} | |
// these values are computed and stored in the loops above... | |
//res.neg_int_sum_ = neg_int_sum; | |
//res.pos_int_sum_ = pos_int_sum; | |
//res.neg_prime_sum_ = neg_prime_sum; | |
//res.pos_prime_sum_ = pos_prime_sum; | |
return 0; | |
} | |
std::map<std::string, my_f_any> float_const_map; | |
void usage(char** argv, std::string message){ | |
if (message.length() > 0) { | |
std::cerr << message << std::endl; | |
} | |
std::cerr << "usage: " << argv[0] << " prime_range_power_of_10 sum_exponent float_digits mod_negative_value" << std::endl; | |
std::cerr << " version: " << my_version << std::endl; | |
std::cerr << " example: " << argv[0] << " 8 1.5 256 5" << std::endl; | |
std::cerr << std::endl; | |
std::cerr << " Sum integers from (1,10**PRIME_RANGE_POWER)" << std::endl; | |
std::cerr << std::endl; | |
std::cerr << " Any number of FLOAT_DIGITs precision is supported but optimized version are available for:" << std::endl; | |
std::cerr << " double: " | |
<< std::numeric_limits<double>::digits10 << " digits of precision" | |
<< " using " << sizeof(double) << " bytes" << std::endl; | |
#ifdef USE_QUAD_FLOAT | |
std::cerr << " quad-float: " | |
<< std::numeric_limits<my_float128>::digits10 << " digits of precision" | |
<< " using " << sizeof(my_float128) << " bytes" << std::endl; | |
#endif | |
std::cerr << " mpfr 64: " | |
<< std::numeric_limits<my_f64>::digits10 << " digits of precision" | |
<< " using " << sizeof(my_f64) << " bytes" << std::endl; | |
std::cerr << " mpfr 128: " | |
<< std::numeric_limits<my_f128>::digits10 << " digits of precision" | |
<< " using " << sizeof(my_f128) << " bytes" << std::endl; | |
std::cerr << " mpfr 256: " | |
<< std::numeric_limits<my_f256>::digits10 << " digits of precision" | |
<< " using " << sizeof(my_f256) << " bytes" << std::endl; | |
std::cerr << " mpfr 512: " | |
<< std::numeric_limits<my_f512>::digits10 << " digits of precision" | |
<< " using " << sizeof(my_f512) << " bytes" << std::endl; | |
std::cerr << " mpfr 1024: " | |
<< std::numeric_limits<my_f1024>::digits10 << " digits of precision" | |
<< " using " << sizeof(my_f1024) << " bytes" << std::endl; | |
std::cerr << std::endl; | |
std::cerr << " Known constants for SUM_EXPONENT are:" << std::endl; | |
for(auto ii = float_const_map.begin(); ii != float_const_map.end(); ++ii) { | |
std::cerr << " " << ii->first << " = " << ii->second << std::endl; | |
} | |
std::cerr << std::endl; | |
std::cerr << " Valid MOD_NEGATIVE_VALUE:" << std::endl; | |
std::cerr << " -1 = revert to switching sign on every prime;" << std::endl; | |
std::cerr << " 0-" << (kMagicHexValue-1) << ": if (prime % this value) is MOD_NEGATIVE_VALUE then sign is negative for sum, otherwise positive" << std::endl; | |
std::cerr << std::endl; | |
exit(1); | |
} | |
void build_map(std::map<std::string, my_f_any> & m) { | |
m["half"] = boost::math::constants::half<my_f_any>(); | |
m["third"] = boost::math::constants::third<my_f_any>(); | |
m["two_thirds"] = boost::math::constants::two_thirds<my_f_any>(); | |
m["three_quarters"] = boost::math::constants::three_quarters<my_f_any>(); | |
m["root_two"] = boost::math::constants::root_two<my_f_any>(); | |
m["root_three"] = boost::math::constants::root_three<my_f_any>(); | |
m["half_root_two"] = boost::math::constants::half_root_two<my_f_any>(); | |
m["ln_two"] = boost::math::constants::ln_two<my_f_any>(); | |
m["ln_ten"] = boost::math::constants::ln_ten<my_f_any>(); | |
m["ln_ln_two"] = boost::math::constants::ln_ln_two<my_f_any>(); | |
m["root_ln_four"] = boost::math::constants::root_ln_four<my_f_any>(); | |
m["one_div_root_two"] = boost::math::constants::one_div_root_two<my_f_any>(); | |
m["pi"] = boost::math::constants::pi<my_f_any>(); | |
m["half_pi"] = boost::math::constants::half_pi<my_f_any>(); | |
m["third_pi"] = boost::math::constants::third_pi<my_f_any>(); | |
m["sixth_pi"] = boost::math::constants::sixth_pi<my_f_any>(); | |
m["two_pi"] = boost::math::constants::two_pi<my_f_any>(); | |
m["two_thirds_pi"] = boost::math::constants::two_thirds_pi<my_f_any>(); | |
m["three_quarters_pi"] = boost::math::constants::three_quarters_pi<my_f_any>(); | |
m["four_thirds_pi"] = boost::math::constants::four_thirds_pi<my_f_any>(); | |
m["one_div_two_pi"] = boost::math::constants::one_div_two_pi<my_f_any>(); | |
m["root_pi"] = boost::math::constants::root_pi<my_f_any>(); | |
m["root_half_pi"] = boost::math::constants::root_half_pi<my_f_any>(); | |
m["root_two_pi"] = boost::math::constants::root_two_pi<my_f_any>(); | |
m["one_div_root_pi"] = boost::math::constants::one_div_root_pi<my_f_any>(); | |
m["one_div_root_two_pi"] = boost::math::constants::one_div_root_two_pi<my_f_any>(); | |
m["root_one_div_pi"] = boost::math::constants::root_one_div_pi<my_f_any>(); | |
m["pi_minus_three"] = boost::math::constants::pi_minus_three<my_f_any>(); | |
m["four_minus_pi"] = boost::math::constants::four_minus_pi<my_f_any>(); | |
m["pi_pow_e"] = boost::math::constants::pi_pow_e<my_f_any>(); | |
m["pi_sqr"] = boost::math::constants::pi_sqr<my_f_any>(); | |
m["pi_sqr_div_six"] = boost::math::constants::pi_sqr_div_six<my_f_any>(); | |
m["pi_cubed"] = boost::math::constants::pi_cubed<my_f_any>(); | |
m["cbrt_pi"] = boost::math::constants::cbrt_pi<my_f_any>(); | |
m["one_div_cbrt_pi"] = boost::math::constants::one_div_cbrt_pi<my_f_any>(); | |
m["e"] = boost::math::constants::e<my_f_any>(); | |
m["exp_minus_half"] = boost::math::constants::exp_minus_half<my_f_any>(); | |
m["e_pow_pi"] = boost::math::constants::e_pow_pi<my_f_any>(); | |
m["root_e"] = boost::math::constants::root_e<my_f_any>(); | |
m["log10_e"] = boost::math::constants::log10_e<my_f_any>(); | |
m["one_div_log10_e"] = boost::math::constants::one_div_log10_e<my_f_any>(); | |
m["degree"] = boost::math::constants::degree<my_f_any>(); | |
m["radian"] = boost::math::constants::radian<my_f_any>(); | |
m["sin_one"] = boost::math::constants::sin_one<my_f_any>(); | |
m["cos_one"] = boost::math::constants::cos_one<my_f_any>(); | |
m["sinh_one"] = boost::math::constants::sinh_one<my_f_any>(); | |
m["cosh_one"] = boost::math::constants::cosh_one<my_f_any>(); | |
m["phi"] = boost::math::constants::phi<my_f_any>(); | |
m["ln_phi"] = boost::math::constants::ln_phi<my_f_any>(); | |
m["one_div_ln_phi"] = boost::math::constants::one_div_ln_phi<my_f_any>(); | |
m["euler"] = boost::math::constants::euler<my_f_any>(); | |
m["one_div_euler"] = boost::math::constants::one_div_euler<my_f_any>(); | |
m["euler_sqr"] = boost::math::constants::euler_sqr<my_f_any>(); | |
m["zeta_two"] = boost::math::constants::zeta_two<my_f_any>(); | |
m["zeta_three"] = boost::math::constants::zeta_three<my_f_any>(); | |
m["catalan"] = boost::math::constants::catalan<my_f_any>(); | |
m["glaisher"] = boost::math::constants::glaisher<my_f_any>(); | |
#if 0 | |
// holy cow - this takes *forever* to run at runtime. you are not welcome, sir khinchin <cough> constant. | |
m["khinchin"] = boost::math::constants::khinchin<my_f_any>(); | |
#endif | |
m["extreme_value_skewness"] = boost::math::constants::extreme_value_skewness<my_f_any>(); | |
m["rayleigh_skewness"] = boost::math::constants::rayleigh_skewness<my_f_any>(); | |
m["rayleigh_kurtosis_excess"] = boost::math::constants::rayleigh_kurtosis_excess<my_f_any>(); | |
m["rayleigh_kurtosis"] = boost::math::constants::rayleigh_kurtosis<my_f_any>(); | |
// Tad's special | |
// sphere packing constant = pi/sqrt(18) == (pi/3)/sqrt(2); | |
m["sphere_packing"] = boost::math::constants::third_pi<my_f_any>()/(boost::math::constants::root_two<my_f_any>()); | |
m["one_over_phi"] = 1.0/boost::math::constants::phi<my_f_any>(); | |
} | |
template <class T> | |
T get_float_const_value(std::map<std::string, my_f_any> & m, std::string s){ | |
T val; | |
auto ii = m.find(s); | |
if (ii != m.end()) { | |
// we found a const name we recognize. | |
// assume this is going to succeed | |
val = boost::numeric_cast<T>(ii->second); | |
} else { | |
// we didn't recognize it as a named constant. So try to convert the string to an number | |
try { | |
val = boost::lexical_cast<T>(s); | |
} | |
catch(const boost::bad_lexical_cast &) { | |
std::cerr << "Could not convert " << s << " into a number" << std::endl; | |
exit(-1); | |
} | |
} | |
return val; | |
} | |
int main(int argc, char** argv) | |
{ | |
double max_prime_power = 10; | |
int float_digits = 128; | |
int mod_negative_value = 5; | |
std::string sum_exp_str; | |
build_map(float_const_map); | |
if (argc < 3) { | |
usage(argv, ""); | |
} | |
if (argc > 1) { | |
max_prime_power = std::atof(argv[1]); | |
if (isnan(max_prime_power)) { | |
usage(argv, "Could not convert power to a number"); | |
} | |
} | |
if (argc > 2) { | |
sum_exp_str = argv[2]; | |
//double sum_exponent = 1.0; | |
//sum_exponent = std::atof(argv[2]); | |
//if (isnan(sum_exponent)){ | |
// usage(argv, "Could not convert power to an floating point number"); | |
//} | |
} | |
if (argc > 3) { | |
float_digits = std::atoi(argv[3]); | |
if (float_digits == 0) { | |
usage(argv, "Could not convert FLOAT_DIGITS input to an int"); | |
} | |
} | |
if (argc > 4) { | |
mod_negative_value = std::atoi(argv[4]); | |
if (mod_negative_value > kMagicHexValue) { | |
usage(argv, "MOD_NEGATIVE_VALUE was too large. Should be -1 to disable or less than 6"); | |
} | |
} | |
const uint64_t nn = pow(10, max_prime_power); | |
long bits = bmp::detail::digits10_2_2((float_digits)); | |
//std::cout << "converting " << float_digits << " floating point digits to " << bits << " bits " << std::endl; | |
switch (float_digits) { | |
case std::numeric_limits<double>::digits10: | |
{ | |
std::cout << "using optimized double data type..." << std::endl; | |
my_f_any v = get_float_const_value<my_f_any>(float_const_map, sum_exp_str); | |
double sum_exp = static_cast<double>(v); | |
// std::atof(sum_exp_str.c_str()); | |
prime_result_t<double> res_double(nn, sum_exp, mod_negative_value); | |
res_double_ptr = &res_double; | |
signal(SIGINT, &my_signal_wrapper<double> ); | |
time_one_sum<double>(res_double); | |
} | |
break; | |
#ifdef USE_QUAD_FLOAT | |
case std::numeric_limits<my_float128>::digits10: | |
{ | |
my_float128 sum_exp = get_float_const_value<my_float128>(float_const_map, sum_exp_str); | |
//my_float128 sum_exp = static_cast<my_float128>(sum_exp_str); | |
prime_result_t<my_float128> res_float128(nn, sum_exp, mod_negative_value); | |
res_float128_ptr = &res_float128; | |
signal(SIGINT, &my_signal_wrapper<my_float128> ); | |
time_one_sum<my_float128>(float128); | |
} | |
break; | |
#endif | |
case std::numeric_limits<my_f256>::digits10: | |
{ | |
my_f256 sum_exp = get_float_const_value<my_f256>(float_const_map, sum_exp_str); | |
//my_f256 sum_exp = static_cast<my_f256>(sum_exp_str); | |
prime_result_t<my_f256> res_f256(nn, sum_exp, mod_negative_value); | |
res_f256_ptr = &res_f256; | |
signal(SIGINT, &my_signal_wrapper<my_f256> ); | |
time_one_sum<my_f256>(res_f256); | |
} | |
break; | |
case std::numeric_limits<my_f64>::digits10: | |
{ | |
my_f64 sum_exp = get_float_const_value<my_f64>(float_const_map, sum_exp_str); | |
//my_f64 sum_exp = static_cast<my_f64>(sum_exp_str); | |
prime_result_t<my_f64> res_f64(nn, sum_exp, mod_negative_value); | |
res_f64_ptr = &res_f64; | |
signal(SIGINT, &my_signal_wrapper<my_f64> ); | |
time_one_sum<my_f64>(res_f64); | |
} | |
break; | |
case std::numeric_limits<my_f128>::digits10: | |
{ | |
my_f128 sum_exp = get_float_const_value<my_f128>(float_const_map, sum_exp_str); | |
//my_f128 sum_exp = static_cast<my_f128>(sum_exp_str); | |
prime_result_t<my_f128> res_f128(nn, sum_exp, mod_negative_value); | |
res_f128_ptr = &res_f128; | |
signal(SIGINT, &my_signal_wrapper<my_f128> ); | |
time_one_sum<my_f128>(res_f128); | |
} | |
break; | |
case std::numeric_limits<my_f512>::digits10: | |
{ | |
my_f512 sum_exp = get_float_const_value<my_f512>(float_const_map, sum_exp_str); | |
prime_result_t<my_f512> res_f512(nn, sum_exp, mod_negative_value); | |
res_f512_ptr = &res_f512; | |
signal(SIGINT, &my_signal_wrapper<my_f512> ); | |
time_one_sum<my_f512>(res_f512); | |
} | |
break; | |
case std::numeric_limits<my_f1024>::digits10: | |
{ | |
my_f1024 sum_exp = get_float_const_value<my_f1024>(float_const_map, sum_exp_str); | |
prime_result_t<my_f1024> res_f1024(nn, sum_exp, mod_negative_value); | |
res_f1024_ptr = &res_f1024; | |
signal(SIGINT, &my_signal_wrapper<my_f1024> ); | |
time_one_sum<my_f1024>(res_f1024); | |
} | |
break; | |
default: | |
{ | |
my_f_any sum_exp = get_float_const_value<my_f_any>(float_const_map, sum_exp_str); | |
prime_result_t<my_f_any> res_f_any(nn, sum_exp, mod_negative_value); | |
mpfr_set_default_prec(bits); | |
bmp::mpfr_float::default_precision(float_digits); | |
res_f_any_ptr = &res_f_any; | |
signal(SIGINT, &my_signal_wrapper<my_f_any> ); | |
time_one_sum<my_f_any>(res_f_any); | |
} | |
break; | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment