Skip to content

Commit

Permalink
[extensions] Automatically generated floating point filters.
Browse files Browse the repository at this point in the history
  • Loading branch information
tinko92 committed Jul 28, 2020
1 parent 02b1632 commit b59b651
Show file tree
Hide file tree
Showing 18 changed files with 2,990 additions and 0 deletions.
1 change: 1 addition & 0 deletions extensions/example/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ project boost-geometry-examples-extensions
;

build-project gis ;
build-project generic_robust_predicates ;
12 changes: 12 additions & 0 deletions extensions/example/generic_robust_predicates/Jamfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Boost.Geometry (aka GGL, Generic Geometry Library)

# Use, modification and distribution is 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)


project boost-geometry-example-extensions-generic_robust_predicates
:
;

exe static_side_2d : static_side_2d.cpp ;
79 changes: 79 additions & 0 deletions extensions/example/generic_robust_predicates/static_side_2d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.

// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2020 program.

// Use, modification and distribution is 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)


#define BOOST_GEOMETRY_NO_BOOST_TEST

#include <iostream>

#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/geometries/point.hpp>

#include <boost/geometry/extensions/triangulation/strategies/cartesian/side_robust.hpp>
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expressions.hpp>
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/stage_a.hpp>


namespace bg = boost::geometry;
using point = bg::model::point<double, 2, bg::cs::cartesian>;

template <typename CalculationType>
struct side_robust_with_static_filter
{
private:
using ct = CalculationType;
using expression = bg::detail::generic_robust_predicates::orient2d;
using filter = bg::detail::generic_robust_predicates::stage_a_static
<
expression,
ct
>;
filter m_filter;
public:
side_robust_with_static_filter(ct x_max, ct y_max, ct x_min, ct y_min)
: m_filter(x_max, y_max, x_max, y_max, x_max, y_max,
x_min, y_min, x_min, y_min, x_min, y_min) {};

template
<
typename P1,
typename P2,
typename P
>
inline int apply(P1 const& p1, P2 const& p2, P const& p) const
{
int sign = m_filter.apply(bg::get<0>(p1),
bg::get<1>(p1),
bg::get<0>(p2),
bg::get<1>(p2),
bg::get<0>(p),
bg::get<1>(p));
if(sign != bg::detail::generic_robust_predicates::sign_uncertain)
{
return sign;
}
else
{
//fallback if filter fails.
return bg::strategy::side::side_robust<double>::apply(p1, p2, p);
}
}
};

int main(int argc, char** argv)
{
point p1(0.0, 0.0);
point p2(1.0, 1.0);
point p (0.0, 1.0);
side_robust_with_static_filter<double> static_strategy(2.0, 2.0, 1.0, 1.0);
std::cout << "Side value: " << static_strategy.apply(p1, p2, p) << "\n";
return 0;
}
1 change: 1 addition & 0 deletions extensions/test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ build-project gis ;
build-project iterators ;
build-project nsphere ;
build-project triangulation ;
build-project generic_robust_predicates ;
12 changes: 12 additions & 0 deletions extensions/test/generic_robust_predicates/Jamfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Boost.Geometry (aka GGL, Generic Geometry Library)
#
# Use, modification and distribution is 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)

test-suite boost-geometry-extensions-generic_robust_predicates
:
[ run approximate.cpp ]
[ run side3d.cpp : : : <debug-symbols>off ]
;

66 changes: 66 additions & 0 deletions extensions/test/generic_robust_predicates/approximate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test

// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.

// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2020 program.

// Use, modification and distribution is 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 <array>

#include <geometry_test_common.hpp>

#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/approximate.hpp>
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expression_tree.hpp>

template <typename CalculationType>
void test_all()
{
using bg::detail::generic_robust_predicates::_1;
using bg::detail::generic_robust_predicates::_2;
using bg::detail::generic_robust_predicates::_3;
using bg::detail::generic_robust_predicates::_4;
using bg::detail::generic_robust_predicates::sum;
using bg::detail::generic_robust_predicates::difference;
using bg::detail::generic_robust_predicates::product;
using bg::detail::generic_robust_predicates::max;
using bg::detail::generic_robust_predicates::abs;
using bg::detail::generic_robust_predicates::post_order;
using bg::detail::generic_robust_predicates::approximate_value;
using bg::detail::generic_robust_predicates::get_approx;
using bg::detail::generic_robust_predicates::approximate_interim;
using ct = CalculationType;
ct r1 = approximate_value<sum<_1, _2>, ct>(
std::array<ct, 2>{1.0, 2.0});
BOOST_CHECK_EQUAL(3.0, r1);
ct r2 = approximate_value<max<abs<_1>, abs<_2>>, ct>(
std::array<ct, 2>{-10.0, 2.0});
BOOST_CHECK_EQUAL(10.0, r2);

using expression = product
<
difference<_1, _2>,
difference<_3, _4>
>;
using evals = post_order<expression>;
std::array<ct, boost::mp11::mp_size<evals>::value> r;
std::array<ct, 4> input {5.0, 3.0, 2.0, 8.0};
approximate_interim<evals, evals, ct>(r, input);
ct r3 = get_approx<evals, typename expression::left, ct>(r, input);
BOOST_CHECK_EQUAL(2.0, r3);
ct r4 = get_approx<evals, typename expression::right, ct>(r, input);
BOOST_CHECK_EQUAL(-6.0, r4);
ct r5 = get_approx<evals, expression, ct>(r, input);
BOOST_CHECK_EQUAL(-12.0, r5);
}


int test_main(int, char* [])
{
test_all<double>();
return 0;
}
76 changes: 76 additions & 0 deletions extensions/test/generic_robust_predicates/side3d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test

// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.

// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2020 program.

// Use, modification and distribution is 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 <array>

#include <geometry_test_common.hpp>

#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expressions.hpp>
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/stage_a.hpp>

template <typename CalculationType>
void test_all()
{
using bg::detail::generic_robust_predicates::orient3d;
using bg::detail::generic_robust_predicates::stage_a_semi_static;
using bg::detail::generic_robust_predicates::stage_a_almost_static;
using bg::detail::generic_robust_predicates::stage_a_static;
using ct = CalculationType;
using semi_static = stage_a_semi_static<orient3d, ct>;
BOOST_CHECK_EQUAL(1,
semi_static::apply(1, 0, 0,
0, 1, 0,
1, 1, 0,
0, 0, 1));
BOOST_CHECK_EQUAL(-1,
semi_static::apply(1, 0, 0,
0, 1, 0,
1, 1, 0,
0, 0, -1));
BOOST_CHECK_EQUAL(0,
semi_static::apply(1, 0, 0,
0, 1, 0,
1, 1, 0,
0, 0, 0));
stage_a_static<orient3d, ct> stat(10, 10, 10,
10, 10, 10,
10, 10, 10,
10, 10, 10,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0);
BOOST_CHECK_EQUAL(1, stat.apply(1, 0, 0,
0, 1, 0,
1, 1, 0,
0, 0, 1));

stage_a_static<orient3d, ct> pessimistic(1e40, 1e40, 1e40,
1e40, 1e40, 1e40,
1e40, 1e40, 1e40,
1e40, 1e40, 1e40,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0);
BOOST_CHECK_EQUAL(bg::detail::generic_robust_predicates::sign_uncertain,
pessimistic.apply(1, 0, 0,
0, 1, 0,
1, 1, 0,
0, 0, 1));
}

int test_main(int, char* [])
{
test_all<double>();
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.

// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2020 program.

// Use, modification and distribution is 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)

#ifndef BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_ALMOST_STATIC_FILTER_HPP
#define BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_ALMOST_STATIC_FILTER_HPP

#include <array>
#include <algorithm>
#include <limits>

#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expression_tree.hpp>

namespace boost { namespace geometry
{

namespace detail { namespace generic_robust_predicates
{

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)
{
return make_filter_impl<Filter, N + 1, End>
::apply(extrema, args..., extrema[N]);
}
};

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)
{
Filter f(args...);
return f;
}
};

template
<
typename Expression,
typename CalculationType,
typename StaticFilter
>
class almost_static_filter
{
private:
using expression_max_argn = max_argn<Expression>;
using ct = CalculationType;
using extrema_array = std::array<ct, 2 * expression_max_argn::value>;
extrema_array m_extrema;
StaticFilter m_filter;
public:
const StaticFilter& filter() const { return m_filter; }
inline almost_static_filter()
{
std::fill(m_extrema.begin(),
m_extrema.begin() + m_extrema.size() / 2,
-std::numeric_limits<ct>::infinity());
std::fill(m_extrema.begin() + m_extrema.size() / 2,
m_extrema.end(),
std::numeric_limits<ct>::infinity());
}
template <typename ...Reals>
int apply(const Reals&... args) const
{
return m_filter.apply(args...);
}

template <typename ...Reals>
inline void update_extrema(const Reals&... args)
{
std::array<ct, sizeof...(Reals)> input {{ static_cast<ct>(args)... }};
for(int i = 0; i < m_extrema.size() / 2; ++i)
{
m_extrema[i] = std::max(m_extrema[i], input[i]);
}
for(int i = m_extrema.size() / 2; i < m_extrema.size(); ++i)
{
m_extrema[i] = std::min(m_extrema[i], input[i]);
}
}

template <typename ...Reals>
inline bool update_extrema_check(const Reals&... args)
{
bool changed = false;
std::array<ct, sizeof...(Reals)> input {{ static_cast<ct>(args)... }};
for(int i = 0; i < m_extrema.size() / 2; ++i)
{
if(input[i] > m_extrema[i])
{
changed = true;
m_extrema[i] = input[i];
}
}
for(int i = m_extrema.size() / 2; i < m_extrema.size(); ++i)
{
if(input[i] < m_extrema[i])
{
changed = true;
m_extrema[i] = input[i];
}
}
return changed;
}

inline void update_filter()
{
m_filter = make_filter_impl
<
StaticFilter,
0,
2 * expression_max_argn::value
>::apply(m_extrema);
}
};

}} // namespace detail::generic_robust_predicates

}} // namespace boost::geometry

#endif // BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_ALMOST_STATIC_FILTER_HPP
Loading

0 comments on commit b59b651

Please sign in to comment.