123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- [mathpart constants..Mathematical Constants]
- [section:constants_intro Introduction]
- Boost.Math provides a collection of mathematical constants.
- [h4 Why use Boost.Math mathematical constants?]
- * Readable. For the very many jobs just using built-in like `double`, you can just write expressions like
- ``double area = pi * r * r;``
- (If that's all you want, jump direct to [link math_toolkit.tutorial.non_templ use in non-template code]!)
- * Effortless - avoiding a search of reference sources.
- * Usable with both builtin floating point types, and user-defined, possibly extended precision, types such as
- NTL, MPFR/GMP, mp_float: in the latter case the constants are computed to the necessary precision and then cached.
- * Accurate - ensuring that the values are as accurate as possible for the
- chosen floating-point type
- * No loss of accuracy from repeated rounding of intermediate computations.
- * Result is computed with higher precision and only rounded once.
- * Less risk of inaccurate result from functions pow, trig and log at [@http://en.wikipedia.org/wiki/Corner_case corner cases].
- * Less risk of [@http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html cancellation error].
- * Portable - as possible between different systems using different floating-point precisions:
- see [link math_toolkit.tutorial.templ use in template code].
- * Tested - by comparison with other published sources, or separately computed at long double precision.
- * Faster - can avoid (re-)calculation at runtime.
- * If the value returned is a builtin type then it's returned by value as a `constexpr` (C++11 feature, if available).
- * If the value is computed and cached (or constructed from a string representation and cached), then it's returned by constant reference.
- This can be
- significant if:
- * Functions pow, trig or log are used.
- * Inside an inner loop.
- * Using a high-precision UDT like __multiprecision.
- * Compiler optimizations possible with built-in types, especially `double`, are not available.
- [endsect] [/section:intro Introduction]
- [section:tutorial Tutorial]
- [section:non_templ Use in non-template code]
- When using the math constants at your chosen fixed precision in non-template code,
- you can simply add a `using namespace` declaration, for example,
- `using namespace boost::math::double_constants`,
- to make the constants of the correct precision for your code
- visible in the current scope, and then use each constant ['as a simple variable - sans brackets]:
- #include <boost/math/constants/constants.hpp>
- double area(double r)
- {
- using namespace boost::math::double_constants;
- return pi * r * r;
- }
- Had our function been written as taking a `float` rather than a `double`,
- we could have written instead:
- #include <boost/math/constants/constants.hpp>
- float area(float r)
- {
- using namespace boost::math::float_constants;
- return pi * r * r;
- }
- Likewise, constants that are suitable for use at `long double` precision
- are available in the namespace `boost::math::long_double_constants`.
- You can see the full list of available constants at [link math_toolkit.constants].
- Some examples of using constants are at [@../../example/constants_eg1.cpp constants_eg1].
- [endsect] [/section:non_templ Use in non-template code]
- [section:templ Use in template code]
- When using the constants inside a function template, we need to ensure that
- we use a constant of the correct precision for our template parameters.
- We can do this by calling the function-template versions, `pi<FPType>()`, of the constants
- like this:
- #include <boost/math/constants/constants.hpp>
- template <class Real>
- Real area(Real r)
- {
- using namespace boost::math::constants;
- return pi<Real>() * r * r;
- }
- Although this syntax is a little less "cute" than the non-template version,
- the code is no less efficient
- (at least for the built-in types `float`, `double` and `long double`) :
- the function template versions of the constants are simple inline functions that
- return a constant of the correct precision for the type used. In addition, these
- functions are declared `constexp` for those compilers that support this, allowing
- the result to be used in constant-expressions provided the template argument is a literal type.
- [tip Keep in mind the difference between the variable version,
- just `pi`, and the template-function version:
- the template-function requires both a <[~floating-point-type]>
- and function call `()` brackets, for example: `pi<double>()`.
- You cannot write `double p = pi<>()`, nor `double p = pi()`.]
- [note You can always use [*both] variable and template-function versions
- [*provided calls are fully qualified], for example:
- ``
- double my_pi1 = boost::math::constants::pi<double>();
- double my_pi2 = boost::math::double_constants::pi;
- ``
- ]
- [warning It may be tempting to simply define
- ``
- using namespace boost::math::double_constants;
- using namespace boost::math::constants;
- ``
- but if you do define two namespaces, this will, of course, create ambiguity!
- ``
- double my_pi = pi(); // error C2872: 'pi' : ambiguous symbol
- double my_pi2 = pi; // Context does not allow for disambiguation of overloaded function
- ``
- Although the mistake above is fairly obvious,
- it is also not too difficult to do this accidentally, or worse, create it in someone elses code.
- Therefore is it prudent to avoid this risk by [*localising the scope of such definitions], as shown above.]
- [tip Be very careful with the type provided as parameter.
- For example, providing an [*integer] instead of a floating-point type can be disastrous (a C++ feature).
- ``cout << "Area = " << area(2) << endl; // Area = 12!!!``
- You should get a compiler warning
- [pre
- warning : 'return' : conversion from 'double' to 'int', possible loss of data
- ] [/pre]
- Failure to heed this warning can lead to very wrong answers!
- You can also avoid this by being explicit about the type of `Area`.
- ``cout << "Area = " << area<double>(2) << endl; // Area = 12.566371``
- ]
- [endsect] [/section:templ Use in template code]
- [section:user_def Use With User-Defined Types]
- The most common example of a high-precision user-defined type will probably be __multiprecision.
- The syntax for using the function-call constants with user-defined types is the same
- as it is in the template class, which is to say we use:
- #include <boost/math/constants/constants.hpp>
- boost::math::constants::pi<UserDefinedType>();
- For example:
- boost::math::constants::pi<boost::multiprecision::cpp_dec_float_50>();
- giving [pi] with a precision of 50 decimal digits.
- However, since the precision of the user-defined type may be much greater than that
- of the built-in floating point types, how the value returned is created is as follows:
- * If the precision of the type is known at compile time:
- * If the precision is less than or equal to that of a `float` and the type is constructable from a `float`
- then our code returns a `float` literal. If the user-defined type is a literal type
- then the function call that returns the constant will be a `constexp`.
- * If the precision is less than or equal to that of a `double` and the type is constructable from a `double`
- then our code returns a `double` literal. If the user-defined type is a literal type
- then the function call that returns the constant will be a `constexp`.
- * If the precision is less than or equal to that of a `long double` and the type is constructable from a `long double`
- then our code returns a `long double` literal. If the user-defined type is a literal type
- then the function call that returns the constant will be a `constexp`.
- * If the precision is less than or equal to that of a `__float128` (and the compiler supports such a type)
- and the type is constructable from a `__float128`
- then our code returns a `__float128` literal. If the user-defined type is a literal type
- then the function call that returns the constant will be a `constexp`.
- * If the precision is less than 100 decimal digits, then the constant will be constructed
- (just the once, then cached in a thread-safe manner) from a string representation of the constant.
- In this case the value is returned as a const reference to the cached value.
- * Otherwise the value is computed (just once, then cached in a thread-safe manner).
- In this case the value is returned as a const reference to the cached value.
- * If the precision is unknown at compile time then:
- * If the runtime precision (obtained from a call to `boost::math::tools::digits<T>()`) is
- less than 100 decimal digits, then the constant is constructed "on the fly" from the string
- representation of the constant.
- * Otherwise the value is constructed "on the fly" by calculating then value of the constant
- using the current default precision of the type. Note that this can make use of the constants
- rather expensive.
- In addition, it is possible to pass a `Policy` type as a second template argument, and use this to control
- the precision:
- #include <boost/math/constants/constants.hpp>
- typedef boost::math::policies::policy<boost::math::policies::digits2<80> > my_policy_type;
- boost::math::constants::pi<MyType, my_policy_type>();
- [note Boost.Math doesn't know how to control the internal precision of `MyType`, the policy
- just controls how the selection process above is carried out, and the calculation precision
- if the result is computed.]
- It is also possible to control which method is used to construct the constant by specialising
- the traits class `construction_traits`:
- namespace boost{ namespace math{ namespace constant{
- template <class T, class Policy>
- struct construction_traits
- {
- typedef mpl::int_<N> type;
- };
- }}} // namespaces
- Where ['N] takes one of the following values:
- [table
- [[['N]][Meaning]]
- [[0][The precision is unavailable at compile time;
- either construct from a decimal digit string or calculate on the fly depending upon the runtime precision.]]
- [[1][Return a float precision constant.]]
- [[2][Return a double precision constant.]]
- [[3][Return a long double precision constant.]]
- [[4][Construct the result from the string representation, and cache the result.]]
- [[Any other value ['N]][Sets the compile time precision to ['N] bits.]]
- ]
- [h5 Custom Specializing a constant]
- In addition, for user-defined types that need special handling, it's possible to partially-specialize
- the internal structure used by each constant. For example, suppose we're using the C++ wrapper around MPFR
- `mpfr_class`: this has its own representation of Pi which we may well wish to use in place of the above
- mechanism. We can achieve this by specialising the class template `boost::math::constants::detail::constant_pi`:
- namespace boost{ namespace math{ namespace constants{ namespace detail{
- template<>
- struct constant_pi<mpfr_class>
- {
- template<int N>
- static mpfr_class get(const mpl::int_<N>&)
- {
- // The template param N is one of the values in the table above,
- // we can either handle all cases in one as is the case here,
- // or overload "get" for the different options.
- mpfr_class result;
- mpfr_const_pi(result.get_mpfr_t(), GMP_RNDN);
- return result;
- }
- };
- }}}} // namespaces
- [h5 Diagnosing what meta-programmed code is doing]
- Finally, since it can be tricky to diagnose what meta-programmed code is doing, there is a
- diagnostic routine that prints information about how this library will handle a specific type,
- it can be used like this:
- #include <boost/math/constants/info.hpp>
- int main()
- {
- boost::math::constants::print_info_on_type<MyType>();
- }
- If you wish, you can also pass an optional std::ostream argument to the `print_info_on_type` function.
- Typical output for a user-defined type looks like this:
- [pre
- Information on the Implementation and Handling of
- Mathematical Constants for Type class boost::math::concepts::real_concept
- Checking for std::numeric_limits<class boost::math::concepts::real_concept> specialisation: no
- boost::math::policies::precision<class boost::math::concepts::real_concept, Policy>
- reports that there is no compile type precision available.
- boost::math::tools::digits<class boost::math::concepts::real_concept>()
- reports that the current runtime precision is
- 53 binary digits.
- No compile time precision is available, the construction method
- will be decided at runtime and results will not be cached
- - this may lead to poor runtime performance.
- Current runtime precision indicates that
- the constant will be constructed from a string on each call.
- ]
- [endsect] [/section:user_def Use With User Defined Types]
- [endsect] [/section:tutorial Tutorial]
- [section:constants The Mathematical Constants]
- This section lists the mathematical constants, their use(s) (and sometimes rationale for their inclusion).
- [table Mathematical Constants
- [[name] [formula] [Value (6 decimals)] [Uses and Rationale]]
- [[[*Rational fractions]] [] [] [] ]
- [[half] [1/2] [0.5] [] ]
- [[third] [1/3] [0.333333] [] ]
- [[two_thirds] [2/3] [0.66667] [] ]
- [[three_quarters] [3/4] [0.75] [] ]
- [[[*two and related]] [] [] [] ]
- [[root_two] [[radic]2] [1.41421] [Equivalent to POSIX constant M_SQRT2] ]
- [[root_three] [[radic]3] [1.73205] [] ]
- [[half_root_two] [[radic]2 /2] [0.707106] [] ]
- [[ln_two] [ln(2)] [0.693147] [Equivalent to POSIX constant M_LN2] ]
- [[ln_ten] [ln(10)] [2.30258] [Equivalent to POSIX constant M_LN10] ]
- [[ln_ln_two] [ln(ln(2))] [-0.366512] [Gumbel distribution median] ]
- [[root_ln_four] [[radic]ln(4)] [1.177410] [] ]
- [[one_div_root_two] [1/[radic]2] [0.707106] [Equivalent to POSIX constant M_SQRT1_2] ]
- [[[*[pi] and related]] [] [] [] ]
- [[pi] [pi] [3.14159] [Ubiquitous. Archimedes constant [@http://en.wikipedia.org/wiki/Pi [pi]]. Equivalent to POSIX constant M_PI]]
- [[half_pi] [[pi]/2] [1.570796] [Equivalent to POSIX constant M_PI2] ]
- [[third_pi] [[pi]/3] [1.04719] [] ]
- [[quarter_pi] [[pi]/4] [0.78539816] [Equivalent to POSIX constant M_PI_4] ]
- [[sixth_pi] [[pi]/6] [0.523598] [] ]
- [[two_pi] [2[pi]] [6.28318] [Many uses, most simply, circumference of a circle]]
- [[two_thirds_pi] [2/3 [pi]] [2.09439] [[@http://en.wikipedia.org/wiki/Sphere#Volume_of_a_sphere volume of a hemi-sphere] = 4/3 [pi] r[cubed]]]
- [[three_quarters_pi] [3/4 [pi]] [2.35619] [ = 3/4 [pi] ]]
- [[four_thirds_pi] [4/3 [pi]] [4.18879] [[@http://en.wikipedia.org/wiki/Sphere#Volume_of_a_sphere volume of a sphere] = 4/3 [pi] r[cubed]]]
- [[one_div_two_pi] [1/(2[pi])] [1.59155] [Widely used]]
- [[root_pi] [[radic][pi]][1.77245] [Widely used]]
- [[root_half_pi] [[radic] [pi]/2] [1.25331] [Widely used]]
- [[root_two_pi][[radic] [pi]*2] [2.50662] [Widely used]]
- [[one_div_pi] [1/[pi]] [0.31830988] [Equivalent to POSIX constant M_1_PI] ]
- [[two_div_pi] [2/[pi]] [0.63661977] [Equivalent to POSIX constant M_2_PI] ]
- [[one_div_root_pi] [1/[radic][pi]] [0.564189] [] ]
- [[two_div_root_pi] [2/[radic][pi]] [1.128379] [Equivalent to POSIX constant M_2_SQRTPI] ]
- [[one_div_root_two_pi] [1/[radic](2[pi])] [0.398942] [] ]
- [[root_one_div_pi] [[radic](1/[pi]] [0.564189] [] ]
- [[pi_minus_three] [[pi]-3] [0.141593] [] ]
- [[four_minus_pi] [4 -[pi]] [0.858407] [] ]
- [[pi_pow_e] [[pi][super e]] [22.4591] [] ]
- [[pi_sqr] [[pi][super 2]] [9.86960] [] ]
- [[pi_sqr_div_six] [[pi][super 2]/6] [1.64493] [] ]
- [[pi_cubed] [[pi][super 3]] [31.00627] [] ]
- [[cbrt_pi] [[radic][super 3] [pi]] [1.46459] [] ]
- [[one_div_cbrt_pi] [1/[radic][super 3] [pi]] [0.682784] [] ]
- [[[*Euler's e and related]] [] [] [] ]
- [[e] [e] [2.71828] [[@http://en.wikipedia.org/wiki/E_(mathematical_constant) Euler's constant e], equivalent to POSIX constant M_E] ]
- [[exp_minus_half] [e [super -1/2]] [0.606530] [] ]
- [[e_pow_pi] [e [super [pi]]] [23.14069] [] ]
- [[root_e] [[radic] e] [1.64872] [] ]
- [[log10_e] [log10(e)] [0.434294] [Equivalent to POSIX constant M_LOG10E] ]
- [[one_div_log10_e] [1/log10(e)] [2.30258] [] ]
- [[log2_e] [log[sub 2](e)] [1.442695] [This is the same as 1/ln(2) and is equivalent to POSIX constant M_LOG2E] ]
- [[[*Trigonometric]] [] [] [] ]
- [[degree] [radians = [pi] / 180] [0.017453] [] ]
- [[radian] [degrees = 180 / [pi]] [57.2957] [] ]
- [[sin_one] [sin(1)] [0.841470] [] ]
- [[cos_one] [cos(1)] [0.54030] [] ]
- [[sinh_one] [sinh(1)] [1.17520] [] ]
- [[cosh_one] [cosh(1)] [1.54308] [] ]
- [[[*Phi]] [ Phidias golden ratio] [[@http://en.wikipedia.org/wiki/Golden_ratio Phidias golden ratio]] [] ]
- [[phi] [(1 + [radic]5) /2] [1.61803] [finance] ]
- [[ln_phi] [ln([phi])] [0.48121] [] ]
- [[one_div_ln_phi] [1/ln([phi])] [2.07808] [] ]
- [[[*Euler's Gamma]] [] [] [] ]
- [[euler] [euler] [0.577215] [[@http://en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant Euler-Mascheroni gamma constant]] ]
- [[one_div_euler] [1/euler] [1.73245] [] ]
- [[euler_sqr] [euler[super 2]] [0.333177] [] ]
- [[[*Misc]] [] [] [] ]
- [[zeta_two] [[zeta](2)] [1.64493] [[@http://en.wikipedia.org/wiki/Riemann_zeta_function Riemann zeta function]] ]
- [[zeta_three] [[zeta](3)] [1.20205] [[@http://en.wikipedia.org/wiki/Riemann_zeta_function Riemann zeta function]] ]
- [[catalan] [['K]] [0.915965] [[@http://mathworld.wolfram.com/CatalansConstant.html Catalan (or Glaisher) combinatorial constant] ]]
- [[glaisher] [['A]] [1.28242] [[@https://oeis.org/A074962/constant Decimal expansion of Glaisher-Kinkelin constant] ]]
- [[khinchin] [['k]] [2.685452] [[@https://oeis.org/A002210/constant Decimal expansion of Khinchin constant] ]]
- [[extreme_value_skewness] [12[radic]6 [zeta](3)/ [pi][super 3]] [1.139547] [Extreme value distribution] ]
- [[rayleigh_skewness] [2[radic][pi]([pi]-3)/(4 - [pi])[super 3/2]] [0.631110] [Rayleigh distribution skewness] ]
- [[rayleigh_kurtosis_excess] [-(6[pi][super 2]-24[pi]+16)/(4-[pi])[super 2]] [0.245089] [[@http://en.wikipedia.org/wiki/Rayleigh_distribution Rayleigh distribution kurtosis excess]] ]
- [[rayleigh_kurtosis] [3+(6[pi][super 2]-24[pi]+16)/(4-[pi])[super 2]] [3.245089] [Rayleigh distribution kurtosis] ]
- ] [/table]
- [note Integer values are [*not included] in this list of math constants, however interesting,
- because they can be so easily and exactly constructed, even for UDT, for example: `static_cast<cpp_float>(42)`.]
- [tip If you know the approximate value of the constant, you can search for the value to find Boost.Math chosen name in this table.]
- [tip Bernoulli numbers are available at __bernoulli_numbers.]
- [tip Factorials are available at __factorial.]
- [endsect] [/section:constants The constants]
- [section:new_const Defining New Constants]
- The library provides some helper code to assist in defining new constants;
- the process for defining a constant called `my_constant` goes like this:
- 1. [*Define a function that calculates the value of the constant].
- This should be a template function, and be placed in `boost/math/constants/calculate_constants.hpp`
- if the constant is to be added to this library,
- or else defined at the top of your source file if not.
- The function should look like this:
- namespace boost{ namespace math{ namespace constants{ namespace detail{
- template <class Real>
- template <int N>
- Real constant_my_constant<Real>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>))
- {
- int required_precision = N ? N : tools::digits<Real>();
- Real result = /* value computed to required_precision bits */ ;
- return result;
- }
- }}}} // namespaces
- Then define a placeholder for the constant itself:
- namespace boost{ namespace math{ namespace constants{
- BOOST_DEFINE_MATH_CONSTANT(my_constant, 0.0, "0");
- }}}
- For example, to calculate [pi]/2, add to `boost/math/constants/calculate_constants.hpp`
- template <class T>
- template<int N>
- inline T constant_half_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>))
- {
- BOOST_MATH_STD_USING
- return pi<T, policies::policy<policies::digits2<N> > >() / static_cast<T>(2);
- }
- Then to `boost/math/constants/constants.hpp` add:
- BOOST_DEFINE_MATH_CONSTANT(half_pi, 0.0, "0"); // Actual values are temporary, we'll replace them later.
- [note Previously defined constants like pi and e can be used, but by *not simply calling* `pi<T>()`;
- specifying the precision via the policy
- `pi<T, policies::policy<policies::digits2<N> > >()`
- is essential to ensure full accuracy.]
- [warning Newly defined constants can only be used once they are included in
- `boost/math/constants/constants.hpp`. So if you add
- `template <class T, class N> T constant_my_constant{...}`,
- then you cannot define `constant_my_constant`
- until you add the temporary `BOOST_DEFINE_MATH_CONSTANT(my_constant, 0.0, "0")`.
- Failing to do this will result in surprising compile errors:
- ``
- error C2143: syntax error : missing ';' before '<'
- error C2433: 'constant_root_two_div_pi' : 'inline' not permitted on data declarations
- error C2888: 'T constant_root_two_div_pi' : symbol cannot be defined within namespace 'detail'
- error C2988: unrecognizable template declaration/definition
- ``
- ]
- 2. [*You will need an arbitrary precision type to use to calculate the value]. This library
- currently supports either `cpp_float`, `NTL::RR` or `mpfr_class` used via the bindings in `boost/math/bindings`.
- The default is to use `NTL::RR` unless you define an alternate macro, for example,
- `USE_MPFR` or `USE_CPP_FLOAT` at the start of your program.
- 3. It is necessary to link to the Boost.Regex library,
- and probably to your chosen arbitrary precision type library.
- 4. You need to add `libs\math\include_private` to your compiler's include path as the needed
- header is not installed in the usual places by default (this avoids a cyclic dependency between
- the Math and Multiprecision library's headers).
- 5. The complete program to generate the constant `half_pi` using function `calculate_half_pi` is then:
- #define USE_CPP_FLOAT // If required.
- #include <boost/math/constants/generate.hpp>
- int main()
- {
- BOOST_CONSTANTS_GENERATE(half_pi);
- }
- The output from the program is a snippet of C++ code
- (actually a macro call) that can be cut and pasted
- into `boost/math/constants/constants.hpp` or else into your own code, for example:
- [pre
- BOOST_DEFINE_MATH_CONSTANT(half_pi, 1.570796326794896619231321691639751442e+00, "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326e+00");
- ]
- This macro BOOST_DEFINE_MATH_CONSTANT inserts a C++ struct code snippet that
- declares the `float`, `double` and `long double` versions of the constant,
- plus a decimal digit string representation correct to 100 decimal
- digits, and all the meta-programming machinery needed to select between them.
- The result of an expanded macro for Pi is shown below.
- [import ./pp_pi.hpp]
- [preprocessed_pi]
- [endsect] [/section:new_const Defining New Constants]
- [section:constants_faq Math Constants FAQs]
- [h4 Why are ['these] Constants Chosen?]
- It is, of course, impossible to please everyone with a list like this.
- Some of the criteria we have used are:
- * Used in Boost.Math.
- * Commonly used.
- * Expensive to compute.
- * Requested by users.
- * [@http://en.wikipedia.org/wiki/Mathematical_constant Used in science and mathematics.]
- * No integer values (because so cheap to construct).
- (You can easily define your own if found convenient, for example: `FPT one =static_cast<FPT>(42);`).
- [h4 How are constants named?]
- * Not macros, so no upper case.
- * All lower case (following C++ standard names).
- * No CamelCase.
- * Underscore as _ delimiter between words.
- * Numbers spelt as words rather than decimal digits (except following pow).
- * Abbreviation conventions:
- * root for square root.
- * cbrt for cube root.
- * pow for pow function using decimal digits like pow23 for n[super 2/3].
- * div for divided by or operator /.
- * minus for operator -, plus for operator +.
- * sqr for squared.
- * cubed for cubed n[super 3].
- * words for greek, like [pi], [zeta] and [Gamma].
- * words like half, third, three_quarters, sixth for fractions. (Digit(s) can get muddled).
- * log10 for log[sub 10]
- * ln for log[sub e]
- [h4 How are the constants derived?]
- The constants have all been calculated using high-precision software working
- with up to 300-bit precision giving about 100 decimal digits.
- (The precision can be arbitrarily chosen and is limited only by compute time).
- [h4 How Accurate are the constants?]
- The minimum accuracy chosen (100 decimal digits) exceeds the
- accuracy of reasonably-foreseeable floating-point hardware (256-bit)
- and should meet most high-precision computations.
- [h4 How are the constants tested?]
- # Comparison using Boost.Test BOOST_CHECK_CLOSE_FRACTION using long double literals,
- with at least 35 decimal digits, enough to be accurate for all long double implementations.
- The tolerance is usually twice `long double epsilon`.
- # Comparison with calculation at long double precision.
- This often requires a slightly higher tolerance than two epsilon
- because of computational noise from round-off etc,
- especially when trig and other functions are called.
- # Comparison with independent published values,
- for example, using [@http://oeis.org/ The On-Line Encyclopedia of Integer Sequences (OEIS)]
- again using at least 35 decimal digits strings.
- # Comparison with independely calculated values using arbitrary precision tools like
- [@http://www.wolfram.com/mathematica/ Mathematica], again using at least 35 decimal digits literal strings.
- [warning We have not yet been able to [*check] that
- [*all] constants are accurate at the full arbitrary precision,
- at present 100 decimal digits.
- But certain key values like `e` and `pi` appear to be accurate
- and internal consistencies suggest that others are this accurate too.
- ]
- [h4 Why is Portability important?]
- Code written using math constants is easily portable even when using different
- floating-point types with differing precision.
- It is a mistake to expect that results of computations will be [*identical], but
- you can achieve the [*best accuracy possible for the floating-point type in use].
- This has no extra cost to the user, but reduces irritating,
- and often confusing and very hard-to-trace effects,
- caused by the intrinsically limited precision of floating-point calculations.
- A harmless symptom of this limit is a spurious least-significant digit;
- at worst, slightly inaccurate constants sometimes cause iterating algorithms
- to diverge wildly because internal comparisons just fail.
- [h4 What is the Internal Format of the constants, and why?]
- See [link math_toolkit.tutorial tutorial] above for normal use,
- but this FAQ explains the internal details used for the constants.
- Constants are stored as 100 decimal digit values.
- However, some compilers do not accept decimal digits strings as long as this.
- So the constant is split into two parts, with the first containing at least
- 128-bit long double precision (35 decimal digits),
- and for consistency should be in scientific format with a signed exponent.
- The second part is the value of the constant expressed as a string literal,
- accurate to at least 100 decimal digits (in practice that means at least 102 digits).
- Again for consistency use scientific format with a signed exponent.
- For types with precision greater than a long double,
- then if T is constructible `T `is constructible from a `const char*`
- then it's directly constructed from the string,
- otherwise we fall back on lexical_cast to convert to type `T`.
- (Using a string is necessary because you can't use a numeric constant
- since even a `long double` might not have enough digits).
- So, for example, a constant like pi is internally defined as
- BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00");
- In this case the significand is 109 decimal digits, ensuring 100 decimal digits are exact, and exponent is zero.
- See [link math_toolkit.new_const defining new constants] to calculate new constants.
- A macro definition like this can be pasted into user code where convenient,
- or into `boost/math/constants.hpp` if it is to be added to the Boost.Math library.
- [h4 What Floating-point Types could I use?]
- Apart from the built-in floating-point types `float`, `double`, `long double`,
- there are several arbitrary precision floating-point classes available,
- but most are not licensed for commercial use.
- [h5 Boost.Multiprecision by Christopher Kormanyos]
- This work is based on an earlier work called e-float:
- Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations,
- in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011.
- [@http://doi.acm.org/10.1145/1916461.1916469]
- [@https://svn.boost.org/svn/boost/sandbox/e_float/ e_float]
- but is now re-factored and available under the Boost license in the Boost-sandbox at
- [@https://svn.boost.org/svn/boost/sandbox/multiprecision/ multiprecision]
- where it is being refined and prepared for review.
- [h5 Boost.cpp_float by John Maddock using Expression Templates]
- [@https://svn.boost.org/svn/boost/sandbox/big_number/ Big Number]
- which is a reworking of [@https://svn.boost.org/svn/boost/sandbox/e_float/ e_float]
- by Christopher Kormanyos to use expression templates for faster execution.
- [h5 NTL class quad_float]
- [@http://shoup.net/ntl/ NTL] by Victor Shoup has fixed and arbitrary high precision fixed and floating-point types.
- However none of these are licenced for commercial use.
- #include <NTL/quad_float.h> // quad precision 106-bit, about 32 decimal digits.
- using NTL::to_quad_float; // Less precise than arbitrary precision NTL::RR.
- NTL class `quad_float`, which gives a form of quadruple precision,
- 106-bit significand (but without an extended exponent range.)
- With an IEC559/IEEE 754 compatible processor,
- for example Intel X86 family, with 64-bit double, and 53-bit significand,
- using the significands of [*two] 64-bit doubles,
- if `std::numeric_limits<double>::digits10` is 16,
- then we get about twice the precision,
- so `std::numeric_limits<quad_float>::digits10()` should be 32.
- (the default `std::numeric_limits<RR>::digits10()` should be about 40).
- (which seems to agree with experiments).
- We output constants (including some noisy bits,
- an approximation to `std::numeric_limits<RR>::max_digits10()`)
- by adding 2 or 3 extra decimal digits, so using `quad_float::SetOutputPrecision(32 + 3);`
- Apple Mac/Darwin uses a similar ['doubledouble] 106-bit for its built-in `long double` type.
- [note The precision of all `doubledouble` floating-point types is rather odd and values given are only approximate.]
- [*New projects should use __multiprecision.]
- [h5 NTL class RR]
- Arbitrary precision floating point with NTL class RR,
- default is 150 bit (about 50 decimal digits)
- used here with 300 bit to output 100 decimal digits,
- enough for many practical non-'number-theoretic' C++ applications.
- __NTL is [*not licenced for commercial use].
- This class is used in Boost.Math and is an option when using big_number projects to calculate new math constants.
- [*New projects should use __multiprecision.]
- [h5 GMP and MPFR]
- [@http://gmplib.org GMP] and [@http://www.mpfr.org/ MPFR] have also been used to compute constants,
- but are licensed under the [@http://www.gnu.org/copyleft/lesser.html Lesser GPL license]
- and are [*not licensed for commercial use].
- [h4 What happened to a previous collection of constants proposed for Boost?]
- A review concluded that the way in which the constants were presented did not meet many peoples needs.
- None of the methods proposed met many users' essential requirement to allow writing simply `pi` rather than `pi()`.
- Many science and engineering equations look difficult to read when because function call brackets can be confused
- with the many other brackets often needed. All the methods then proposed of avoiding the brackets failed to meet all needs,
- often on grounds of complexity and lack of applicability to various realistic scenarios.
- So the simple namespace method, proposed on its own, but rejected at the first review,
- has been added to allow users to have convenient access to float, double and long double values,
- but combined with template struct and functions to allow simultaneous use
- with other non-built-in floating-point types.
- [h4 Why do the constants (internally) have a struct rather than a simple function?]
- A function mechanism was provided by in previous versions of Boost.Math.
- The new mechanism is to permit partial specialization. See Custom Specializing a constant above.
- It should also allow use with other packages like [@http://www.ttmath.org/ ttmath Bignum C++ library.]
- [h4 Where can I find other high precision constants?]
- # Constants with very high precision and good accuracy (>40 decimal digits)
- from Simon Plouffe's web based collection [@http://pi.lacim.uqam.ca/eng/].
- # [@https://oeis.org/ The On-Line Encyclopedia of Integer Sequences (OEIS)]
- # Checks using printed text optically scanned values and converted from:
- D. E. Knuth, Art of Computer Programming, Appendix A, Table 1, Vol 1, ISBN 0 201 89683 4 (1997)
- # M. Abrahamovitz & I. E. Stegun, National Bureau of Standards, Handbook of Mathematical Functions,
- a reference source for formulae now superceded by
- # Frank W. Olver, Daniel W. Lozier, Ronald F. Boisvert, Charles W. Clark, NIST Handbook of Mathemetical Functions, Cambridge University Press, ISBN 978-0-521-14063-8, 2010.
- # John F Hart, Computer Approximations, Kreiger (1978) ISBN 0 88275 642 7.
- # Some values from Cephes Mathematical Library, Stephen L. Moshier
- and CALC100 100 decimal digit Complex Variable Calculator Program, a DOS utility.
- # Xavier Gourdon, Pascal Sebah, 50 decimal digits constants at [@http://numbers.computation.free.fr/Constants/constants.html Number, constants and computation].
- [h4 Where are Physical Constants?]
- Not here in this Boost.Math collection, because physical constants:
- * Are measurements, not truely constants.
- * Are not truly constant and keeping changing as mensuration technology improves.
- * Have a instrinsic uncertainty.
- * Mathematical constants are stored and represented at varying precision, but should never be inaccurate.
- Some physical constants may be available in Boost.Units.
- [endsect] [/section:FAQ FAQ]
- [endmathpart] [/section:constants Mathematical Constants]
- [/
- Copyright 2012 John Maddock and Paul A. Bristow.
- Distributed under 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).
- ]
|