Boost.Math and Math Constants

Boost.Math has always had an inconspicuous collection of useful math constants, mainly those that are used internally. The presentation of these was as a function-template, called for example, as pi<double>(). using namespace boost::math::constants; return pi<Real>() * r * r; This leads to some rather ugly equations and is most unpopular with scientific and engineering users. John Maddock has now added a new cunning feature that allows the vast majority of users who just want a built-in double to get the constants quickly as plain variables. So in non-template code, users can write using boost::math::double_constants; double area = pi * r * r; and users can read the equations easily. (Float and long double are similarly available in their own namespaces). The original mechanism which can be used for higher multiprecision user-defined floating-point types appears unchanged but has been improved to work better with UDTs and high precision types. Some draft detailed docs about just these new proposals are at http://boost-sandbox.sourceforge.net/libs/math_constants/doc/html/index.html We would like to be sure that 1 This additional mechanism of presenting constants is acceptable. 2 It is acceptable to add more constants (current new list is about 60 constants). Are there important constants that you think we have missed? Do we need a mini-review? Other views? Paul PS 1 Are there important constants that you think we have missed? 2 Please tell me of mistakes and typos in the draft docs. --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

2011/12/7 Paul A. Bristow <pbristow@hetp.u-net.com>
Boost.Math has always had an inconspicuous collection of useful math constants, mainly those that are used internally.
The presentation of these was as a function-template, called for example, as pi<double>().
using namespace boost::math::constants; return pi<Real>() * r * r;
This leads to some rather ugly equations and is most unpopular with scientific and engineering users.
John Maddock has now added a new cunning feature that allows the vast majority of users who just want a built-in double to get the constants quickly as plain variables. So in non-template code, users can write
using boost::math::double_constants; double area = pi * r * r;
and users can read the equations easily.
(Float and long double are similarly available in their own namespaces).
I like this ;-)
The original mechanism which can be used for higher multiprecision user-defined floating-point types appears unchanged but has been improved to work better with UDTs and high precision types.
Some draft detailed docs about just these new proposals are at
http://boost-sandbox.sourceforge.net/libs/math_constants/doc/html/index.html
We would like to be sure that
1 This additional mechanism of presenting constants is acceptable.
2 It is acceptable to add more constants (current new list is about 60 constants).
Are there important constants that you think we have missed?
Do we need a mini-review?
Other views?
Paul
PS
1 Are there important constants that you think we have missed?
I'm not sure if these are important constants, but if there are: root_three, half_root_two, one_div_root_two, then I'd add: half_root_three, and one_dif_root_three.
2 Please tell me of mistakes and typos in the draft docs.
Regards Kris

On Wed, Dec 7, 2011 at 7:33 AM, Paul A. Bristow <pbristow@hetp.u-net.com>wrote:
Boost.Math has always had an inconspicuous collection of useful math constants, mainly those that are used internally.
The presentation of these was as a function-template, called for example, as pi<double>().
using namespace boost::math::constants; return pi<Real>() * r * r;
This leads to some rather ugly equations and is most unpopular with scientific and engineering users.
John Maddock has now added a new cunning feature that allows the vast majority of users who just want a built-in double to get the constants quickly as plain variables. So in non-template code, users can write
using boost::math::double_constants; double area = pi * r * r;
and users can read the equations easily.
(Float and long double are similarly available in their own namespaces).
It seems like this isn't a huge improvement over double const pi = boost::math::constants::pi< double >(); double area = pi * r * r; ...except when one wishes to use several constants (but I wouldn't think that would be all that common...). The original mechanism which can be used for higher multiprecision
user-defined floating-point types appears unchanged but has been improved to work better with UDTs and high precision types.
Some draft detailed docs about just these new proposals are at
http://boost-sandbox.sourceforge.net/libs/math_constants/doc/html/index.html
We would like to be sure that
1 This additional mechanism of presenting constants is acceptable.
2 It is acceptable to add more constants (current new list is about 60 constants).
Are there important constants that you think we have missed?
Do we need a mini-review?
Other views?
Paul
PS
1 Are there important constants that you think we have missed?
2 Please tell me of mistakes and typos in the draft docs.
I'll probably look over the draft docs when I get a chance. - Jeff

using boost::math::double_constants; double area = pi * r * r;
and users can read the equations easily.
(Float and long double are similarly available in their own namespaces).
It seems like this isn't a huge improvement over
double const pi = boost::math::constants::pi< double >(); double area = pi * r * r;
As a dyed in the wool C++'er I'd agree. But a previous review of a MathConstants lib by Paul failed because folks got very hot under the collar about this. Some folks needed constants that could be used in generic code, others were of the "over my dead body unless it's a constant variable in a header" persuasion. So we made both available. So <shrug> I guess. Hoping to avoid the flame wars this time around yours, John ;-)

On Wed, Dec 7, 2011 at 9:11 AM, John Maddock <boost.regex@virgin.net> wrote:
using boost::math::double_constants;
double area = pi * r * r;
and users can read the equations easily.
(Float and long double are similarly available in their own namespaces).
It seems like this isn't a huge improvement over
double const pi = boost::math::constants::pi< double >(); double area = pi * r * r;
As a dyed in the wool C++'er I'd agree.
But a previous review of a MathConstants lib by Paul failed because folks got very hot under the collar about this. Some folks needed constants that could be used in generic code, others were of the "over my dead body unless it's a constant variable in a header" persuasion. So we made both available. So <shrug> I guess.
Hoping to avoid the flame wars this time around yours, John ;-)
++<shrug>, then - Jeff

On 7-12-2011 16:33, Paul A. Bristow wrote:
Boost.Math has always had an inconspicuous collection of useful math constants, mainly those that are used internally.
The presentation of these was as a function-template, called for example, as pi<double>().
using namespace boost::math::constants; return pi<Real>() * r * r;
This leads to some rather ugly equations and is most unpopular with scientific and engineering users.
John Maddock has now added a new cunning feature that allows the vast majority of users who just want a built-in double to get the constants quickly as plain variables. So in non-template code, users can write
using boost::math::double_constants; double area = pi * r * r;
and users can read the equations easily.
Nice. But actually I need something else too. I don't think I mailed this earlier so I use this announcement to describe this additional wish/suggestion shortly. pi<Real>() is a macro/function, but there should be a structure behind. If I want to use a templated user defined type, such as ttmath (I'm a fan of that library), I'm stuck (unless I oversee something). Because it boost::math::constants::pi<T> cannot be partially specialized because it is a function. To solve this Boost.Geometry defines a small class: template <typename T> struct define_pi { static inline T apply() { // Default calls Boost.Math return boost::math::constants::pi<T>(); } }; and a utility function: template <typename T> inline T pi() { return detail::define_pi<T>::apply(); } The structure behing can then be perfectly specialized for ttmath: template <ttmath::uint Exponent, ttmath::uint Mantissa> struct define_pi<ttmath::Big<Exponent, Mantissa> > { static inline ttmath::Big<Exponent, Mantissa> apply() { static ttmath::Big<Exponent, Mantissa> const the_pi("3.1415etc" return the_pi; } }; This works. But Boost.Math would define this "define_pi" structure, or similar, this workaround would not be necessary... Is that feasable?
Some draft detailed docs about just these new proposals are at
http://boost-sandbox.sourceforge.net/libs/math_constants/doc/html/index.html
What is the SVN repos behind? At boost sandbox I assume? Thanks, Barend

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Barend Gehrels Sent: Wednesday, December 07, 2011 9:00 PM To: boost@lists.boost.org Subject: Re: [boost] Boost.Math and Math Constants
Some draft detailed docs about just these new proposals are at
http://boost-sandbox.sourceforge.net/libs/math_constants/doc/html/inde x.html
What is the SVN repos behind? At boost sandbox I assume?
SVN is troublesome to use for Quickbook (especially Doxygenated and indexed) generated files, because filenames keep changing, so I've found it more convenient to use sFTP to boost-sandbox.sourceforge.net. Takes load off the hard-pressed SVN server too. Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

Hi Paul,
Some draft detailed docs about just these new proposals are at
http://boost-sandbox.sourceforge.net/libs/math_constants/doc/html/inde x.html What is the SVN repos behind? At boost sandbox I assume? SVN is troublesome to use for Quickbook (especially Doxygenated and indexed) generated files, because filenames keep changing, so I've found it more convenient to use sFTP to boost-sandbox.sourceforge.net.
Takes load off the hard-pressed SVN server too.
Thanks, but I did mean the SVN repos for the C++ implementation. Docs are perfectly readable on sourceforge, no problem. Just looked again, yes, I like pi/180 and 180/pi there, we will use them. Great. Regards, Barend

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of John Maddock Sent: Friday, December 09, 2011 9:42 AM To: boost@lists.boost.org Subject: Re: [boost] Boost.Math and Math Constants
Thanks for all who contributed to this thread, especially an interesting idea to allow partial specialization (which we are thinking about - well actually, so far the organ grinder is ;-). But nobody has really answered this part of my original questions - "Does this change need a formal (mini-)review?"
From the responses, you seem to accept that the namespace floats additions are useful, and otherwise it is just increasing the list of constants that Boost.Math provides.
So can we take it that the answer is no review is needed? And that a larger collection of constants can just be added, probably to make release 1.50. Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

on Wed Dec 14 2011, "Paul A. Bristow" <pbristow-AT-hetp.u-net.com> wrote:
-----Original Message-----
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of John Maddock Sent: Friday, December 09, 2011 9:42 AM To: boost@lists.boost.org Subject: Re: [boost] Boost.Math and Math Constants
Thanks for all who contributed to this thread, especially an interesting idea to allow partial specialization (which we are thinking about - well actually, so far the organ grinder is ;-).
But nobody has really answered this part of my original questions -
"Does this change need a formal (mini-)review?"
The answer to that question is pretty much always "no." Changes of any scale are up to the library maintainer. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Nice. But actually I need something else too. I don't think I mailed this earlier so I use this announcement to describe this additional wish/suggestion shortly.
pi<Real>() is a macro/function, but there should be a structure behind. If I want to use a templated user defined type, such as ttmath (I'm a fan of that library), I'm stuck (unless I oversee something). Because it boost::math::constants::pi<T> cannot be partially specialized because it is a function.
Ah yes, the functions can only be fully specialized, and yes we could relatively easily add a struct layer in behind the function. John.

On 8-12-2011 11:19, John Maddock wrote:
Nice. But actually I need something else too. I don't think I mailed this earlier so I use this announcement to describe this additional wish/suggestion shortly.
pi<Real>() is a macro/function, but there should be a structure behind. If I want to use a templated user defined type, such as ttmath (I'm a fan of that library), I'm stuck (unless I oversee something). Because it boost::math::constants::pi<T> cannot be partially specialized because it is a function.
Ah yes, the functions can only be fully specialized, and yes we could relatively easily add a struct layer in behind the function.
That would be perfect! Thanks, Barend

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Barend Gehrels Sent: Thursday, December 08, 2011 7:22 PM To: boost@lists.boost.org Subject: Re: [boost] Boost.Math and Math Constants
On 8-12-2011 11:19, John Maddock wrote:
Nice. But actually I need something else too. I don't think I mailed this earlier so I use this announcement to describe this additional wish/suggestion shortly.
pi<Real>() is a macro/function, but there should be a structure behind. If I want to use a templated user defined type, such as ttmath (I'm a fan of that library), I'm stuck (unless I oversee something). Because it boost::math::constants::pi<T> cannot be partially specialized because it is a function.
Ah yes, the functions can only be fully specialized, and yes we could relatively easily add a struct layer in behind the function.
That would be perfect!
John has worked more macro magic, so that the effect a that Boost constant macro like BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884, 1971693993751058209749445923078164062862089986280348253421170679821480865, 0); for pi now generates a struct so partial specialization is now possible as Barend requested. The C++ that this produces is show below (and will be in the Boost.Math docs), but we'd just like to check that this meets your needs/suggestion. (An example of using this with ttmath would be nice for the docs? Could provide one?) Paul // Preprocessed pi constant, annotated. namespace boost { namespace math { namespace constants { namespace detail { template <class T> struct constant_pi { private: // Default implementations from string of decimal digits: static inline T get_from_string() { static const T result = detail::convert_from_string<T>("3.141592653589793238462643383279502884197169399375105820974944592307 81640628620899862803482534211706798214808651e+00", boost::is_convertible<const char*, T>()); return result; } template <int N> static T compute(); public: // Default implementations from string of decimal digits: static inline T get(const mpl::int_<construct_from_string>&) { constant_initializer<T, & constant_pi<T>::get_from_string >::do_nothing(); return get_from_string(); } // Float, double and long double versions: static inline T get(const mpl::int_<construct_from_float>) { return 3.141592653589793238462643383279502884e+00F; } static inline T get(const mpl::int_<construct_from_double>&) { return 3.141592653589793238462643383279502884e+00; } static inline T get(const mpl::int_<construct_from_long_double>&) { return 3.141592653589793238462643383279502884e+00L; } // For very high precision that is nonetheless can be calculated at compile time: template <int N> static inline T get(const mpl::int_<N>& n) { constant_initializer2<T, N, & constant_pi<T>::template compute<N> >::do_nothing(); return compute<N>(); } //For true arbitrary precision, which may well vary at runtime. static inline T get(const mpl::int_<0>&) { return tools::digits<T>() > max_string_digits ? compute<0>() : get(mpl::int_<construct_from_string>()); } }; // template <class T> struct constant_pi } // namespace detail // The actual forwarding function (including policy to control precision). template <class T, class Policy> inline T pi( ) { return detail:: constant_pi<T>::get(typename construction_traits<T, Policy>::type()); } // The actual forwarding function (using default policy to control precision). template <class T> inline T pi() { return pi<T, boost::math::policies::policy<> >() } } // namespace constants // Namespace specific versions, for the three built-in floats: namespace float_constants { static const float pi = 3.141592653589793238462643383279502884e+00F; } namespace double_constants { static const double pi = 3.141592653589793238462643383279502884e+00; } namespace long_double_constants { static const long double pi = 3.141592653589793238462643383279502884e+00L; } namespace constants{; } // namespace constants } // namespace math } // namespace boost

For what it's worth, I've been doing some experiments with constexpr in GCC and it's now possible to compute maximally-precise statically-initialized constants for any floating type via series expansion, at compile-time. Crazy stuff. on Fri Dec 16 2011, "Paul A. Bristow" <pbristow-AT-hetp.u-net.com> wrote:
-----Original Message-----
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Barend Gehrels Sent: Thursday, December 08, 2011 7:22 PM To: boost@lists.boost.org Subject: Re: [boost] Boost.Math and Math Constants
On 8-12-2011 11:19, John Maddock wrote:
Nice. But actually I need something else too. I don't think I mailed this earlier so I use this announcement to describe this additional wish/suggestion shortly.
pi<Real>() is a macro/function, but there should be a structure behind. If I want to use a templated user defined type, such as ttmath (I'm a fan of that library), I'm stuck (unless I oversee something). Because it boost::math::constants::pi<T> cannot be partially specialized because it is a function.
Ah yes, the functions can only be fully specialized, and yes we could relatively easily add a struct layer in behind the function.
That would be perfect!
John has worked more macro magic, so that the effect a that Boost constant macro like
BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884, 1971693993751058209749445923078164062862089986280348253421170679821480865, 0);
for pi now generates a struct so partial specialization is now possible as Barend requested.
The C++ that this produces is show below (and will be in the Boost.Math docs), but we'd just like to check that this meets your needs/suggestion.
(An example of using this with ttmath would be nice for the docs? Could provide one?)
Paul
// Preprocessed pi constant, annotated.
namespace boost { namespace math { namespace constants { namespace detail { template <class T> struct constant_pi { private: // Default implementations from string of decimal digits: static inline T get_from_string() { static const T result = detail::convert_from_string<T>("3.141592653589793238462643383279502884197169399375105820974944592307 81640628620899862803482534211706798214808651e+00", boost::is_convertible<const char*, T>()); return result; } template <int N> static T compute();
public: // Default implementations from string of decimal digits: static inline T get(const mpl::int_<construct_from_string>&) { constant_initializer<T, & constant_pi<T>::get_from_string >::do_nothing(); return get_from_string(); } // Float, double and long double versions: static inline T get(const mpl::int_<construct_from_float>) { return 3.141592653589793238462643383279502884e+00F; } static inline T get(const mpl::int_<construct_from_double>&) { return 3.141592653589793238462643383279502884e+00; } static inline T get(const mpl::int_<construct_from_long_double>&) { return 3.141592653589793238462643383279502884e+00L; } // For very high precision that is nonetheless can be calculated at compile time: template <int N> static inline T get(const mpl::int_<N>& n) { constant_initializer2<T, N, & constant_pi<T>::template compute<N> >::do_nothing(); return compute<N>(); } //For true arbitrary precision, which may well vary at runtime. static inline T get(const mpl::int_<0>&) { return tools::digits<T>() > max_string_digits ? compute<0>() : get(mpl::int_<construct_from_string>()); } }; // template <class T> struct constant_pi } // namespace detail
// The actual forwarding function (including policy to control precision). template <class T, class Policy> inline T pi( ) { return detail:: constant_pi<T>::get(typename construction_traits<T, Policy>::type()); } // The actual forwarding function (using default policy to control precision). template <class T> inline T pi() { return pi<T, boost::math::policies::policy<> >() } } // namespace constants
// Namespace specific versions, for the three built-in floats: namespace float_constants { static const float pi = 3.141592653589793238462643383279502884e+00F; } namespace double_constants { static const double pi = 3.141592653589793238462643383279502884e+00; } namespace long_double_constants { static const long double pi = 3.141592653589793238462643383279502884e+00L; } namespace constants{; } // namespace constants } // namespace math } // namespace boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Dave Abrahams BoostPro Computing http://www.boostpro.com

For what it's worth, I've been doing some experiments with constexpr in GCC and it's now possible to compute maximally-precise statically-initialized constants for any floating type via series expansion, at compile-time. Crazy stuff.
Crazy indeed - can you have loops in such code? Either way I'd love to see some example code if that's possible, Cheers, John.

on Sat Dec 17 2011, John Maddock <boost.regex-AT-virgin.net> wrote:
For what it's worth, I've been doing some experiments with constexpr in GCC and it's now possible to compute maximally-precise statically-initialized constants for any floating type via series expansion, at compile-time. Crazy stuff.
Crazy indeed - can you have loops in such code? Either way I'd love to see some example code if that's possible,
No, you have to use recursion. But you can use pointer indirections(!) I've got some examples lying about. https://gist.github.com/1457531#L33 demonstrates feasibility but I this is not the best way to calculate pi and plus I don't know how to tell where a 2d grid actually converges. It would be better to use Machin's formula, but was more interested in the challenge than in actually getting a good pi and I'm just out of time for playing around with it now. I can also show you a version that doesn't rely on memoization in the compiler (which GCC has) but instead builds its own linked-list containing a history of earlier values at compile-time. https://gist.github.com/1491172 Again, it has the same problem of not knowing how to tell where it has converged, but again, I was just interested in the challenge. Cheers, -- Dave Abrahams BoostPro Computing http://www.boostpro.com

We would like to be sure that 1 This additional mechanism of presenting constants is acceptable. 2 It is acceptable to add more constants (current new list is about 60 constants). Are there important constants that you think we have missed? ------------------------------------------------------------------- Looks like good work. I also use these constants frequently: one one_minus = -1 ten hundred thousand million billion trillion googol = 10^100 ln10, approx. 2.3025850929940456840179914546843642076011014886288 degree = pi / 180, approx., 0.017453292519943295769236907684886127134428718885417 khinchin, approx. 2.6854520010653064453097148354817956938203822939945 glaisher, approx. 1.2824271291006226368753425688697917277676889273250 Thank you. Best regards, Chris.

On Wed, Dec 07, 2011 at 09:03:26PM +0000, Christopher Kormanyos wrote:
billion trillion
Those are a horrible idea to attempt to define, as their meaning is ambigious - see http://en.wikipedia.org/wiki/Long_and_short_scales -- Lars Viklund | zao@acc.umu.se

On Wed, Dec 7, 2011 at 1:09 PM, Lars Viklund <zao@acc.umu.se> wrote:
On Wed, Dec 07, 2011 at 09:03:26PM +0000, Christopher Kormanyos wrote:
billion trillion
Those are a horrible idea to attempt to define, as their meaning is ambigious - see http://en.wikipedia.org/wiki/Long_and_short_scales
How about simply _1 _10 _100 ... then? *if* it's deemed desirable to have such constants in the first place. I.e., in what instances are the corresponding literals insufficient? - Jeff

Le 07/12/2011 22:15, Jeffrey Lee Hellrung, Jr. a écrit :
How about simply _1 _10 _100 ...
conflicts with mpl::_1, boost::_1 and all other lambda liekplacehodler
then? *if* it's deemed desirable to have such constants in the first place. I.e., in what instances are the corresponding literals insufficient?
Constant placeholder for integer make little sense, they make for real constant with non trivial vlaue and representation : pi, gold, etc ... In NT2 we decided to have everything a functor (constant included) and forward them to free function. This allow us to have both functionnal and object like interface for them.

On Wed, Dec 07, 2011 at 09:03:26PM +0000, Christopher Kormanyos wrote:
billion trillion
Those are a horrible idea to attempt to define, as their meaning is ambigious - see http://en.wikipedia.org/wiki/Long_and_short_scales
How about simply _1 _10 _100 ... then? *if* it's deemed desirable to have such constants in the first place. I.e., in what instances are the corresponding literals insufficient?
We decided not to add constants that were simple integers, if there's a good use case we could certainly add them though. John.

How about simply
_1 _10 _100 ... then? *if* it's deemed desirable to have such constants in the first place. I.e., in what instances are the corresponding literals insufficient?
We decided not to add constants that were simple integers, if there's a good use case we could certainly add them though.
-------------------------------------------------------------- I guess (1) would be better than one(). The only real use for them that I know is with non-built-in types that lack conversion to/from int. (This arises with explicit ctors, etc.) But since boost policy wants user-defined types to be convertible, the int (1) is better than the subroutine one(), etc. I guess this was a relic in my brain. Sorry. Best regards, Chris.

I guess (1) would be better than one().
The only real use for them that I know is with non-built-in types that lack conversion to/from int. (This arises with explicit ctors, etc.)
But since boost policy wants user-defined types to be convertible, the int (1) is better than the subroutine one(), etc.
I guess this was a relic in my brain.
I think we all have a few of those! :-) Actually, lets say we want to multiply a number by 10, the "best" method may vary by type: x * 10 Will likely be the most efficient method for types that support mutiplication by integer natively (for example MPFR), where as: x * ten<mybignum>() may be more efficient if using a literal would result in a temporary "mybignum" being constructed. Sadly nothing is ever as easy as it seems... John.

billion
trillion
Those are a horrible idea to attempt to define, as their meaning is ambigious - see http://en.wikipedia.org/wiki/Long_and_short_scales Lars Viklund | zao@acc.umu.se --------------------------------------------------------- I guess you're right. And they're not even enough to express national debts anymore, either.
participants (9)
-
Barend Gehrels
-
Christopher Kormanyos
-
Dave Abrahams
-
Jeffrey Lee Hellrung, Jr.
-
Joel Falcou
-
John Maddock
-
Krzysztof Czainski
-
Lars Viklund
-
Paul A. Bristow