*First problem - more precision* Check the stopping condition of boost.math, it says the tolerance is \sqrt{\epsilon}. So if you use 100-digits precision, then tolerance is roughly 10^-50. For more precision, you have to use more digits such as 1000 digits by using BF= number<cpp_dec_float<1000> >; . Full code:
#include<iostream> #include<boost/math/quadrature/tanh_sinh.hpp> #include <boost/multiprecision/cpp_dec_float.hpp> using namespace std; using namespace boost::math::quadrature; using namespace boost::multiprecision; using BF= number<cpp_dec_float<1000> >; int main(){ auto f2 = [](BF x) { return x/BF(sqrt(x*x-BF("0.25"))); }; tanh_sinh<BF> integrator; std::cout << std::setprecision(std::numeric_limits<BF>::max_digits10) << "Comp.: " << integrator.integrate(f2, BF("0.5"), sqrt(BF("1.25"))) << std::endl; return 0; }; Be patient, this run about 10 mins in my single core server. *Second problem - error* I didn't reproduce it. Just modify my code and everything is OK. On Fri, Aug 21, 2020 at 9:18 AM Anirban Pal via Boost-users < boost-users@lists.boost.org> wrote: > Thank you for your response. I’ve run into a few more issues with > accuracy. Here is my function, which has a singularity at 0.5 and I'm > integrating it from 0.5 to sqrt(1.25): > > using BF = boost::multiprecision::cpp_bin_float_100; > > auto f1 = [](BF x) { return x/BF(sqrt(x*x-BF("0.25"))); }; > BF Q1 = integrator.integrate(f1, BF("0.5"), BF(sqrt(BF("1.25")))); > > This gives me a value of Q1 which is close to the true value of 1 with an > error of O(10^-51). I am curious if this should be lower, like O(10^-100). > (I hope I’m not being greedy!) > > Nevertheless, if I try a related function. > > auto f2 = [](BF x) { return x/BF(sqrt(x*x-BF("0.25"))) - x; }; > BF Q2 = integrator.integrate(f2, BF("0.5"), BF(sqrt(BF("1.25")))); > > or an equivalent one: > > auto f3 = [](BF x) { return (x - x*BF(sqrt(x*x-BF("0.25"))) > )/BF(sqrt(x*x-BF("0.25"))); }; > BF Q3 = integrator.integrate(f3, BF("0.5"), BF(sqrt(BF("1.25")))); > > I get an error message: > > boost_test5: /usr/local/include/boost/math/quadrature/tanh_sinh.hpp:196: > boost::math::quadrature::tanh_sinh<Real, Policy>::integrate(F, Real, Real, > Real, Real*, Real*, std::size_t*)::<lambda(Real, Real)> [with F = main(int, > char**)::<lambda(BF)>; Real = > boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<100> > >; Policy = > boost::math::policies::policy<boost::math::policies::default_policy, > boost::math::policies::default_policy, boost::math::policies::default_policy, > boost::math::policies::default_policy, boost::math::policies::default_policy, > boost::math::policies::default_policy, boost::math::policies::default_policy, > boost::math::policies::default_policy, boost::math::policies::default_policy, > boost::math::policies::default_policy, > boost::math::policies::default_policy>; result_type = > boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<100> > >]: Assertion `position != a' failed. > Aborted (core dumped) > > I'm not sure how I could improve my code. I tried using > boost::multiprecision::sqrt but i didn't notice any difference. > > Thank you for your attention. > > > > On Mon, 17 Aug 2020 at 04:47, Paul A. Bristow via Boost-users > boost-users@lists.boost.org <http://mailto:boost-users@lists.boost.org> > wrote: > > >> >> > -----Original Message----- >> > From: Boost-users <boost-users-boun...@lists.boost.org> On Behalf Of >> John Maddock via Boost-users >> > Sent: 16 August 2020 21:24 >> > To: Anirban Pal via Boost-users <boost-users@lists.boost.org> >> > Cc: John Maddock <jz.madd...@googlemail.com> >> > Subject: Re: [Boost-users] limited accuracy for tanh-sinh integrator >> > >> > >> > On 16/08/2020 21:15, Anirban Pal via Boost-users wrote: >> > > >> > > Hello, >> > > >> > > I’m using the tanh-sinh integrator to integrate a simple function f(x) >> > > = 0.26*x from 3.0 to 4.0. >> > > The exact result is 0.91. With the integrator I’m getting a result >> > > accurate to only 10^-18 with cpp_bin_float_100 multiprecision. >> > > >> > You have the double precision constant 0.26 in your code, and since >> this is an inexact binary value, >> > everything that depends on that constant is inherently limited to >> double precision. Try constructing it >> > as Real(26) / 100. >> >> Everyone falls into this pit, and in my case, repeatedly ☹ >> >> You need to be ever vigilant not to use double precision items by mistake. >> >> Using numeric_limits<>::max_digits10 is useful because it shows the >> digits beyond double at about 17 decimal digits. Being random should raise >> suspicions. >> >> If you are only using multiprecision types, then always using decimal >> digit strings like "1.23456" is simple. >> >> If you can use a fraction like Real(1)/1000 that also works fine. >> >> You may also find the macro BOOST_MATH_TEST_VALUE in >> I:\boost\libs\math\test\test_value.hpp helpful if you want to make code >> portable over different floating-point types from fundamental to >> multiprecision? >> >> Paul >> >> >> _______________________________________________ >> Boost-users mailing list >> Boost-users@lists.boost.org >> https://lists.boost.org/mailman/listinfo.cgi/boost-users >> > -- > Anirban Pal > > > > _______________________________________________ > Boost-users mailing list > Boost-users@lists.boost.org > https://lists.boost.org/mailman/listinfo.cgi/boost-users >
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users