Skip to content

Commit

Permalink
Limits recursion for distribution, fixes benchmarks, and adds divisio…
Browse files Browse the repository at this point in the history
…n to benchmarks
  • Loading branch information
universenox committed Aug 13, 2019
1 parent 951e8c0 commit 9c90320
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 58 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -2,6 +2,8 @@
.vscode/
doc/html
*.cbp
test.cpp
a.out

#cmake products
cmake-build-debug/
Expand Down
8 changes: 6 additions & 2 deletions bench/include/benchmark_helpers.hpp
Expand Up @@ -10,7 +10,7 @@ struct bench_invalid_operation_exception : public std::exception {
}
};

constexpr void realOperationEq(boost::real::real& lhs, boost::real::real& rhs,
constexpr void realOperationEq(boost::real::real<>& lhs, boost::real::real<>& rhs,
boost::real::OPERATION op) {
switch (op) {
case boost::real::OPERATION::ADDITION:
Expand All @@ -22,13 +22,17 @@ constexpr void realOperationEq(boost::real::real& lhs, boost::real::real& rhs,
case boost::real::OPERATION::MULTIPLICATION:
lhs *= rhs;
break;
case boost::real::OPERATION::DIVISION:
lhs /= rhs;
break;
default:
throw bench_invalid_operation_exception();

}
}

enum class Comparison {GREATER_THAN, LESS_THAN, EQUALS};
constexpr bool realComp(boost::real::real& lhs,boost::real::real& rhs, Comparison comp) {
constexpr bool realComp(boost::real::real<>& lhs, boost::real::real<>& rhs, Comparison comp) {
switch (comp) {
case (Comparison::GREATER_THAN):
return lhs > rhs;
Expand Down
2 changes: 1 addition & 1 deletion bench/main-bench.cpp
Expand Up @@ -3,6 +3,6 @@

// ensure this is >= to MAX_NUM_DIGITS_XX for all benchmarks, else we will get
// a precision error and the benchmarks will not be meaningful.
std::optional<size_t> boost::real::const_precision_iterator::global_maximum_precision = 10000;
template<> std::optional<size_t> boost::real::const_precision_iterator<int>::global_maximum_precision = 10;

BENCHMARK_MAIN();
13 changes: 8 additions & 5 deletions bench/real_construction_bench.cpp
Expand Up @@ -13,12 +13,12 @@ const int MULTIPLIER_TC = 10; // for range evaluation of tree construction benc
/// MULTIPLIER_TC between MIN_TREE_NODES and MAX_TREE_NODES
void BM_RealOperationTreeConstruction(benchmark::State& state, boost::real::OPERATION op) {
for (auto i : state) {
boost::real::real a ("1234567891");
boost::real::real b ("9876532198");
boost::real::real<> a ("1234567891");
boost::real::real<> b ("9876532198");

// We keep the precision constant here because in constructing the *= tree, we would get way more digits
// than in +=, -= trees. This should make the benchmarks more meaningful
a.set_maximum_precision(10);
a.set_maximum_precision(2);

for (int i = 0; i < state.range(0); i++) {
realOperationEq(a,b,op);
Expand All @@ -29,7 +29,6 @@ void BM_RealOperationTreeConstruction(benchmark::State& state, boost::real::OPER
}

// these benchmark the operation tree constructors for each operation type.
/// @TODO: add division bench
BENCHMARK_CAPTURE(BM_RealOperationTreeConstruction, addition, boost::real::OPERATION(boost::real::OPERATION::ADDITION))
->RangeMultiplier(MULTIPLIER_TC)->Range(MIN_TREE_NODES ,MAX_TREE_NODES)->Unit(benchmark::kMillisecond)
->Complexity();
Expand All @@ -42,6 +41,10 @@ BENCHMARK_CAPTURE(BM_RealOperationTreeConstruction, multiplication, boost::real:
->RangeMultiplier(MULTIPLIER_TC)->Range(MIN_TREE_NODES ,MAX_TREE_NODES)->Unit(benchmark::kMillisecond)
->Complexity();

BENCHMARK_CAPTURE(BM_RealOperationTreeConstruction, division, boost::real::OPERATION(boost::real::OPERATION::DIVISION))
->RangeMultiplier(MULTIPLIER_TC)->Range(MIN_TREE_NODES ,MAX_TREE_NODES)->Unit(benchmark::kMillisecond)
->Complexity();

const int MIN_NUM_DIGITS_EC = 10;
const int MAX_NUM_DIGITS_EC = 10000;
const int MULTIPLIER_EC = 10; // for range evaluation of explicit construction benchmarks
Expand All @@ -57,7 +60,7 @@ void BM_RealExplicitConstruction_String(benchmark::State& state) {
}
state.ResumeTiming();

boost::real::real a(number);
boost::real::real<> a(number);
state.SetComplexityN(state.range(0));
}
}
Expand Down
27 changes: 16 additions & 11 deletions bench/real_op_evaluation_bench.cpp
Expand Up @@ -9,8 +9,8 @@ const int MULTIPLIER_TE = 10; // for range evaluation of tree evaluation benchm
/// MULTIPLIER_TE between MIN_TREE_NODES and MAX_TREE_NODES
void BM_RealOperationTreeEvaluation(benchmark::State& state, boost::real::OPERATION op) {
for (auto i : state) {
boost::real::real a ("12");
boost::real::real b ("34");
boost::real::real<> a ("12");
boost::real::real<> b ("34");

state.PauseTiming();
for (int i = 0; i < state.range(0); i++) {
Expand All @@ -23,7 +23,6 @@ void BM_RealOperationTreeEvaluation(benchmark::State& state, boost::real::OPERAT
}
}

/// @TODO: add division.
BENCHMARK_CAPTURE(BM_RealOperationTreeEvaluation, addition, boost::real::OPERATION(boost::real::OPERATION::ADDITION))
->RangeMultiplier(MULTIPLIER_TE)->Range(MIN_TREE_NODES ,MAX_TREE_NODES)->Unit(benchmark::kMillisecond)
->Complexity();
Expand All @@ -36,10 +35,14 @@ BENCHMARK_CAPTURE(BM_RealOperationTreeEvaluation, multiplication, boost::real::O
->RangeMultiplier(MULTIPLIER_TE)->Range(MIN_TREE_NODES ,MAX_TREE_NODES)->Unit(benchmark::kMillisecond)
->Complexity();

BENCHMARK_CAPTURE(BM_RealOperationTreeEvaluation, division, boost::real::OPERATION(boost::real::OPERATION::DIVISION))
->RangeMultiplier(MULTIPLIER_TE)->Range(MIN_TREE_NODES ,MAX_TREE_NODES)->Unit(benchmark::kMillisecond)
->Complexity();


const int MIN_NUM_DIGITS = 1000;
const int MAX_NUM_DIGITS = 10000;
const int MULTIPLIER_OE = 6;
const int MIN_NUM_DIGITS = 1;
const int MAX_NUM_DIGITS = 100 ;
const int MULTIPLIER_OE = 10;

/// benchmarks a op= b, where a, b, have n digits, where n is the set of powers of
/// MULTIPLIER_OE, between MIN_NUM_DIGITS and MAX_NUM_DIGITS
Expand All @@ -50,13 +53,13 @@ void BM_RealOperationEvaluation(benchmark::State& state, boost::real::OPERATION
for (int i = 0; i < state.range(0); i++) {
tmp.push_back('2');
}
boost::real::real a(tmp);
boost::real::real<> a(tmp);

tmp.clear();
for (int i = 0; i < state.range(0); i++) {
tmp.push_back('3');
}
boost::real::real b(tmp);
boost::real::real<> b(tmp);
realOperationEq(a,b,op);
state.ResumeTiming();

Expand All @@ -65,7 +68,6 @@ void BM_RealOperationEvaluation(benchmark::State& state, boost::real::OPERATION
}
}

///@TODO: add division
// The BM_RealOperationEvaluation operations are much faster, so these use nanoseconds in the result.
BENCHMARK_CAPTURE(BM_RealOperationEvaluation, addition, boost::real::OPERATION(boost::real::OPERATION::ADDITION))
->RangeMultiplier(MULTIPLIER_OE)->Range(MIN_NUM_DIGITS,MAX_NUM_DIGITS)
Expand All @@ -79,6 +81,9 @@ BENCHMARK_CAPTURE(BM_RealOperationEvaluation, multiplication, boost::real::OPERA
->RangeMultiplier(MULTIPLIER_OE)->Range(MIN_NUM_DIGITS,MAX_NUM_DIGITS)
->Complexity();

BENCHMARK_CAPTURE(BM_RealOperationEvaluation, division, boost::real::OPERATION(boost::real::OPERATION::DIVISION))
->RangeMultiplier(MULTIPLIER_OE)->Range(MIN_NUM_DIGITS,MAX_NUM_DIGITS)
->Complexity();

/// benchmarks operator> operator< and operator== for numbers a, b, where a == b, with n digits
void BM_RealComparisonEvaluation(benchmark::State& state, Comparison comp) {
Expand All @@ -88,8 +93,8 @@ void BM_RealComparisonEvaluation(benchmark::State& state, Comparison comp) {
for (int i = 0; i < state.range(0); i++) { // we compare 111...1 and 111..1
tmp.push_back('1');
}
boost::real::real a(tmp);
boost::real::real b(tmp);
boost::real::real<> a(tmp);
boost::real::real<> b(tmp);

state.ResumeTiming();

Expand Down
34 changes: 18 additions & 16 deletions include/real/exact_number.hpp
Expand Up @@ -17,7 +17,9 @@ namespace boost {
struct exact_number {
using exponent_t = int;

static const int BASE = 10;
// TODO: replace all redundant declarations of base with this
// static const T BASE = ;

std::vector<T> digits = {};
exponent_t exponent = 0;
bool positive = true;
Expand Down Expand Up @@ -389,7 +391,7 @@ namespace boost {

// ensuring that assignment from -1 * (maximum_precision) to exponent will not
// overflow
if (maximum_precision > std::abs(std::numeric_limits<exponent_t>::min())) {
if (maximum_precision > (unsigned int) std::abs(std::numeric_limits<exponent_t>::min())) {
throw exponent_overflow_exception();
}

Expand Down Expand Up @@ -615,20 +617,21 @@ namespace boost {
exact_number<T>(std::vector<T> vec, bool pos = true) : digits(vec), exponent(vec.size()), positive(pos) {};

/// ctor from any integral type
template<typename I, typename std::enable_if_t<std::is_integral<I>::value>>
exact_number(I x) {
if (x < 0)
positive = false;
else
positive = true;
/// @TODO: use whichever base.
// template<typename I, typename std::enable_if_t<std::is_integral<I>::value>>
// exact_number(I x) {
// if (x < 0)
// positive = false;
// else
// positive = true;

exponent = 0;
while (((x % BASE) != 0) || (x != 0)) {
exponent++;
push_front(std::abs(x%BASE));
x /= BASE;
}
}
// exponent = 0;
// while (((x % BASE) != 0) || (x != 0)) {
// exponent++;
// push_front(std::abs(x%BASE));
// x /= BASE;
// }
// }

// returns {integer_part, decimal_part, exponent, is_positive}
constexpr static std::tuple<std::string_view, std::string_view, exponent_t, bool> number_from_string(std::string_view number) {
Expand All @@ -639,7 +642,6 @@ namespace boost {
bool exp_positive = true;
bool positive = true;

bool on_integer = false;
bool has_exponent = false;
bool has_decimal = false;
bool has_sign = false;
Expand Down

0 comments on commit 9c90320

Please sign in to comment.