Skip to content

Commit

Permalink
Add and edit documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
universenox committed Aug 15, 2019
1 parent 1ec4742 commit 3757c61
Show file tree
Hide file tree
Showing 15 changed files with 541 additions and 452 deletions.
218 changes: 52 additions & 166 deletions README.md

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions bench/main-bench.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#include <benchmark/benchmark.h>
#include <real/real.hpp>

// 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.
template<> std::optional<size_t> boost::real::const_precision_iterator<int>::global_maximum_precision = 10;

BENCHMARK_MAIN();
4 changes: 3 additions & 1 deletion bench/real_construction_bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void BM_RealOperationTreeConstruction(benchmark::State& state, boost::real::OPER

// 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(2);
boost::real::real<>::set_global_maximum_precision(10);

for (int i = 0; i < state.range(0); i++) {
realOperationEq(a,b,op);
Expand Down Expand Up @@ -55,6 +55,8 @@ void BM_RealExplicitConstruction_String(benchmark::State& state) {
state.PauseTiming(); // construct a string representing a number of n digits
std::string number;

boost::real::real<>::set_global_maximum_precision(state.range(0)); // provide enough precision to not throw precision exception

for (int i = 0; i < state.range(0); i++) {
number.push_back('1');
}
Expand Down
12 changes: 9 additions & 3 deletions bench/real_op_evaluation_bench.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <benchmark/benchmark.h>
#include <benchmark_helpers.hpp>

const int MIN_TREE_NODES = 10;
const int MIN_TREE_NODES = 10;
const int MAX_TREE_NODES = 10000;
const int MULTIPLIER_TE = 10; // for range evaluation of tree evaluation benchmarks

Expand Down Expand Up @@ -44,11 +44,14 @@ 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
/// 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
void BM_RealOperationEvaluation(benchmark::State& state, boost::real::OPERATION op) {
for (auto i : state) {
state.PauseTiming(); // construct a, b
// keep precision at a constant so multiplication isn't significantly
// more precise than addition, to make the comparison fair
boost::real::real<>::set_global_maximum_precision(10);
std::string tmp;
for (int i = 0; i < state.range(0); i++) {
tmp.push_back('2');
Expand Down Expand Up @@ -90,12 +93,15 @@ void BM_RealComparisonEvaluation(benchmark::State& state, Comparison comp) {
for (auto i : state) {
state.PauseTiming(); // construct a, b
std::string tmp;

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);

// to avoid precision exception being thrown
boost::real::real<>::set_global_maximum_precision(tmp.size());
state.ResumeTiming();

bool boo = realComp(a,b,comp); // evaluation
Expand All @@ -113,4 +119,4 @@ BENCHMARK_CAPTURE(BM_RealComparisonEvaluation, GREATER_THAN, Comparison::GREATER

BENCHMARK_CAPTURE(BM_RealComparisonEvaluation, EQUALS, Comparison::EQUALS)
->RangeMultiplier(MULTIPLIER_OE)->Range(MIN_NUM_DIGITS,MAX_NUM_DIGITS)->Unit(benchmark::kMillisecond)
->Complexity();
->Complexity();
2 changes: 1 addition & 1 deletion doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PROJECT_NUMBER = 1.0.0
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF = "Boost.Real numerical data type for real numbers representation using range arithmetic."
PROJECT_BRIEF = "Real number representation using interval arithmetic."

# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
Expand Down
62 changes: 36 additions & 26 deletions include/real/const_precision_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,46 +16,42 @@

namespace boost {
namespace real{
/**
* @file The const_precision_iterator provides the functionality to iterate through precision intervals
* of all three kinds of reals
*
* @note variant and visit/visitors are used extensively in this implementation
* @TODO: consider doing traversals to lower the demands of recursion
* @sa documention on std::variant, std::visit
*/
// used in visitors
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

// fwd decl
template <typename T>
class real;

/// a real_number is a variant of the three main underlying types @ref real.hpp
template <typename T>
using real_number = std::variant<std::monostate, real_explicit<T>, real_algorithm<T>, real_operation<T>>;
using precision_t = size_t;

/// the default max precision to use if the user hasn't provided one.
const precision_t DEFAULT_MAXIMUM_PRECISION = 10;

/**
* The const_precision_iterator provides the functionality to iterate through precision intervals
* of all three kinds of reals
*
* @todo consider doing traversals to lower the demands of recursion
* @sa documention on std::variant, std::visit
* @todo some precision stuff is currently undefined behavior, i.e., operations between numbers
* with different precisions.
*/
template <typename T>
class const_precision_iterator {
public:
/**
* @brief Optional user-provided maximum precision for all const_precision_iterators.
*/

inline static std::optional<precision_t> global_maximum_precision;
/// @TODO look into STL-style iterators
/// @todo look into STL-style iterators
// typedef std::forward_iterator_tag iterator_category;
// typedef void difference_type (?);
// typedef ??? value_type
// typedef const value_type& reference (?) not necessary because const
// typedef const value_type* pointer

private:
/**
* @brief this holds a ptr to explicit number, algorithmic number, or real_operation
*/
*/
// raw pointer here is ok, precision iterator is always attached to the variant it points to
// (refer to real_data.hpp). Any time the variant is destroyed, so is this pointer.
real_number<T> * _real_ptr;
Expand All @@ -66,11 +62,19 @@ namespace boost {
/// local max precision, is used if set to > 0 by user
precision_t _maximum_precision = 0;

/**
* @brief Optional user-provided maximum precision for all const_precision_iterators.
*/
static inline std::optional<precision_t> global_maximum_precision;

/**
* @brief Contains the lower and upper bounds of the underlying real number, for precision = @ref _precision.
*/
interval<T> _approximation_interval;

void check_and_swap_boundaries() {
std::visit( overloaded { // perform operation on whatever is held in variant
[this] (real_explicit<T>& real) {
[this] (real_explicit<T>& real) {
if (!real.positive()) {
this->_approximation_interval.swap_bounds();
}
Expand Down Expand Up @@ -99,21 +103,27 @@ namespace boost {
*
* @details The user may set the maximum precision for any specific precision iterator.
* They may also set a general maximum precision (the static optional value).
* Preference is given: _maximum_precision > maximum_precision > DEFAULT_MAXIMUM_PRECISION
* Preference is given: _maximum_precision > global_maximum_precision > DEFAULT_MAXIMUM_PRECISION
*/
precision_t maximum_precision() const {
if((_maximum_precision == 0) && !(global_maximum_precision))
if((_maximum_precision == 0) && !(const_precision_iterator::global_maximum_precision))
return DEFAULT_MAXIMUM_PRECISION;
else if (_maximum_precision == 0)
return global_maximum_precision.value();
return const_precision_iterator::global_maximum_precision.value();
else
return _maximum_precision;
}

/// @brief sets the local maximum precision
void set_maximum_precision(precision_t maximum_precision) {
this->_maximum_precision = maximum_precision;
}

/// @brief sets the global maximum precision
static void set_global_maximum_precision(precision_t maximum_precision) {
global_maximum_precision = maximum_precision;
}

/**
* @brief *Default constructor:*
* Constructs an empty real::const_precision_iterator that points to nullptr.
Expand All @@ -134,7 +144,7 @@ namespace boost {

/**
* @brief Constructor for the least precise precision iterator
*/
*/
explicit const_precision_iterator(real_number<T> * a) : _real_ptr(a), _precision(1) {
std::visit( overloaded { // perform operation on whatever is held in variant
[this] (real_explicit<T>& real) {
Expand Down Expand Up @@ -249,7 +259,7 @@ namespace boost {
*/
void operator++() {
std::visit( overloaded { // perform operation on whatever is held in variant
[this] (real_explicit<T>& real) {
[this] (real_explicit<T>& real) {
this->iterate_n_times(1);
},
[this] (real_algorithm<T>& real) {
Expand All @@ -266,7 +276,7 @@ namespace boost {

void iterate_n_times(int n) {
std::visit( overloaded { // perform operation on whatever is held in variant
[this, &n] (real_explicit<T>& real) {
[this, &n] (real_explicit<T>& real) {
if (this->_precision >= real.digits().size()) {
return;
}
Expand Down Expand Up @@ -394,6 +404,6 @@ namespace boost {
}
};
}
}
}

#endif // BOOST_CONST_PRECISION_ITERATOR_HPP

0 comments on commit 3757c61

Please sign in to comment.