Skip to content

Commit

Permalink
Style fixes, removal of unused parameters and addition of some explan…
Browse files Browse the repository at this point in the history
…ations in comments.
  • Loading branch information
tinko92 committed Aug 11, 2020
1 parent c773353 commit 9c51a62
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct side_robust_with_static_filter
bg::get<1>(p2),
bg::get<0>(p),
bg::get<1>(p));
if(sign != bg::detail::generic_robust_predicates::sign_uncertain)
if (sign != bg::detail::generic_robust_predicates::sign_uncertain)
{
return sign;
}
Expand All @@ -68,7 +68,7 @@ struct side_robust_with_static_filter
}
};

int main(int argc, char** argv)
int main()
{
point p1(0.0, 0.0);
point p2(1.0, 1.0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ template <typename Filter, std::size_t N, std::size_t End>
struct make_filter_impl
{
template <typename ExtremaArray, typename ...Reals>
static Filter apply(const ExtremaArray& extrema, const Reals&... args)
static Filter apply(ExtremaArray const& extrema, Reals const&... args)
{
return make_filter_impl<Filter, N + 1, End>
::apply(extrema, args..., extrema[N]);
Expand All @@ -39,13 +39,27 @@ template <typename Filter, std::size_t End>
struct make_filter_impl<Filter, End, End>
{
template <typename ExtremaArray, typename ...Reals>
static Filter apply(const ExtremaArray& extrema, const Reals&... args)
static Filter apply(ExtremaArray const& extrema, Reals const&... args)
{
Filter f(args...);
return f;
}
};

//The almost static filter holds an instance of a static filter and applies it
//when it is called. Its static filter can be updated and applied like this:
//
//almost_static_filter<...> f;
//
//f.update(max1, max2, ..., min1, min2, ...);
//
//f.apply(arg1, arg2, ...);
//
//Unlike with the static filter, global bounds do not need to be known at
//construction time and with incremental algorithms where inputs with higher
//magnitude are added later, the earlier applications of the filter may benefit
//from more optimistic error bounds.

template
<
typename Expression,
Expand All @@ -72,13 +86,13 @@ class almost_static_filter
std::numeric_limits<ct>::infinity());
}
template <typename ...Reals>
int apply(const Reals&... args) const
int apply(Reals const&... args) const
{
return m_filter.apply(args...);
}

template <typename ...Reals>
inline void update_extrema(const Reals&... args)
inline void update_extrema(Reals const&... args)
{
std::array<ct, sizeof...(Reals)> input {{ static_cast<ct>(args)... }};
for(int i = 0; i < m_extrema.size() / 2; ++i)
Expand All @@ -92,7 +106,7 @@ class almost_static_filter
}

template <typename ...Reals>
inline bool update_extrema_check(const Reals&... args)
inline bool update_extrema_check(Reals const&... args)
{
bool changed = false;
std::array<ct, sizeof...(Reals)> input {{ static_cast<ct>(args)... }};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ namespace boost { namespace geometry
namespace detail { namespace generic_robust_predicates
{

//The templates in this file are meant to be used for the evaluation of
//expressions with floating-point precision and floating-point rounding.
//The most important template in this file is approximate_interim.

template
<
typename Node,
Expand All @@ -37,7 +41,7 @@ template
>
struct get_nth_real_impl
{
static inline Real apply(const InputArr& input)
static inline Real apply(InputArr const& input)
{
return input[N - 1];
}
Expand All @@ -51,7 +55,7 @@ template
>
struct get_nth_real_impl<Node, 0, Real, InputArr>
{
static inline Real apply(const InputArr&)
static inline Real apply(InputArr const&)
{
return Node::value;
}
Expand All @@ -64,7 +68,7 @@ template
typename Real,
typename InputArr
>
inline Real get_nth_real(const InputArr& input)
inline Real get_nth_real(InputArr const& input)
{
return get_nth_real_impl<Node, Node::argn, Real, InputArr>::apply(input);
}
Expand All @@ -80,7 +84,7 @@ template
>
struct get_approx_impl
{
static inline Real apply(Arr& interim_results, const InputArr& input)
static inline Real apply(Arr& interim_results, InputArr const&)
{
return interim_results[boost::mp11::mp_find<All, Node>::value];
}
Expand All @@ -96,7 +100,7 @@ template
>
struct get_approx_impl<All, Node, Real, Arr, true, InputArr>
{
static inline Real apply(Arr& interim_results, const InputArr& input)
static inline Real apply(Arr&, InputArr const& input)
{
return get_nth_real<Node, Node::argn, Real, InputArr>(input);
}
Expand All @@ -110,7 +114,7 @@ template
typename Arr,
typename InputArr
>
inline Real get_approx(Arr& interim_results, const InputArr& input)
inline Real get_approx(Arr& interim_results, InputArr const& input)
{
return get_approx_impl
<
Expand Down Expand Up @@ -145,7 +149,7 @@ template
>
struct approximate_remainder_impl
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
approximate_interim_impl
Expand Down Expand Up @@ -178,7 +182,7 @@ struct approximate_remainder_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input) {}
static inline void apply(Arr&, InputArr const&) {}
};

template
Expand All @@ -189,7 +193,7 @@ template
typename Arr,
typename InputArr
>
inline void approximate_remainder(Arr& interim_results, const InputArr& input)
inline void approximate_remainder(Arr& interim_results, InputArr const& input)
{
approximate_remainder_impl
<
Expand Down Expand Up @@ -220,7 +224,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
interim_results[boost::mp11::mp_find<All, node>::value] =
Expand Down Expand Up @@ -255,7 +259,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
interim_results[boost::mp11::mp_find<All, node>::value] = std::max(
Expand Down Expand Up @@ -290,7 +294,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
interim_results[boost::mp11::mp_find<All, node>::value] = std::min(
Expand Down Expand Up @@ -325,7 +329,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
interim_results[boost::mp11::mp_find<All, node>::value] =
Expand Down Expand Up @@ -360,7 +364,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
interim_results[boost::mp11::mp_find<All, node>::value] =
Expand Down Expand Up @@ -395,7 +399,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
using node = boost::mp11::mp_front<Remaining>;
interim_results[boost::mp11::mp_find<All, node>::value] =
Expand Down Expand Up @@ -432,7 +436,7 @@ struct approximate_interim_impl
InputArr
>
{
static inline void apply(Arr& interim_results, const InputArr& input)
static inline void apply(Arr& interim_results, InputArr const& input)
{
approximate_remainder
<
Expand All @@ -443,6 +447,13 @@ struct approximate_interim_impl
}
};

//All expects an boost::mp11::mp_list of all expressions that need to be
//evaluated. Remaining expects an boost::mp11::mp_list of the expressions
//that are left to be evaluated. In the first call it is expected to be
//equal to All and it serves as an anchor for template recursion. Real is a
//floating-point type. The remaining template arguments are deduced from
//parameters.

template
<
typename All,
Expand All @@ -451,7 +462,7 @@ template
typename Arr,
typename InputArr
>
inline void approximate_interim(Arr& interim_results, const InputArr& input)
inline void approximate_interim(Arr& interim_results, InputArr const& input)
{
approximate_remainder
<
Expand All @@ -462,7 +473,7 @@ inline void approximate_interim(Arr& interim_results, const InputArr& input)
}

template<typename Expression, typename Real, typename InputArr>
inline Real approximate_value(const InputArr& input)
inline Real approximate_value(InputArr const& input)
{
using stack = typename boost::mp11::mp_unique<post_order<Expression>>;
using evals = typename boost::mp11::mp_remove_if<stack, is_leaf>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ namespace boost { namespace geometry
namespace detail { namespace generic_robust_predicates
{

//The templates in this file are helpers for the computation of error maps and
//error expressions (see also error_bound.hpp). A coefficient list is a
//boost::mp11::mp_list that contains integers that represent the coefficients
//of an polynomial. This is used for the polynomials in epsilon that occur in
//forward error analysis, e.g. epsilon + 2 * epsilon^2 + epsilon^3 would be
//represented by the type mp_list<mp_int<1>, mp_int<2>, mp_int<1>>.
//
//See p. 39 in "Adaptive Precision Floating-Point Arithmetic and Fast Robust
//Geometric Predicates" by Jonathan Richard Shewchuk (can be downloaded from
//https://www.cs.cmu.edu/~quake/robust.html) for the inspiration for the
//methods implemented below.

//only meant to be used in assertions
template <typename T> using is_mp_int =
boost::mp11::mp_same<T, boost::mp11::mp_int<T::value>>;
Expand Down Expand Up @@ -68,12 +80,21 @@ struct coeff_truncate_impl
static_assert(is_coeff_list<L>::value, "type should be a coefficient list");
};

//Because of the way floating-point numbers are rounded, for a given epsilon
//polynomial we only care about the first two non-zero coefficients.
//e.g. if a*eps + b*eps^2 + c*eps^3 is considered then c * eps^3 is always
//neglible unless c is so large that it must have resulted from the analysis
//of an expression that is so complex that it cannot be feasibly processed
//by the methods implemented in this feature.
template <typename L> using coeff_truncate = typename coeff_truncate_impl<L>::type;

template <typename L> using app_zero_b =
boost::mp11::mp_push_front<L, boost::mp11::mp_int<0>>;
template <typename L> using app_zero_f =
boost::mp11::mp_push_back<L, boost::mp11::mp_int<0>>;

//For a coefficient list representing the polynomial p, the following template
//produces the coefficient list representing p * (1 + eps).
template <typename L> using mult_by_1_p_eps = coeff_truncate
<
boost::mp11::mp_transform
Expand Down Expand Up @@ -110,6 +131,9 @@ struct mult_by_1_p_eps_pow_impl<L, N, boost::mp11::mp_true>
using type = L;
};


//For a coefficient list representing the polynomial p, the following template
//produces the cofficient list representing p * (1 + eps)^N
template <typename L, typename N> using mult_by_1_p_eps_pow = coeff_truncate
<
typename mult_by_1_p_eps_pow_impl<L, N>::type
Expand All @@ -123,6 +147,9 @@ template <typename L> using div_by_1_m_eps_helper =
boost::mp11::mp_plus
>;

//For a coefficient list representing a polynomial p in eps, the following
//template computes a coefficient list representing a polynomial q such that
//q * (1 - p) >= p.
template <typename L> using div_by_1_m_eps = coeff_truncate
<
boost::mp11::mp_push_back
Expand Down Expand Up @@ -406,6 +433,11 @@ struct coeff_round_impl<L, 0> { using type = L; };
template <typename L>
struct coeff_round_impl<L, 1> { using type = L; };

//The following template rounds a coefficient list up such that the
//corresponding polynomial evaluated for epsilon is a representable
//floating-point number.
//
//e.g. 3 * eps + 12 * eps^2 + 1 * eps^3 is rounded to 3 * eps + 16 * eps^2
template <typename L> using coeff_round = typename coeff_round_impl<L>::type;

template <typename IV1, typename IV2> using indexed_value_product =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ namespace boost { namespace geometry
namespace detail { namespace generic_robust_predicates
{

//The templates in this file are utilities for the generation of error
//expressions for given arithmetic expressions. This is done using forward
//error analysis methods at compile time. This analysis produces an error map
//that is folded into an error expression.
//
//An Error Map is a template fulfilling the boost::mp11 map concept. The keys K
//are expressions (as in expression trees and the values V are lists of
//integers. Each key-value pair represents the contribution of an error term to
//the total error, i.e. the error expression is something like the sum of
//abs<K> * (V[0] * epsilon + V[1] * epsilon^2 + ...)
//
//over all key-value pairs KV in the error map.
//
//See p. 39 in "Adaptive Precision Floating-Point Arithmetic and Fast Robust
//Geometric Predicates" by Jonathan Richard Shewchuk (can be downloaded from
//https://www.cs.cmu.edu/~quake/robust.html) for the inspiration for the
//methods implemented below.

template <typename KV> using second_is_coeff_list =
is_coeff_list< boost::mp11::mp_second<KV> >;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ namespace boost { namespace geometry
namespace detail { namespace generic_robust_predicates
{

//The templates in this file are designed to represent arithmetic expressions
//In the type system so that they can be processed at compile-time for the
//automatic creation of floating-point filters.
//
//E.g. the arithmetic expression a * b + c can be represented by the type
//
//sum< product < argument<1>, argument<2> >, argument<3> >
//
//The arguments represent the input variables and are the leaves of the
//expression tree (other possible leaves are constants). Because they represent
//placeholders their indexing is one-based rather than zero-based, similar to
//the placeholders for std::bind.

enum class operator_types {
sum, difference, product, abs, no_op, max, min
};
Expand Down Expand Up @@ -144,6 +157,12 @@ struct static_constant_interface : public leaf
template <typename Node>
using is_leaf = boost::mp11::mp_bool<Node::is_leaf>;

//post_order_impl and post_order are templates for compile-time traversion of
//expression trees. The post_order traversal was chosen because it guarantees
//that children (subexpressions) are evaluated before there parents as is
//necessary for the evaluation of the arithmetic expressions that these
//expression trees represent.

template
<
typename In,
Expand Down
Loading

0 comments on commit 9c51a62

Please sign in to comment.