简体   繁体   中英

Boost::multiprecision and cardinal_cubic_b_spline

I'm new using the boost::multiprecision library and tried to use it combination with boost::math::interpolators::cardinal_cubic_b_spline however I can't compile the program.

The example code is

#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
#include <iostream>
#include <boost/multiprecision/gmp.hpp>

using boost::multiprecision::mpf_float_50;

int main() {
    std::vector<mpf_float_50> v(10);
    mpf_float_50 step(0.01);

    for (size_t i = 0; i < v.size(); ++i) {
        v.at(i) = sin(i*step);
    }

    mpf_float_50 leftPoint(0.0);
    boost::math::interpolators::cardinal_cubic_b_spline<mpf_float_50> spline(v.begin(), v.end(), leftPoint, step);

    mpf_float_50 x(3.1);
    mpf_float_50 tmpVal = spline(x);
    std::cout << tmpVal << std::endl;

    return 0;
}

When change the type of variables to boost::multiprecision::cpp_bin_float_50 the program is working. Also, boost::multiprecision::mpf_float_50 is working in all other examples I have tried.

The error I get is:

/home/..../main.cpp:19:31:   required from here
/usr/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp:50:10: error: conversion from ‘expression<boost::multiprecision::detail::function,boost::multiprecision::detail::abs_funct<boost::multiprecision::backends::gmp_float<50> >,boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::gmp_float<50> >, long unsigned int, void, void>,[...],[...]>’ to non-scalar type ‘expression<boost::multiprecision::detail::subtract_immediates,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<50> >,long unsigned int,[...],[...]>’ requested

The same error appeared for cpp_dec_float_50, mpfr_float_50 etc. I'm not sure what I'm doing wrong.

The selected type. is the GMP backend. To give it the usual operators, it is wrapped in the frontend template number<> :

Live On Coliru

using F = boost::multiprecision::mpf_float_50;

int main() {
    F a = 3, b = 2;
    F c = b - a;
    std::cout << "a:" << a << ", b:" << b << ", c:" << c << std::endl;

    b = abs(b - a);
    std::cout << "a:" << a << ", b:" << b << ", c:" << c << std::endl;
}

Prints

a:3, b:2, c:-1
a:3, b:1, c:-1

However, the number<> enables expression templates by default. That means, typeof(F{} - F{}) is not necessarily F , but something like:

namespace mp = boost::multiprecision;
using F      = mp::mpf_float_50;

int main() {
    F a = 3, b = 2;

    mp::detail::expression<mp::detail::subtract_immediates, F, F> //
        c = b - a;

Template expressions can greatly optimize some code, eg by simplifying evaluation of complicated expressions.

However, some generic code doesn't deal well with the expression templates. Therefore you can turn them off:

namespace mp = boost::multiprecision;
using F      = mp::number<mp::gmp_float<50>, mp::et_off>;

Now it all compiles, and probably works as it should.

Live On Coliru

#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
#include <iostream>
#include <boost/multiprecision/gmp.hpp>

namespace mp = boost::multiprecision;
using F      = mp::number<mp::gmp_float<50>, mp::et_off>;

int main() {
    std::vector<F> v(10);
    F              step(0.01);

    for (size_t i = 0; i < v.size(); ++i) {
        v.at(i) = sin(i * step);
    }

    F leftPoint(0.0);
    boost::math::interpolators::cardinal_cubic_b_spline<F> spline(v.begin(), v.end(), leftPoint, step);

    F x(3.1);
    F tmpVal = spline(x);
    std::cout << tmpVal << std::endl;
}

Now printing:

0.0449663

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM