[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -42,7 +42,7 @@ if $(is_unix)
lib gsl ;
lib gslcblas ;
lib Rmath ;
obj has_libstdcxx_tr1 : has_libstdcxx_tr1.cpp ;
obj has_libstdcxx_tr1 : ../accuracy/has_libstdcxx_tr1.cpp ;
explicit has_libstdcxx_tr1 ;
obj has_c99_cmath : has_c99_cmath.cpp ;
explicit has_c99_cmath ;
@@ -104,7 +104,7 @@ rule all-tests {
result += [ run $(source) /boost/regex//boost_regex /boost/system /boost/chrono /boost/filesystem table_helper
: : : release <include>../../test
[ check-target-builds ../accuracy//has_c99_cmath : <define>TEST_C99 ]
[ check-target-builds ../accuracy//has_libstdcxx_tr1 : <define>TEST_LIBSTDCXX ]
[ check-target-builds has_libstdcxx_tr1 : <define>TEST_LIBSTDCXX ]
[ check-target-builds ../accuracy//has_gsl : <define>TEST_GSL <source>gsl <source>gslcblas ]
[ check-target-builds ../accuracy//has_rmath : <define>TEST_RMATH <source>Rmath ]
# [ check-target-builds is_intel_win : <build>no : ]

View File

@@ -0,0 +1,79 @@
// (C) Copyright Matt Borland 2021.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <vector>
#include <boost/math/tools/random_vector.hpp>
#include <boost/math/statistics/bivariate_statistics.hpp>
#include <benchmark/benchmark.h>
using boost::math::generate_random_vector;
template<typename T>
void seq_covariance(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> u = generate_random_vector<T>(size, seed);
std::vector<T> v = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::covariance(std::execution::seq, u, v));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void par_covariance(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> u = generate_random_vector<T>(size, seed);
std::vector<T> v = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::covariance(std::execution::par, u, v));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void seq_correlation(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> u = generate_random_vector<T>(size, seed);
std::vector<T> v = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::correlation_coefficient(std::execution::seq, u, v));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void par_correlation(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> u = generate_random_vector<T>(size, seed);
std::vector<T> v = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::correlation_coefficient(std::execution::par, u, v));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK_TEMPLATE(seq_covariance, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(par_covariance, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(seq_correlation, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(par_correlation, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_MAIN();

View File

@@ -0,0 +1,57 @@
#include <vector>
#include <random>
#include <benchmark/benchmark.h>
#include <boost/math/special_functions/chebyshev.hpp>
template<class Real>
void ChebyshevClenshaw(benchmark::State& state)
{
std::vector<Real> v(state.range(0));
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_real_distribution<Real> unif(-1,1);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = unif(mt);
}
using boost::math::chebyshev_clenshaw_recurrence;
Real x = unif(mt);
for (auto _ : state)
{
benchmark::DoNotOptimize(chebyshev_clenshaw_recurrence(v.data(), v.size(), x));
}
state.SetComplexityN(state.range(0));
}
template<class Real>
void TranslatedChebyshevClenshaw(benchmark::State& state)
{
std::vector<Real> v(state.range(0));
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_real_distribution<Real> unif(-1,1);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = unif(mt);
}
using boost::math::detail::unchecked_chebyshev_clenshaw_recurrence;
Real x = unif(mt);
Real a = -2;
Real b = 5;
for (auto _ : state)
{
benchmark::DoNotOptimize(unchecked_chebyshev_clenshaw_recurrence(v.data(), v.size(), a, b, x));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK_TEMPLATE(TranslatedChebyshevClenshaw, double)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity(benchmark::oN);
BENCHMARK_TEMPLATE(ChebyshevClenshaw, double)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity(benchmark::oN);
BENCHMARK_MAIN();

View File

@@ -0,0 +1,117 @@
// (C) Copyright Nick Thompson 2020.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <random>
#include <iostream>
#include <iomanip>
#include <benchmark/benchmark.h>
#include <boost/math/tools/cohen_acceleration.hpp>
#include <boost/multiprecision/float128.hpp>
#include <boost/multiprecision/mpfr.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/core/demangle.hpp>
using boost::multiprecision::number;
using boost::multiprecision::mpfr_float_backend;
using boost::multiprecision::float128;
using boost::multiprecision::cpp_bin_float_50;
using boost::multiprecision::cpp_bin_float_100;
using boost::math::tools::cohen_acceleration;
using boost::math::constants::pi;
template<typename Real>
class G {
public:
G(){
k_ = 0;
}
Real operator()() {
k_ += 1;
return 1/(k_*k_);
}
private:
Real k_;
};
template<class Real>
void CohenAcceleration(benchmark::State& state)
{
using std::abs;
Real x = pi<Real>()*pi<Real>()/12;
for (auto _ : state)
{
auto g = G<Real>();
x = cohen_acceleration(g);
benchmark::DoNotOptimize(x);
}
if (abs(x - pi<Real>()*pi<Real>()/12) > 16*std::numeric_limits<Real>::epsilon())
{
std::cerr << std::setprecision(std::numeric_limits<Real>::max_digits10);
std::cerr << "Cohen acceleration computed " << x << " on type " << boost::core::demangle(typeid(Real).name()) << "\n";
std::cerr << "But expected value is " << pi<Real>()*pi<Real>()/12 << "\n";
}
}
BENCHMARK_TEMPLATE(CohenAcceleration, float);
BENCHMARK_TEMPLATE(CohenAcceleration, double);
BENCHMARK_TEMPLATE(CohenAcceleration, long double);
BENCHMARK_TEMPLATE(CohenAcceleration, float128);
BENCHMARK_TEMPLATE(CohenAcceleration, cpp_bin_float_50);
BENCHMARK_TEMPLATE(CohenAcceleration, cpp_bin_float_100);
BENCHMARK_TEMPLATE(CohenAcceleration, number<mpfr_float_backend<100>>);
BENCHMARK_TEMPLATE(CohenAcceleration, number<mpfr_float_backend<200>>);
BENCHMARK_TEMPLATE(CohenAcceleration, number<mpfr_float_backend<300>>);
BENCHMARK_TEMPLATE(CohenAcceleration, number<mpfr_float_backend<400>>);
BENCHMARK_TEMPLATE(CohenAcceleration, number<mpfr_float_backend<1000>>);
template<class Real>
void NaiveSum(benchmark::State& state)
{
using std::abs;
Real x = pi<Real>()*pi<Real>()/12;
for (auto _ : state)
{
auto g = G<Real>();
Real term = g();
x = term;
bool even = false;
while (term > std::numeric_limits<Real>::epsilon()/2) {
term = g();
if (even) {
x += term;
even = false;
} else {
x -= term;
even = true;
}
}
benchmark::DoNotOptimize(x);
}
// The accuracy tests don't pass because the sum is ill-conditioned:
/*if (abs(x - pi<Real>()*pi<Real>()/12) > 16*std::numeric_limits<Real>::epsilon())
{
std::cerr << std::setprecision(std::numeric_limits<Real>::max_digits10);
std::cerr << "Cohen acceleration computed " << x << " on type " << boost::core::demangle(typeid(Real).name()) << "\n";
std::cerr << "But expected value is " << pi<Real>()*pi<Real>()/12 << "\n";
}*/
}
BENCHMARK_TEMPLATE(NaiveSum, float);
BENCHMARK_TEMPLATE(NaiveSum, double);
BENCHMARK_TEMPLATE(NaiveSum, long double);
BENCHMARK_TEMPLATE(NaiveSum, float128);
BENCHMARK_TEMPLATE(NaiveSum, cpp_bin_float_50);
BENCHMARK_TEMPLATE(NaiveSum, cpp_bin_float_100);
BENCHMARK_TEMPLATE(NaiveSum, number<mpfr_float_backend<100>>);
BENCHMARK_TEMPLATE(NaiveSum, number<mpfr_float_backend<200>>);
BENCHMARK_TEMPLATE(NaiveSum, number<mpfr_float_backend<300>>);
BENCHMARK_TEMPLATE(NaiveSum, number<mpfr_float_backend<400>>);
BENCHMARK_TEMPLATE(NaiveSum, number<mpfr_float_backend<1000>>);
BENCHMARK_MAIN();

View File

@@ -0,0 +1,186 @@
// (C) Copyright Nick Thompson 2020.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <benchmark/benchmark.h>
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/mpfr.hpp>
using namespace boost::math::constants;
using boost::multiprecision::mpfr_float;
void LaplaceLimit(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(laplace_limit<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(LaplaceLimit)->RangeMultiplier(2)->Range(128, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Dottie(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(dottie<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Dottie)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void ReciprocalFibonacci(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(reciprocal_fibonacci<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(ReciprocalFibonacci)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Pi(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(pi<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Pi)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Gauss(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(gauss<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Gauss)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Exp1(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(e<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Exp1)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Catalan(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(catalan<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Catalan)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Plastic(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(plastic<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Plastic)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void RootTwo(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(root_two<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(RootTwo)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void ZetaThree(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(zeta_three<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(ZetaThree)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Euler(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(euler<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Euler)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void LnTwo(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(ln_two<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(LnTwo)->RangeMultiplier(2)->Range(512, 1<<20)->Complexity()->Unit(benchmark::kMicrosecond);
void Glaisher(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(glaisher<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(Glaisher)->RangeMultiplier(2)->Range(512, 4096)->Complexity()->Unit(benchmark::kMicrosecond);
void Khinchin(benchmark::State& state)
{
mpfr_float::default_precision(state.range(0));
for (auto _ : state)
{
benchmark::DoNotOptimize(khinchin<mpfr_float>());
}
state.SetComplexityN(state.range(0));
}
// There is a performance bug in the Khinchin constant:
BENCHMARK(Khinchin)->RangeMultiplier(2)->Range(512, 512)->Complexity()->Unit(benchmark::kMicrosecond);
BENCHMARK_MAIN();

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
#include <boost/lexical_cast.hpp>
template <class T>
std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<16>&)
std::vector<T> const& fibonacci_numbers(const std::integral_constant<int, 16>&)
{
static const boost::uint16_t numbers[] = {
static_cast<boost::uint16_t>(21u),
@@ -38,7 +38,7 @@ std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<16>&)
}
template <class T>
std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<32>&)
std::vector<T> const& fibonacci_numbers(const std::integral_constant<int, 32>&)
{
static const boost::uint32_t numbers[] = {
21u,
@@ -88,7 +88,7 @@ std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<32>&)
}
template <class T>
std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<64>&)
std::vector<T> const& fibonacci_numbers(const std::integral_constant<int, 64>&)
{
static const boost::uint64_t numbers[] = {
21uLL,
@@ -184,7 +184,7 @@ std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<64>&)
}
template <class T>
std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<0>&)
std::vector<T> const& fibonacci_numbers(const std::integral_constant<int, 0>&)
{
static const T numbers[] = {
boost::lexical_cast<T>("21"),
@@ -1192,7 +1192,7 @@ std::vector<T> const& fibonacci_numbers(const boost::mpl::int_<0>&)
template <class T>
std::vector<std::pair<T, T> > const& fibonacci_numbers_permution_1()
{
typedef boost::mpl::int_<
typedef std::integral_constant<int,
((std::numeric_limits<T>::digits <= 16) ? 16 : ((std::numeric_limits<T>::digits <= 32) ? 32 : (std::numeric_limits<T>::digits <= 64) ? 64 : 0))
> tag_type;
@@ -1210,7 +1210,7 @@ std::vector<std::pair<T, T> > const& fibonacci_numbers_permution_1()
template <class T>
std::vector<std::pair<T, T> > const& fibonacci_numbers_permution_2()
{
typedef boost::mpl::int_<
typedef std::integral_constant<int,
((std::numeric_limits<T>::digits <= 16) ? 16 : ((std::numeric_limits<T>::digits <= 32) ? 32 : (std::numeric_limits<T>::digits <= 64) ? 64 : 0))
> tag_type;

View File

@@ -685,7 +685,7 @@ Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywor
Quickbook Usage: [role red Some red text]
*/
span.red { inline-block; color: red; }
span.red { display: inline-block; color: red; }
span.green { color: green; }
span.lime { color: #00FF00; }
span.blue { color: blue; }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
// (C) Copyright Nick Thompson 2020.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <random>
#include <benchmark/benchmark.h>
#include <boost/math/special_functions/jacobi_theta.hpp>
#include <boost/multiprecision/float128.hpp>
#include <boost/multiprecision/mpfr.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
using boost::multiprecision::number;
using boost::multiprecision::mpfr_float_backend;
using boost::multiprecision::float128;
using boost::multiprecision::cpp_bin_float_50;
using boost::multiprecision::cpp_bin_float_100;
using boost::math::jacobi_theta1;
using boost::math::jacobi_theta1tau;
template<class Real>
void JacobiTheta1(benchmark::State& state)
{
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_real_distribution<long double> unif(0,0.01);
Real x = static_cast<Real>(unif(mt));
Real q = static_cast<Real>(unif(mt));
for (auto _ : state)
{
benchmark::DoNotOptimize(jacobi_theta1(x, q));
x += std::numeric_limits<Real>::epsilon();
}
}
BENCHMARK_TEMPLATE(JacobiTheta1, float);
BENCHMARK_TEMPLATE(JacobiTheta1, double);
BENCHMARK_TEMPLATE(JacobiTheta1, long double);
BENCHMARK_TEMPLATE(JacobiTheta1, float128);
BENCHMARK_TEMPLATE(JacobiTheta1, number<mpfr_float_backend<100>>);
BENCHMARK_TEMPLATE(JacobiTheta1, number<mpfr_float_backend<200>>);
BENCHMARK_TEMPLATE(JacobiTheta1, number<mpfr_float_backend<300>>);
BENCHMARK_TEMPLATE(JacobiTheta1, number<mpfr_float_backend<400>>);
BENCHMARK_TEMPLATE(JacobiTheta1, number<mpfr_float_backend<1000>>);
BENCHMARK_TEMPLATE(JacobiTheta1, cpp_bin_float_50);
BENCHMARK_TEMPLATE(JacobiTheta1, cpp_bin_float_100);
template<class Real>
void JacobiTheta1Tau(benchmark::State& state)
{
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_real_distribution<long double> unif(0,0.01);
Real x = static_cast<Real>(unif(mt));
Real q = static_cast<Real>(unif(mt));
for (auto _ : state)
{
benchmark::DoNotOptimize(jacobi_theta1tau(x, q));
x += std::numeric_limits<Real>::epsilon();
}
}
BENCHMARK_TEMPLATE(JacobiTheta1Tau, float);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, double);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, long double);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, float128);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, number<mpfr_float_backend<100>>);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, number<mpfr_float_backend<200>>);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, number<mpfr_float_backend<300>>);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, number<mpfr_float_backend<400>>);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, number<mpfr_float_backend<1000>>);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, cpp_bin_float_50);
BENCHMARK_TEMPLATE(JacobiTheta1Tau, cpp_bin_float_100);
BENCHMARK_MAIN();

View File

@@ -10,6 +10,10 @@
#include <boost/array.hpp>
#include <boost/chrono.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <iomanip>
extern std::vector<std::vector<double> > data;
template <class Array>
void add_data(const Array& a)

View File

@@ -0,0 +1,47 @@
// (C) Copyright Nick Thompson 2020.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <random>
#include <benchmark/benchmark.h>
#include <boost/math/special_functions/rsqrt.hpp>
#include <boost/multiprecision/float128.hpp>
#include <boost/multiprecision/mpfr.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
using boost::multiprecision::number;
using boost::multiprecision::mpfr_float_backend;
using boost::multiprecision::float128;
using boost::multiprecision::cpp_bin_float_50;
using boost::multiprecision::cpp_bin_float_100;
using boost::math::rsqrt;
template<class Real>
void Rsqrt(benchmark::State& state)
{
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_real_distribution<long double> unif(1,100);
Real x = static_cast<Real>(unif(mt));
for (auto _ : state)
{
benchmark::DoNotOptimize(rsqrt(x));
x += std::numeric_limits<Real>::epsilon();
}
}
BENCHMARK_TEMPLATE(Rsqrt, float);
BENCHMARK_TEMPLATE(Rsqrt, double);
BENCHMARK_TEMPLATE(Rsqrt, long double);
BENCHMARK_TEMPLATE(Rsqrt, float128);
BENCHMARK_TEMPLATE(Rsqrt, number<mpfr_float_backend<100>>);
BENCHMARK_TEMPLATE(Rsqrt, number<mpfr_float_backend<200>>);
BENCHMARK_TEMPLATE(Rsqrt, number<mpfr_float_backend<300>>);
BENCHMARK_TEMPLATE(Rsqrt, number<mpfr_float_backend<400>>);
BENCHMARK_TEMPLATE(Rsqrt, number<mpfr_float_backend<1000>>);
BENCHMARK_TEMPLATE(Rsqrt, cpp_bin_float_50);
BENCHMARK_TEMPLATE(Rsqrt, cpp_bin_float_100);
BENCHMARK_MAIN();

View File

@@ -70,7 +70,7 @@ extern "C" {
extern void cdfnor(int*, double*, double*, double*, double*, double*, int*, double*);
extern void cdfpoi(int*, double*, double*, double*, double*, int*, double*);
extern void cdft(int*, double*, double*, double*, double*, int*, double*);
extern void cdftnc(int*, double*, double*, double*, double*, double*, int*, double*);
//extern void cdftnc(int*, double*, double*, double*, double*, double*, int*, double*);
}
inline double dcdflib_beta_cdf(double x, double a, double b)
@@ -272,7 +272,7 @@ inline double dcdflib_t_quantile(double p, double param)
cdft(&what, &p, &q, &x, &param, &status, &bound);
return x;
}
/*
inline double dcdflib_t_n_cdf(double x, double param, double nc)
{
int what = 1;
@@ -290,7 +290,7 @@ inline double dcdflib_t_n_quantile(double p, double param, double nc)
cdftnc(&what, &p, &q, &x, &param, &nc, &status, &bound);
return x;
}
*/
#endif
extern std::vector<std::vector<double> > data;

View File

@@ -0,0 +1,32 @@
// (C) Copyright Nick Thompson 2020.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <random>
#include <benchmark/benchmark.h>
#include <boost/math/tools/agm.hpp>
#include <boost/multiprecision/float128.hpp>
using boost::math::tools::agm;
template<class Real>
void AGM(benchmark::State& state)
{
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_real_distribution<long double> unif(1,100);
Real x = static_cast<Real>(unif(mt));
for (auto _ : state)
{
benchmark::DoNotOptimize(agm(x,Real(1)));
}
}
BENCHMARK_TEMPLATE(AGM, float);
BENCHMARK_TEMPLATE(AGM, double);
BENCHMARK_TEMPLATE(AGM, long double);
BENCHMARK_TEMPLATE(AGM, boost::multiprecision::float128);
BENCHMARK_MAIN();

View File

@@ -436,6 +436,16 @@ int main()
test_boost_2_param<boost::math::inverse_gaussian_distribution>(inverse_gaussian);
distribution_tester kolmogorov("KolmogorovSmirnov");
kolmogorov.add_test_case(3, one_param_quantile<boost::math::kolmogorov_smirnov_distribution<> >());
kolmogorov.add_test_case(20, one_param_quantile<boost::math::kolmogorov_smirnov_distribution<> >());
kolmogorov.add_test_case(200, one_param_quantile<boost::math::kolmogorov_smirnov_distribution<> >());
kolmogorov.add_test_case(2000, one_param_quantile<boost::math::kolmogorov_smirnov_distribution<> >());
kolmogorov.add_test_case(20000, one_param_quantile<boost::math::kolmogorov_smirnov_distribution<> >());
kolmogorov.add_test_case(200000, one_param_quantile<boost::math::kolmogorov_smirnov_distribution<> >());
test_boost_1_param<boost::math::kolmogorov_smirnov_distribution>(kolmogorov);
distribution_tester laplace("Laplace");
laplace.add_test_case(0, 1, two_param_quantile<boost::math::laplace_distribution<> >());
laplace.add_test_case(20, 20, two_param_quantile<boost::math::laplace_distribution<> >());
@@ -735,8 +745,8 @@ int main()
students_t.run_timed_tests([](const std::vector<double>& v, double x) { return dcdflib_t_cdf(x, v[0]); }, "CDF", "DCDFLIB");
students_t.run_timed_tests([](const std::vector<double>& v, double x) { return dcdflib_t_quantile(x, v[0]); }, "quantile", "DCDFLIB", true);
non_central_t.run_timed_tests([](const std::vector<double>& v, double x) { return dcdflib_t_n_cdf(x, v[0], v[1]); }, "CDF", "DCDFLIB");
non_central_t.run_timed_tests([](const std::vector<double>& v, double x) { return dcdflib_t_n_quantile(x, v[0], v[1]); }, "quantile", "DCDFLIB", true);
//non_central_t.run_timed_tests([](const std::vector<double>& v, double x) { return dcdflib_t_n_cdf(x, v[0], v[1]); }, "CDF", "DCDFLIB");
//non_central_t.run_timed_tests([](const std::vector<double>& v, double x) { return dcdflib_t_n_quantile(x, v[0], v[1]); }, "quantile", "DCDFLIB", true);
#endif
}

View File

@@ -7,7 +7,7 @@
# pragma warning (disable : 4224)
#endif
#include <boost/math/common_factor_rt.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/math/special_functions/prime.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/integer.hpp>
@@ -103,8 +103,8 @@ T get_prime_products()
template <class T>
T get_uniform_random()
{
static boost::random::uniform_int_distribution<T> minmax((std::numeric_limits<T>::min)(), (std::numeric_limits<T>::max)());
return minmax(rng);
static boost::random::uniform_int_distribution<T> minimax((std::numeric_limits<T>::min)(), (std::numeric_limits<T>::max)());
return minimax(rng);
}
template <class T>
@@ -172,7 +172,7 @@ T binary_textbook(T u, T v)
template <typename Integer>
inline BOOST_CXX14_CONSTEXPR Integer gcd_default(Integer a, Integer b) BOOST_GCD_NOEXCEPT(Integer)
{
using boost::math::gcd;
using boost::integer::gcd;
return gcd(a, b);
}
@@ -180,7 +180,7 @@ inline BOOST_CXX14_CONSTEXPR Integer gcd_default(Integer a, Integer b) BOOST_GCD
template <class T>
void test_type(const char* name)
{
using namespace boost::math::gcd_detail;
using namespace boost::integer::gcd_detail;
typedef T int_type;
std::vector<pair<int_type, int_type> > data;
@@ -373,13 +373,13 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
if(vp->size() <= 2)
{
if(vp->size() == 1)
*up = boost::math::gcd_detail::mixed_binary_gcd(*vp->limbs(), *up->limbs());
*up = boost::integer::gcd_detail::mixed_binary_gcd(*vp->limbs(), *up->limbs());
else
{
double_limb_type i, j;
i = vp->limbs()[0] | (static_cast<double_limb_type>(vp->limbs()[1]) << sizeof(limb_type) * CHAR_BIT);
j = (up->size() == 1) ? *up->limbs() : up->limbs()[0] | (static_cast<double_limb_type>(up->limbs()[1]) << sizeof(limb_type) * CHAR_BIT);
u = boost::math::gcd_detail::mixed_binary_gcd(i, j);
u = boost::integer::gcd_detail::mixed_binary_gcd(i, j);
}
break;
}

View File

@@ -0,0 +1,130 @@
// (C) Copyright Nick Thompson and Matt Borland 2020.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <random>
#include <boost/math/statistics/univariate_statistics.hpp>
#include <benchmark/benchmark.h>
template <class Z>
void test_mode(benchmark::State& state)
{
using boost::math::statistics::sorted_mode;
std::random_device rd;
std::mt19937_64 mt(rd());
std::uniform_int_distribution<> dist {1, 10};
auto gen = [&dist, &mt](){return dist(mt);};
std::vector<Z> v(state.range(0));
std::generate(v.begin(), v.end(), gen);
for (auto _ : state)
{
std::vector<Z> modes;
benchmark::DoNotOptimize(sorted_mode(v.begin(), v.end(), std::back_inserter(modes)));
}
state.SetComplexityN(state.range(0));
}
template <class Z>
void sequential_test_mode(benchmark::State& state)
{
using boost::math::statistics::sorted_mode;
std::vector<Z> v(state.range(0));
size_t current_num {1};
// produces {1, 2, 3, 4, 5...}
for(size_t i {}; i < v.size(); ++i)
{
v[i] = current_num;
++current_num;
}
for (auto _ : state)
{
std::vector<Z> modes;
benchmark::DoNotOptimize(sorted_mode(v, std::back_inserter(modes)));
}
state.SetComplexityN(state.range(0));
}
template <class Z>
void sequential_pairs_test_mode(benchmark::State& state)
{
using boost::math::statistics::sorted_mode;
std::vector<Z> v(state.range(0));
size_t current_num {1};
size_t current_num_counter {};
// produces {1, 1, 2, 2, 3, 3, ...}
for(size_t i {}; i < v.size(); ++i)
{
v[i] = current_num;
++current_num_counter;
if(current_num_counter > 2)
{
++current_num;
current_num_counter = 0;
}
}
for (auto _ : state)
{
std::vector<Z> modes;
benchmark::DoNotOptimize(sorted_mode(v, std::back_inserter(modes)));
}
state.SetComplexityN(state.range(0));
}
template <class Z>
void sequential_multiple_test_mode(benchmark::State& state)
{
using boost::math::statistics::sorted_mode;
std::vector<Z> v(state.range(0));
size_t current_num {1};
size_t current_num_counter {};
// produces {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...}
for(size_t i {}; i < v.size(); ++i)
{
v[i] = current_num;
++current_num_counter;
if(current_num_counter > current_num)
{
++current_num;
current_num_counter = 0;
}
}
for (auto _ : state)
{
std::vector<Z> modes;
benchmark::DoNotOptimize(sorted_mode(v, std::back_inserter(modes)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK_TEMPLATE(test_mode, int32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(test_mode, int64_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(test_mode, uint32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_test_mode, int32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_test_mode, int64_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_test_mode, uint32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_pairs_test_mode, int32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_pairs_test_mode, int64_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_pairs_test_mode, uint32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_multiple_test_mode, int32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_multiple_test_mode, int64_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_TEMPLATE(sequential_multiple_test_mode, uint32_t)->RangeMultiplier(2)->Range(1<<1, 1<<22)->Complexity();
BENCHMARK_MAIN();

View File

@@ -98,20 +98,20 @@ std::string make_order_string(int n)
return result;
}
void test_poly_1(const boost::mpl::int_<1>&)
void test_poly_1(const std::integral_constant<int, 1>&)
{
}
template <int N>
void test_poly_1(const boost::mpl::int_<N>&)
void test_poly_1(const std::integral_constant<int, N>&)
{
test_poly_1(boost::mpl::int_<N - 1>());
test_poly_1(std::integral_constant<int, N - 1>());
double time = exec_timed_test([](const std::vector<double>& v)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_polynomial_c_imp_1(denom, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_polynomial_c_imp_1(denom, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Double Coefficients)");
@@ -120,27 +120,27 @@ void test_poly_1(const boost::mpl::int_<N>&)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_polynomial_c_imp_1(denom_int, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_polynomial_c_imp_1(denom_int, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Integer Coefficients)");
}
void test_poly_2(const boost::mpl::int_<1>&)
void test_poly_2(const std::integral_constant<int, 1>&)
{
}
template <int N>
void test_poly_2(const boost::mpl::int_<N>&)
void test_poly_2(const std::integral_constant<int, N>&)
{
test_poly_2(boost::mpl::int_<N - 1>());
test_poly_2(std::integral_constant<int, N - 1>());
double time = exec_timed_test([](const std::vector<double>& v)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_polynomial_c_imp_2(denom, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_polynomial_c_imp_2(denom, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Double Coefficients)");
@@ -149,31 +149,31 @@ void test_poly_2(const boost::mpl::int_<N>&)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_polynomial_c_imp_2(denom_int, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_polynomial_c_imp_2(denom_int, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Integer Coefficients)");
}
void test_poly_3(const boost::mpl::int_<1>&)
void test_poly_3(const std::integral_constant<int, 1>&)
{
}
template <int N>
void test_poly_3(const boost::mpl::int_<N>&)
void test_poly_3(const std::integral_constant<int, N>&)
{
test_poly_3(boost::mpl::int_<N - 1>());
test_poly_3(std::integral_constant<int, N - 1>());
double time = exec_timed_test([](const std::vector<double>& v) { double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_polynomial_c_imp_3(denom, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_polynomial_c_imp_3(denom, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Double Coefficients)");
time = exec_timed_test([](const std::vector<double>& v) { double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_polynomial_c_imp_3(denom_int, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_polynomial_c_imp_3(denom_int, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Integer Coefficients)");
@@ -191,20 +191,20 @@ U evaluate_polynomial_0(const T* poly, U const& z, std::size_t count)
return sum;
}
void test_rat_1(const boost::mpl::int_<1>&)
void test_rat_1(const std::integral_constant<int, 1>&)
{
}
template <int N>
void test_rat_1(const boost::mpl::int_<N>&)
void test_rat_1(const std::integral_constant<int, N>&)
{
test_rat_1(boost::mpl::int_<N - 1>());
test_rat_1(std::integral_constant<int, N - 1>());
double time = exec_timed_test([](const std::vector<double>& v)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_rational_c_imp_1(num, denom, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_rational_c_imp_1(num, denom, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Double Coefficients)");
@@ -213,26 +213,26 @@ void test_rat_1(const boost::mpl::int_<N>&)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_rational_c_imp_1(num, denom_int, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_rational_c_imp_1(num, denom_int, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Integer Coefficients)");
}
void test_rat_2(const boost::mpl::int_<1>&)
void test_rat_2(const std::integral_constant<int, 1>&)
{
}
template <int N>
void test_rat_2(const boost::mpl::int_<N>&)
void test_rat_2(const std::integral_constant<int, N>&)
{
test_rat_2(boost::mpl::int_<N - 1>());
test_rat_2(std::integral_constant<int, N - 1>());
double time = exec_timed_test([](const std::vector<double>& v)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_rational_c_imp_2(num, denom, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_rational_c_imp_2(num, denom, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Double Coefficients)");
@@ -241,26 +241,26 @@ void test_rat_2(const boost::mpl::int_<N>&)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_rational_c_imp_2(num, denom_int, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_rational_c_imp_2(num, denom_int, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Integer Coefficients)");
}
void test_rat_3(const boost::mpl::int_<1>&)
void test_rat_3(const std::integral_constant<int, 1>&)
{
}
template <int N>
void test_rat_3(const boost::mpl::int_<N>&)
void test_rat_3(const std::integral_constant<int, N>&)
{
test_rat_3(boost::mpl::int_<N - 1>());
test_rat_3(std::integral_constant<int, N - 1>());
double time = exec_timed_test([](const std::vector<double>& v)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_rational_c_imp_3(num, denom, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_rational_c_imp_3(num, denom, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Double Coefficients)");
@@ -269,7 +269,7 @@ void test_rat_3(const boost::mpl::int_<N>&)
{
double result = 0;
for (unsigned i = 0; i < 10; ++i)
result += boost::math::tools::detail::evaluate_rational_c_imp_3(num, denom_int, v[0] + i, static_cast<boost::mpl::int_<N>*>(0));
result += boost::math::tools::detail::evaluate_rational_c_imp_3(num, denom_int, v[0] + i, static_cast<std::integral_constant<int, N>*>(0));
return result;
});
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Integer Coefficients)");
@@ -339,9 +339,9 @@ int main()
report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(i), "Method 0[br](Integer Coefficients)");
}
test_poly_1(boost::mpl::int_<20>());
test_poly_2(boost::mpl::int_<20>());
test_poly_3(boost::mpl::int_<20>());
test_poly_1(std::integral_constant<int, 20>());
test_poly_2(std::integral_constant<int, 20>());
test_poly_3(std::integral_constant<int, 20>());
for (unsigned i = 3; i <= 20; ++i)
{
@@ -362,9 +362,9 @@ int main()
report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(i), "Method 0[br](Integer Coefficients)");
}
test_rat_1(boost::mpl::int_<20>());
test_rat_2(boost::mpl::int_<20>());
test_rat_3(boost::mpl::int_<20>());
test_rat_1(std::integral_constant<int, 20>());
test_rat_2(std::integral_constant<int, 20>());
test_rat_3(std::integral_constant<int, 20>());
return 0;
}

View File

@@ -0,0 +1,424 @@
// Copyright 2020 Matt Borland
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/statistics/univariate_statistics.hpp>
#include <boost/assert.hpp>
#include <benchmark/benchmark.h>
#include <vector>
#include <algorithm>
#include <random>
#include <execution>
#include <iostream>
#include <iterator>
template<class T>
std::vector<T> generate_random_vector(std::size_t size, std::size_t seed)
{
if (seed == 0)
{
std::random_device rd;
seed = rd();
}
std::vector<T> v(size);
std::mt19937 gen(seed);
if constexpr (std::is_floating_point<T>::value)
{
std::normal_distribution<T> dis(0, 1);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = dis(gen);
}
return v;
}
else if constexpr (std::is_integral<T>::value)
{
// Rescaling by larger than 2 is UB!
std::uniform_int_distribution<T> dis(std::numeric_limits<T>::lowest()/2, (std::numeric_limits<T>::max)()/2);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = dis(gen);
}
return v;
}
else if constexpr (boost::is_complex<T>::value)
{
std::normal_distribution<typename T::value_type> dis(0, 1);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = {dis(gen), dis(gen)};
}
return v;
}
else if constexpr (boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_complex)
{
std::normal_distribution<long double> dis(0, 1);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = {dis(gen), dis(gen)};
}
return v;
}
else if constexpr (boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_floating_point)
{
std::normal_distribution<long double> dis(0, 1);
for (size_t i = 0; i < v.size(); ++i)
{
v[i] = dis(gen);
}
return v;
}
else
{
BOOST_ASSERT_MSG(false, "Could not identify type for random vector generation.");
return v;
}
}
template<typename T>
void mean(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::mean(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_mean(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::mean(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void variance(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::variance(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_variance(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::variance(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void skewness(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::skewness(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_skewness(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::skewness(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void first_four_moments(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::first_four_moments(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_first_four_moments(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::first_four_moments(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void kurtosis(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::kurtosis(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_kurtosis(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::kurtosis(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void median(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::median(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_median(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::median(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void median_absolute_deviation(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::median_absolute_deviation(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_median_absolute_deviation(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::median_absolute_deviation(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void gini_coefficient(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::gini_coefficient(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_gini_coefficient(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::gini_coefficient(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void interquartile_range(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::interquartile_range(std::execution::seq, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_interquartile_range(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::interquartile_range(std::execution::par, test_set));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void mode(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
std::vector<T> modes;
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::mode(std::execution::seq, test_set, std::back_inserter(modes)));
}
state.SetComplexityN(state.range(0));
}
template<typename T>
void parallel_mode(benchmark::State& state)
{
constexpr std::size_t seed {};
const std::size_t size = state.range(0);
std::vector<T> test_set = generate_random_vector<T>(size, seed);
std::vector<T> modes;
for(auto _ : state)
{
benchmark::DoNotOptimize(boost::math::statistics::mode(std::execution::par, test_set, std::back_inserter(modes)));
}
state.SetComplexityN(state.range(0));
}
// Mean
BENCHMARK_TEMPLATE(mean, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_mean, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(mean, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_mean, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Variance
BENCHMARK_TEMPLATE(variance, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_variance, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(variance, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_variance, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Skewness
BENCHMARK_TEMPLATE(skewness, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_skewness, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(skewness, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_skewness, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// First four moments
BENCHMARK_TEMPLATE(first_four_moments, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_first_four_moments, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(first_four_moments, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_first_four_moments, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Kurtosis
BENCHMARK_TEMPLATE(kurtosis, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_kurtosis, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(kurtosis, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_kurtosis, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Median
BENCHMARK_TEMPLATE(median, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_median, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(median, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_median, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Median absolute deviation
BENCHMARK_TEMPLATE(median_absolute_deviation, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_median_absolute_deviation, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(median_absolute_deviation, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_median_absolute_deviation, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Gini Coefficient
BENCHMARK_TEMPLATE(gini_coefficient, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_gini_coefficient, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(gini_coefficient, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_gini_coefficient, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Interquartile Range - Only floating point values implemented
BENCHMARK_TEMPLATE(interquartile_range, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_interquartile_range, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
// Mode
BENCHMARK_TEMPLATE(mode, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_mode, int)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(mode, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_TEMPLATE(parallel_mode, double)->RangeMultiplier(2)->Range(1 << 6, 1 << 20)->Complexity(benchmark::oN)->UseRealTime();
BENCHMARK_MAIN();