Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically generated, fast floating-point predicates #739

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

tinko92
Copy link
Contributor

@tinko92 tinko92 commented Jul 28, 2020

This pull request contains the first part of my GSoC 2020 project. This code is still work in progress and there might be changes to the interface before the end of GSoC.

The project aims to implement a number of facilities that allow easy creation of fast and robust geometric floating-point predicates, such as, for example, orientation tests (Boost.Geometry currently has a 2d orientation test in the side-strategy). As of writing this, the pull request contains templates to

  • automatically derive error bounds for the approximate evaluation of such expressions
  • build static, almost static and semi-static filters from these expressions

I intend to add

  • generation of functions for the exact evaluation of arbitrary arithmetic floating-point expressions containing +, - and * using expansion arithmetic
  • improvements for the error bound derivation
  • an alternative method for error bound derivation
  • some additional filters
  • automatic detection of reusable interim results between filter stages

The usage of the various templates for the creation of geometric predicates is illustrated in the tests and the example.

This pull request depends on Boost.MP11, which depends on C++11 but has no additional dependencies. The code itself depends on C++14 because of certain constexpr features.

Copy link
Member

@vissarion vissarion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Tinko, this is very interesting. I have minor comments.

bg::get<1>(p2),
bg::get<0>(p),
bg::get<1>(p));
if(sign != bg::detail::generic_robust_predicates::sign_uncertain)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a space missing after if

}
};

int main(int argc, char** argv)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

argc, argv are unused, please compile with -Wall since there are a few more unused variables in this PR.

struct make_filter_impl
{
template <typename ExtremaArray, typename ...Reals>
static Filter apply(const ExtremaArray& extrema, const Reals&... args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ExtremaArray& should beExtremaArray const&, similar for const ExtremaArray&

struct make_filter_impl<Filter, End, End>
{
template <typename ExtremaArray, typename ...Reals>
static Filter apply(const ExtremaArray& extrema, const Reals&... args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}

template <typename ...Reals>
inline bool update_extrema_check(const Reals&... args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}

template <typename ...Reals>
inline void update_extrema(const Reals&... args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same hare

typename Arr,
typename InputArr
>
inline Real get_approx(Arr& interim_results, const InputArr& input)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually the output parameter(s) goes after the input parameter(s) in the library
also const InputArr& should be InputArr const&

>;

using orient2d = det2x2
<
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 8 spaces here vs 4 above?

@tinko92 tinko92 force-pushed the feature/floating_point_filters branch from 9c51a62 to 4da968e Compare August 26, 2020 23:17
@tinko92
Copy link
Contributor Author

tinko92 commented Mar 4, 2021

I have made the following changes to the PR:

  • The template-based error bound calculation has been replaced by a constexpr based implementation. This improves compile-time, template instantiation depth and readability.
  • I have tried to address all feedback (spaces after if, unused parameters, position of "const" in types"
  • Staged predicates have been added.

The PR now includes a new test-case in https://github.com/BoostGSoC20/geometry/blob/feature/floating_point_filters/extensions/test/generic_robust_predicates/staged.cpp . It illustrates the intended use of the code in this PR.

For a given geometric predicate (in the example the side-predicate), an expression type needs to be constructed. Using the expression type and a floating-point calculation type (like double), filters can be constructed from the stage_* files. These filters can be combined into a staged_predicate for usage, for example, in a robust side strategy or any other strategy that can be computed as the sign of a polynomial of floating-point coordinates.

The remaining headers are not intended to be used directly and can be considered implementation details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants