File: mp_t.hpp

package info (click to toggle)
scipy 1.16.0-1exp7
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 234,820 kB
  • sloc: cpp: 503,145; python: 344,611; ansic: 195,638; javascript: 89,566; fortran: 56,210; cs: 3,081; f90: 1,150; sh: 848; makefile: 785; pascal: 284; csh: 135; lisp: 134; xml: 56; perl: 51
file content (71 lines) | stat: -rw-r--r-- 1,967 bytes parent folder | download | duplicates (18)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//  (C) Copyright John Maddock 2014.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_MATH_TOOLS_MP_T
#define BOOST_MATH_TOOLS_MP_T

#ifndef BOOST_MATH_PRECISION
#define BOOST_MATH_PRECISION 1000
#endif

#if defined(BOOST_MATH_USE_MPFR)

#include <boost/multiprecision/mpfr.hpp>

typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<BOOST_MATH_PRECISION *301L / 1000L> > mp_t;

#else

#include <boost/multiprecision/cpp_bin_float.hpp>

typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<BOOST_MATH_PRECISION, boost::multiprecision::digit_base_2> > mp_t;

#endif

inline mp_t ConvPrec(mp_t arg, int digits)
{
   int e1, e2;
   mp_t t = frexp(arg, &e1);
   t = frexp(floor(ldexp(t, digits + 1)), &e2);
   return ldexp(t, e1);
}

inline mp_t relative_error(mp_t a, mp_t b)
{
   mp_t min_val = boost::math::tools::min_value<mp_t>();
   mp_t max_val = boost::math::tools::max_value<mp_t>();

   if((a != 0) && (b != 0))
   {
      // mp_tODO: use isfinite:
      if(fabs(b) >= max_val)
      {
         if(fabs(a) >= max_val)
            return 0;  // one infinity is as good as another!
      }
      // If the result is denormalised, treat all denorms as equivalent:
      if((a < min_val) && (a > 0))
         a = min_val;
      else if((a > -min_val) && (a < 0))
         a = -min_val;
      if((b < min_val) && (b > 0))
         b = min_val;
      else if((b > -min_val) && (b < 0))
         b = -min_val;
      return (std::max)(fabs((a - b) / a), fabs((a - b) / b));
   }

   // Handle special case where one or both are zero:
   if(min_val == 0)
      return fabs(a - b);
   if(fabs(a) < min_val)
      a = min_val;
   if(fabs(b) < min_val)
      b = min_val;
   return (std::max)(fabs((a - b) / a), fabs((a - b) / b));
}


#endif // BOOST_MATH_TOOLS_MP_T