Boost logo

Boost Users :

Subject: Re: [Boost-users] multiprecision modf
From: Daniel Brake (danielthebrake_at_[hidden])
Date: 2016-08-03 12:19:31


Paul, Boost,

Thanks for the quick reply!

I haven’t looked into this in detail, but I think not,
> but Boost.Math does
>
> #include <boost/math/special_functions/modf.hpp>
>
> You might also need to add this to your local function(s) to aid Argument
> Dependant Lookup (ADL).
>
> BOOST_MATH_STD_USING

Boost.Math and the BOOST_MATH_STD_USING solved the modf problem, so long as
I include and using before including Karma.
Since the compiler got past that, it generated a new error, related to
log10, floor, and int comparison. I've had errors related to log10, floor,
and ceil in the context of Eigen before. /u/ggael resolved them by
explicit casting in certain places, see e.g.
https://forum.kde.org/viewtopic.php?f=74&t=133404&p=359710#p359710

Here's the new error message:

In file included from test/generating/mpfr_float.cpp:27:
In file included from ./include/bertini2/io/generators.hpp:44:
In file included from /usr/local/include/boost/spirit/include/karma.hpp:16:
In file included from /usr/local/include/boost/spirit/home/karma.hpp:15:
In file included from
/usr/local/include/boost/spirit/home/karma/numeric.hpp:16:
In file included from
/usr/local/include/boost/spirit/home/karma/numeric/real.hpp:32:
/usr/local/include/boost/spirit/home/karma/numeric/real_policies.hpp:263:39:
error: incompatible operand types ('int' and 'typename
      enable_if_c<number_category<detail::expression<function,
log10_funct<mpfr_float_backend<0, allocate_dynamic> >,
number<mpfr_float_backend<0,
      allocate_dynamic>,
boost::multiprecision::expression_template_option::et_on>, void, void>
>::value == number_kind_floating_point,
      detail::expression<detail::function, detail::floor_funct<typename
detail::backend_type<detail::expression<function,
      log10_funct<mpfr_float_backend<0, allocate_dynamic> >,
number<mpfr_float_backend<0, allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>, void,
void> >::type>, detail::expression<function,
log10_funct<mpfr_float_backend<0,
      allocate_dynamic> >, number<mpfr_float_backend<0, allocate_dynamic>,
boost::multiprecision::expression_template_option::et_on>, void, void> >
>::type' (aka
'boost::multiprecision::detail::expression<boost::multiprecision::detail::function,

boost::multiprecision::detail::floor_funct<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic> >,

boost::multiprecision::detail::expression<boost::multiprecision::detail::function,

boost::multiprecision::detail::log10_funct<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic> >,

boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>, void,
void>, void, void>'))
                (traits::test_zero(n) ? 0 : floor(log10(n))) + 1;
                                      ^ ~ ~~~~~~~~~~~~~~~
/usr/local/include/boost/spirit/home/karma/numeric/detail/real_utils.hpp:170:24:
note: in instantiation of function template specialization

'boost::spirit::karma::real_policies<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>

>::fraction_part<boost::spirit::karma::detail::output_iterator<std::__1::back_insert_iterator<std::__1::basic_string<char>
>, mpl_::int_<0>,
      boost::spirit::unused_type> >' requested here
            r = r && p.fraction_part(sink, long_frac_part, prec, precision);
                       ^
/usr/local/include/boost/spirit/home/karma/numeric/real_policies.hpp:94:30:
note: in instantiation of function template specialization

'boost::spirit::karma::real_inserter<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>,
bertini::generators::BertiniNumPolicy<mpfr_float>,
boost::spirit::unused_type,

boost::spirit::unused_type>::call_n<boost::spirit::karma::detail::output_iterator<std::__1::back_insert_iterator<std::__1::basic_string<char>
>,
      mpl_::int_<0>, boost::spirit::unused_type>,
boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on> >'
requested here
            return Inserter::call_n(sink, n, p);
                             ^
/usr/local/include/boost/spirit/home/karma/numeric/detail/real_utils.hpp:56:31:
note: in instantiation of function template specialization

'boost::spirit::karma::real_policies<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>

>::call<boost::spirit::karma::real_inserter<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>,
bertini::generators::BertiniNumPolicy<mpfr_float>,
boost::spirit::unused_type,
      boost::spirit::unused_type>,
boost::spirit::karma::detail::output_iterator<std::__1::back_insert_iterator<std::__1::basic_string<char>
>,
      mpl_::int_<0>, boost::spirit::unused_type>,
bertini::generators::BertiniNumPolicy<mpfr_float> >' requested here
            return p.template call<real_inserter>(sink, n, p);
                              ^
/usr/local/include/boost/spirit/home/karma/numeric/real.hpp:192:35: note:
in instantiation of function template specialization

'boost::spirit::karma::real_inserter<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>,
bertini::generators::BertiniNumPolicy<mpfr_float>,
boost::spirit::unused_type,

boost::spirit::unused_type>::call<boost::spirit::karma::detail::output_iterator<std::__1::back_insert_iterator<std::__1::basic_string<char>
>,
      mpl_::int_<0>, boost::spirit::unused_type>,
boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on> >'
requested here
            return inserter_type::call(sink, traits::extract_from<T>(attr,
context), p_) &&
                                  ^
/usr/local/include/boost/spirit/home/karma/generate.hpp:69:45: note: in
instantiation of function template specialization

'boost::spirit::karma::any_real_generator<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>,
bertini::generators::BertiniNumPolicy<mpfr_float>,
boost::spirit::unused_type,

boost::spirit::unused_type>::generate<boost::spirit::karma::detail::output_iterator<std::__1::back_insert_iterator<std::__1::basic_string<char>
>,
      mpl_::int_<0>, boost::spirit::unused_type>,
boost::spirit::context<boost::fusion::cons<const

boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on> &,
boost::fusion::nil_>, boost::spirit::locals<mpl_::na, mpl_::na, mpl_::na,
mpl_::na,
      mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >,
boost::spirit::unused_type,

boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on> >'
requested here
        return compile<karma::domain>(expr).generate(sink, context, unused,
attr);
                                            ^
/usr/local/include/boost/spirit/home/karma/generate.hpp:91:23: note: in
instantiation of function template specialization

'boost::spirit::karma::generate<std::__1::back_insert_iterator<std::__1::basic_string<char>
>, mpl_::int_<0>,

boost::spirit::karma::real_generator<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>,
bertini::generators::BertiniNumPolicy<mpfr_float> >,

boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on> >'
requested here
        return karma::generate(sink, expr, attr);
                      ^
./include/bertini2/io/generators.hpp:153:21: note: in instantiation of
function template specialization

'boost::spirit::karma::generate<std::__1::back_insert_iterator<std::__1::basic_string<char>
>,

boost::spirit::karma::real_generator<boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on>,
bertini::generators::BertiniNumPolicy<mpfr_float> >,

boost::multiprecision::number<boost::multiprecision::backends::mpfr_float_backend<0,
allocate_dynamic>,
      boost::multiprecision::expression_template_option::et_on> >'
requested here
                    return generate(sink,
                           ^
test/generating/mpfr_float.cpp:53:47: note: in instantiation of function
template specialization

'bertini::generators::Classic::generate<std::__1::back_insert_iterator<std::__1::basic_string<char>
> >' requested here
    BOOST_CHECK(bertini::generators::Classic::generate(sink, z));

Any help with this one would be greatly appreciated. It feels beyond my
diagnosis. It feels to me like I might should feed mpfr_float into Fusion
to adapt it, so I can use the type directly with Karma. Here's the
generator code so far:

template <typename Num>
struct BertiniNumPolicy : public karma::real_policies<Num>
{
    // we want the numbers always to be in scientific format
    static int floatfield(Num n) { return std::ios_base::scientific; }

    static unsigned int precision(Num) {
        return std::numeric_limits<Num>::max_digits10;
      }
};

template<>
struct BertiniNumPolicy<mpfr_float> : public
karma::real_policies<mpfr_float>
{
    // we want the numbers always to be in scientific format
    static int floatfield(mpfr_float n) { return std::ios_base::scientific;
}

    static unsigned int precision(mpfr_float const& x) {
        return x.precision();
      }
};

template<typename Num>
using FullPrec = boost::spirit::karma::real_generator<Num,
BertiniNumPolicy<Num> >;

FullPrec<double> const full_prec_d = FullPrec<double>();
FullPrec<mpfr_float> const full_prec_mp = FullPrec<mpfr_float>();

template <typename OutputIterator>
static bool generate(OutputIterator sink, mpfr_float const& c)
{
    using boost::spirit::karma::generate;

    return generate(sink,

        // Begin grammar
        (
           full_prec_mp
        ),
        // End grammar

        c // Data to output
        );
}

As a last question, I am unsure about the use of the a function parameter
in my specialization BertiniNumPolicy<mpfr_float>, particularly the
precision(mpfr_float) function. In the documentation and examples I have
seen for specializations, this function doesn't use the argument. Is it ok
that it does, that it checks the actual precision of x??? See above code.
An alternate method for me might be to just use the str() method provided
by the number<...> from Multiprecision, but it seems like since this type
is numeric, I'd like to be able to generate using the numeric generators
from Karma.

Thanks again!

Daniel Brake

> ---------- Forwarded message ----------
> From: "Paul A. Bristow" <pbristow_at_[hidden]>
> To: <boost-users_at_[hidden]>
> Cc:
> Date: Wed, 3 Aug 2016 10:00:20 +0100
> Subject: Re: [Boost-users] multiprecision modf
>
> I haven’t looked into this in detail, but I think not,
>
>
>
> but Boost.Math does
>
>
>
> #include <boost/math/special_functions/modf.hpp>
>
>
>
> You might also need to add this to your local function(s) to aid Argument
> Dependant Lookup (ADL).
>
>
>
> BOOST_MATH_STD_USING
>
>
>
>
> http://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/config_macros.html#math_toolkit.config_macros.boost_math_macros
>
>
>
> *Table 11. Boost.Math Macros*
>
>
>
> “Provides using statements for many std:: (abs to sqrt) and boost::math
> (rounds, modf) functions. This allows these functions to be called
> unqualified so that ifargument-dependent Argument Dependent Lookup
> <http://en.wikipedia.org/wiki/Argument-dependent_name_lookup> fails to
> find a suitable overload, then the std:: versions will also be considered.”
>
>
>
> HTH
>
>
>
> Paul
>



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