Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost.polygon.voronoi] [Boost.multiprecision] higher precision voronoi
From: Weatherby,Gerard (gweatherby_at_[hidden])
Date: 2014-03-17 11:57:19


> -----Original Message-----
> From: Boost-users [mailto:boost-users-bounces_at_[hidden]] On Behalf Of
> It's a conceptual issue: polynomial is calling std::sqrt, but there is no overload of
> sqrt for multiprecision types in that namespace: to place them there would
> actually be mal-formed according to the std.
>
> Had polygon been coded like this:
>
> template <typename T>
> T get_sqrt(const T& that) {
> using std::sqrt;
> return (sqrt)(that); // ADL is now active }
>
> Then the correct overload would have been found.
>
> One possible workaround would be to provide an overload of get_sqrt but that
> would be hard to do in the presence of expression templates :-( Turning them off
> in the number type you're using would make life much easier, or else I can help
> with providing expression-template aware overloads.

I tried both suggestions as best I understood them; changing the boost::polygon::voronoi get_sqrt implementation and changing
my code as follows. (Aside: I realized I actually wanted 80, not 48 floating point bits).

namespace bmulti = boost::multiprecision;
   using bmulti::et_off;
    typedef bmulti::number<bmulti::cpp_dec_float<80>,et_off> floatingType;

   using bmulti::cpp_int_backend;
   using bmulti::signed_magnitude;
   using bmulti::unsigned_magnitude;
   using bmulti::unchecked;
   typedef bmulti::number<cpp_int_backend<128, 128, signed_magnitude, unchecked, void>,et_off > int128;
   typedef bmulti::number<cpp_int_backend<128, 128, unsigned_magnitude, unchecked, void>,et_off > uint128;
   typedef bmulti::number<cpp_int_backend<512, 512, signed_magnitude, unchecked, void>,et_off > int512;

    struct voronoi_ctype_traits {
        typedef boost::int64_t int_type;
        typedef int128 int_x2_type;
        typedef uint128 uint_x2_type;
        typedef int512 big_int_type;
        typedef floatingType fpt_type;
        typedef floatingType efpt_type;
        typedef compareFloatingType ulp_cmp_type;
        typedef FloatingConverter to_fpt_converter_type;
        typedef FloatingConverter to_efpt_converter_type;
...
But still got:
1>d:\workspace\movingboundary\boost_1_53_0\boost\polygon\detail\voronoi_robust_fpt.hpp(61): error C2665: 'sqrt' : none of the 3 overloads could convert all the argument types
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\math.h(127): could be 'double sqrt(double)'
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\math.h(540): or 'float sqrt(float)'
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\math.h(588): or 'long double sqrt(long double)'
1> while trying to match the argument list '(const boost::multiprecision::number<Backend,ExpressionTemplates>)'
1> with
1> [
1> Backend=boost::multiprecision::backends::cpp_dec_float<80>,
1> ExpressionTemplates=et_off
1> ]
1>

What does seem to work for MSVC compiling is adding (somewhat inelegant) definition:
namespace std {
    boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80> >
    sqrt(const boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80> >& in) {
        boost::multiprecision::backends::cpp_dec_float<80> v = in.canonical_value(in);
        return v.calculate_sqrt( );
    }
}

But gcc 4.8.2 compiling produces:
In file included from /state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/detail/voronoi_predicates.hpp:15:0,
                 from /state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/voronoi_builder.hpp:20,
                 from /state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/voronoi.hpp:17,
                 from /state/partition1/MovingBoundary/Tests/v64.cpp:6:
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/detail/voronoi_robust_fpt.hpp: In instantiation of 'T boost::polygon::detail::get_sqrt(const T&) [with T = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u>]':
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/detail/voronoi_predicates.hpp:1042:46: required from 'void boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::lazy_circle_formation_functor<Site, Circle>::ppp(const site_type&, const site_type&, const site_type&, boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::lazy_circle_formation_functor<Site, Circle>::circle_type&) [with Site = boost::polygon::detail::site_event<long int>; Circle = boost::polygon::detail::circle_event<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u> >; CTYPE_TRAITS = vcellVoronoiImpl::voronoi_ctype_traits; boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::lazy_circle_formation_functor<Site, Circle>::site_type = boost::polygon::detail::site_event<long int>; boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::lazy_circle_formation_functor<Site, Circle>::circle_type = boost::polygon::detail::circle_event<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u> >]'
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/detail/voronoi_predicates.hpp:1467:13: required from 'bool boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::circle_formation_predicate<Site, Circle, CEP, CFF>::operator()(const site_type&, const site_type&, const site_type&, boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::circle_formation_predicate<Site, Circle, CEP, CFF>::circle_type&) [with Site = boost::polygon::detail::site_event<long int>; Circle = boost::polygon::detail::circle_event<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u> >; CEP = boost::polygon::detail::voronoi_predicates<vcellVoronoiImpl::voronoi_ctype_traits>::circle_existence_predicate<boost::polygon::detail::site_event<long int> >; CFF = boost::polygon::detail::voronoi_predicates<vcellVoronoiImpl::voronoi_ctype_traits>::lazy_circle_formation_functor<boost::polygon::detail::site_event<long int>, boost::polygon::detail::circle_event<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u> > >; CTYPE_TRAITS = vcellVoronoiImpl::voronoi_ctype_traits; boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::circle_formation_predicate<Site, Circle, CEP, CFF>::site_type = boost::polygon::detail::site_event<long int>; boost::polygon::detail::voronoi_predicates<CTYPE_TRAITS>::circle_formation_predicate<Site, Circle, CEP, CFF>::circle_type = boost::polygon::detail::circle_event<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u> >]'
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/voronoi_builder.hpp:478:5: required from 'void boost::polygon::voronoi_builder<T, CTT, VP>::activate_circle_event(const site_event_type&, const site_event_type&, const site_event_type&, boost::polygon::voronoi_builder<T, CTT, VP>::beach_line_iterator) [with T = long int; CTT = vcellVoronoiImpl::voronoi_ctype_traits; VP = boost::polygon::detail::voronoi_predicates<vcellVoronoiImpl::voronoi_ctype_traits>; boost::polygon::voronoi_builder<T, CTT, VP>::site_event_type = boost::polygon::detail::site_event<long int>; typename CTT::int_type = long int; boost::polygon::voronoi_builder<T, CTT, VP>::beach_line_iterator = std::_Rb_tree_iterator<std::pair<const boost::polygon::detail::beach_line_node_key<boost::polygon::detail::site_event<long int> >, boost::polygon::detail::beach_line_node_data<void, boost::polygon::detail::circle_event<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u> > > > >]'
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/voronoi_builder.hpp:309:51: required from 'void boost::polygon::voronoi_builder<T, CTT, VP>::process_site_event(OUTPUT*) [with OUTPUT = boost::polygon::voronoi_diagram<long int, vcellVoronoiImpl::vcell_vd_traits>; T = long int; CTT = vcellVoronoiImpl::voronoi_ctype_traits; VP = boost::polygon::detail::voronoi_predicates<vcellVoronoiImpl::voronoi_ctype_traits>]'
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/voronoi_builder.hpp:106:34: required from 'void boost::polygon::voronoi_builder<T, CTT, VP>::construct(OUTPUT*) [with OUTPUT = boost::polygon::voronoi_diagram<long int, vcellVoronoiImpl::vcell_vd_traits>; T = long int; CTT = vcellVoronoiImpl::voronoi_ctype_traits; VP = boost::polygon::detail::voronoi_predicates<vcellVoronoiImpl::voronoi_ctype_traits>]'
/state/partition1/MovingBoundary/Tests/v64.cpp:93:20: required from here
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/detail/voronoi_robust_fpt.hpp:61:21: error: no matching function for call to 'sqrt(const boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u>&)'
   return (sqrt)(that);
                     ^
/state/partition1/MovingBoundary/boost_1_53_0/boost/polygon/detail/voronoi_robust_fpt.hpp:61:21: note: candidates are:
In file included from /usr/include/features.h:361:0,
                 from /home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/x86_64-unknown-linux-gnu/bits/os_defines.h:39,
                 from /home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/x86_64-unknown-linux-gnu/bits/c++config.h:426,
                 from /home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/cmath:41,
                 from /state/partition1/MovingBoundary/Tests/v64.cpp:3:
/usr/include/bits/mathcalls.h:157:1: note: double sqrt(double)
 __MATHCALL (sqrt,, (_Mdouble_ __x));
 ^
/usr/include/bits/mathcalls.h:157:1: note: no known conversion for argument 1 from 'const boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u>' to 'double'
In file included from /state/partition1/MovingBoundary/Tests/v64.cpp:3:0:
/home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/cmath:482:3: note: constexpr float std::sqrt(float)
   sqrt(float __x)
   ^
/home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/cmath:482:3: note: no known conversion for argument 1 from 'const boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u>' to 'float'
/home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/cmath:486:3: note: constexpr long double std::sqrt(long double)
   sqrt(long double __x)
   ^
/home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/cmath:486:3: note: no known conversion for argument 1 from 'const boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<80u>, (boost::multiprecision::expression_template_option)0u>' to 'long double'
/home/CAM/gweatherby/.local/easybuild/software/GCC/4.8.2/include/c++/4.8.2/cmath:494:5: note: template<class _Tp> constexpr typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type std::sqrt(_Tp)
     sqrt(_Tp __x)
....


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net