Boost logo

Boost :

Subject: Re: [boost] Numeric constants
From: Brandon Kohn (blkohn_at_[hidden])
Date: 2009-01-30 15:02:08


> From: "John Maddock" <john_at_[hidden]>
> Currently with Boost.Math if you call:
>
> pi<my_UDT>()
>
> then internally it does a lexical_cast from a string containing ~100
> decimal digits to my_UDT. The resulting value is cached for performance
> reasons, but of course that's not thread safe, although it could be made
> so (still on the TODO list though). So unless my_UDT supports an
> unfeasably large number of digits, you should get pi to the full precision
> of your type. We currently use this with both NTL::RR and mpfr_class (2
> arbitrary precision types), and it works very well. Obviously there are
> float/double/long double specialisations that just return the numeric
> constant directly (with appropriate suffix). And finally don't forget
> that you could add user-defined full specialisations of the templates for
> my_UDT if my_UDT provides it's own interfaces to various constants.
>
> John.

I played around with this type of idea in the geometry code I've been
working on. In my case I wanted to support any kind of type as well as
rational types (for which even a 100 decimal pi might be considered poor
resolution?). I've never really worked in a domain requiring this high of a
precision for pi.. but figured it was fun to give it a whirl.

One use case for such a thing would be if you are using integral types
for defining the geometry but still need to work with some constants like
PI (in very high precisions).

So for an example I had a specialization say for an arbitrary big int type
(with a traits specialization to limit the precision to something ....
mortal):

template <>
struct constants<my_big_int>
{
  typedef my_big_int int_type;
  typedef rational_promotion_traits< int_type >::rational_type
rational_type;

  //! \brief Calculate the required digits of pi for type my_big_int.
  static inline rational_type pi()
  {
      //! Calculate PI to the required precision using a spigot algorithm.
      static rational_type _pi = detail::calculate_pi< rational_type,
                                numeric_traits< int_type >::precision
>::pi();
      return _pi;
  }
};

And voila, I had a means to use a tailor fit approximation of PI with my
integral geometry types. I always figured this really didn't belong to the
geometry code.. and that it should be factored out and into a more general
numeric library (but there wasn't one that I saw at the time). Would
Boost.Math already have a facility covering this use case?

Cheers,

Brandon
 


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk