Skip to content

Instantly share code, notes, and snippets.

@pstoll
Created February 3, 2019 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pstoll/9bf1b7f967b98985f845c493ef660d0a to your computer and use it in GitHub Desktop.
Save pstoll/9bf1b7f967b98985f845c493ef660d0a to your computer and use it in GitHub Desktop.
hex sum 1.0.4 source setup.

Installation

brew install cmake
brew install primesieve
brew install boost
brew install mpfr
cmake .
# 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)
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 ()
//
// 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