123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- [section:high_precision Using Boost.Math with High-Precision Floating-Point Libraries]
- The special functions, distributions, constants and tools in this library
- can be used with a number of high-precision libraries, including:
- * __multiprecision
- * __e_float
- * __NTL
- * __GMP
- * __MPFR
- * __gcc_quad_type
- * Intel _Quad type
- The last four have some license restrictions;
- only __multiprecision when using the `cpp_float` backend
- can provide an unrestricted [@http://www.boost.org/LICENSE_1_0.txt Boost] license.
- At present, the price of a free license is slightly lower speed.
- Of course, the main cost of higher precision is very much decreased
- (usually at least hundred-fold) computation speed, and big increases in memory use.
- Some libraries offer true
- [@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary-precision arithmetic]
- where the precision is limited only by available memory and compute time, but most are used
- at some arbitrarily-fixed precision, say 100 decimal digits, like __multiprecision `cpp_dec_float_100`.
- __multiprecision can operate in both ways, but the most popular choice is likely to be about a hundred
- decimal digits, though examples of computing about a million digits have been demonstrated.
- [section:why_high_precision Why use a high-precision library rather than built-in floating-point types?]
- For nearly all applications, the built-in floating-point types, `double`
- (and `long double` if this offers higher precision than `double`)
- offer enough precision, typically a dozen decimal digits.
- Some reasons why one would want to use a higher precision:
- * A much more precise result (many more digits) is just a requirement.
- * The range of the computed value exceeds the range of the type: factorials are the textbook example.
- * Using `double` is (or may be) too inaccurate.
- * Using `long double` (or may be) is too inaccurate.
- * Using an extended-precision type implemented in software as
- [@http://en.wikipedia.org/wiki/Double-double_(arithmetic)#Double-double_arithmetic double-double]
- ([@http://en.wikipedia.org/wiki/Darwin_(operating_system) Darwin]) is sometimes unpredictably inaccurate.
- * Loss of precision or inaccuracy caused by extreme arguments or
- [@http://en.wikipedia.org/wiki/Loss_of_significance cancellation errors].
- * An accuracy as good as possible for a chosen built-in floating-point type is required.
- * As a reference value, for example, to determine the inaccuracy
- of a value computed with a built-in floating point type,
- (perhaps even using some quick'n'dirty algorithm).
- The accuracy of many functions and distributions in Boost.Math has been measured in this way
- from tables of very high precision (up to 1000 decimal digits).
- Many functions and distributions have differences from exact values
- that are only a few least significant bits - computation noise.
- Others, often those for which analytical solutions are not available,
- require approximations and iteration:
- these may lose several decimal digits of precision.
- Much larger loss of precision can occur for [@http://en.wikipedia.org/wiki/Boundary_case boundary]
- or [@http://en.wikipedia.org/wiki/Corner_case corner cases],
- often caused by [@http://en.wikipedia.org/wiki/Loss_of_significance cancellation errors].
- (Some of the worst and most common examples of
- [@http://en.wikipedia.org/wiki/Loss_of_significance cancellation error or loss of significance]
- can be avoided by using __complements: see __why_complements).
- If you require a value which is as accurate as can be represented in the floating-point type,
- and is thus the
- [@https://en.wikipedia.org/wiki/Floating-point_arithmetic#Representable_numbers,_conversion_and_rounding closest representable value]
- correctly rounded to nearest,
- and has an error less than 1/2 a
- [@http://en.wikipedia.org/wiki/Least_significant_bit least significant bit] or
- [@http://en.wikipedia.org/wiki/Unit_in_the_last_place ulp]
- it may be useful to use a higher-precision type,
- for example, `cpp_dec_float_50`, to generate this value.
- Conversion of this value to a built-in floating-point type ('float', `double` or `long double`)
- will not cause any further loss of precision.
- A decimal digit string will also be 'read' precisely by the compiler
- into a built-in floating-point type to the nearest representable value.
- [note In contrast, reading a value from an `std::istream` into a built-in floating-point type
- is [*not guaranteed by the C++ Standard] to give the nearest representable value.]
- William Kahan coined the term
- [@http://en.wikipedia.org/wiki/Rounding#The_table-maker.27s_dilemma Table-Maker's Dilemma]
- for the problem of correctly rounding functions.
- Using a much higher precision (50 or 100 decimal digits)
- is a practical way of generating (almost always) correctly rounded values.
- [endsect] [/section:why_high_precision Why use a high-precision library rather than built-in floating-point types?]
- [section:use_multiprecision Using Boost.Multiprecision]
- [*All new projects are recommended to use __multiprecision.]
- [import ../../example/big_seventh.cpp]
- [big_seventh_example_1]
- [big_seventh_example_2]
- The full source of this example is at [@../../example/big_seventh.cpp big_seventh.cpp]
- [import ../../example/fft_sines_table.cpp]
- [fft_sines_table_example_1]
- [fft_sines_table_example_2]
- [fft_sines_table_example_3
- ]
- The table output is:
- [fft_sines_table_example_output]
- [fft_sines_table_example_check]
- The full source of this example is at [@../../example/fft_sines_table.cpp fft_sines_table.cpp]
- [/TODO another example needed here]
- [/import ../../example/ibeta_mp_example.cpp]
- [/ibeta_mp_example_1]
- [/The program output is:]
- [/ibeta_mp_output_1]
- [endsect] [/section:use_multiprecision Using Boost.Multiprecision]
- [section:float128 Using with GCC's __float128 datatype]
- At present support for GCC's native `__float128` datatype is extremely limited: the numeric constants
- will all work with that type, and that's about it. If you want to use the distributions or special
- functions then you will need to provide your own wrapper header that:
- * Provides `std::numeric_limits<__float128>` support.
- * Provides overloads of the standard library math functions for type `__float128`
- and which forward to the libquadmath equivalents.
- Ultimately these facilities should be provided by GCC and `libstdc++`.
- [endsect] [/section:float128 Using with GCC's __float128 datatype]
- [section:use_mpfr Using With MPFR or GMP - High-Precision Floating-Point Library]
- The special functions and tools in this library can be used with
- [@http://www.mpfr.org MPFR] (an arbitrary precision number type based on the __GMP),
- either via the bindings in [@../../../../boost/math/bindings/mpfr.hpp boost/math/bindings/mpfr.hpp],
- or via [@../../../../boost/math/bindings/mpfr.hpp boost/math/bindings/mpreal.hpp].
- [*New projects are recommended to use __multiprecision with GMP/MPFR backend instead.]
- In order to use these bindings you will need to have installed [@http://www.mpfr.org MPFR]
- plus its dependency the [@http://gmplib.org GMP library]. You will also need one of the
- two supported C++ wrappers for MPFR:
- [@http://math.berkeley.edu/~wilken/code/gmpfrxx/ gmpfrxx (or mpfr_class)],
- or [@http://www.holoborodko.com/pavel/mpfr/ mpfr-C++ (mpreal)].
- Unfortunately neither `mpfr_class` nor `mpreal` quite satisfy our conceptual requirements,
- so there is a very thin set of additional interfaces and some helper traits defined in
- [@../../../../boost/math/bindings/mpfr.hpp boost/math/bindings/mpfr.hpp] and
- [@../../../../boost/math/bindings/mpreal.hpp boost/math/bindings/mpreal.hpp]
- that you should use in place of including 'gmpfrxx.h' or 'mpreal.h' directly.
- The classes `mpfr_class` or `mpreal` are
- then usable unchanged once this header is included, so for example `mpfr_class`'s
- performance-enhancing expression templates are preserved and fully supported by this library:
- #include <boost/math/bindings/mpfr.hpp>
- #include <boost/math/special_functions/gamma.hpp>
- int main()
- {
- mpfr_class::set_dprec(500); // 500 bit precision
- //
- // Note that the argument to tgamma is
- // an expression template - that's just fine here.
- //
- mpfr_class v = boost::math::tgamma(sqrt(mpfr_class(2)));
- std::cout << std::setprecision(50) << v << std::endl;
- }
- Alternatively use with `mpreal` would look like:
- #include <boost/math/bindings/mpreal.hpp>
- #include <boost/math/special_functions/gamma.hpp>
- int main()
- {
- mpfr::mpreal::set_precision(500); // 500 bit precision
- mpfr::mpreal v = boost::math::tgamma(sqrt(mpfr::mpreal(2)));
- std::cout << std::setprecision(50) << v << std::endl;
- }
- There is a concept checking test program for mpfr support
- [@../../../../libs/math/test/mpfr_concept_check.cpp here] and
- [@../../../../libs/math/test/mpreal_concept_check.cpp here].
- [endsect] [/section:use_mpfr Using With MPFR / GMP - a High-Precision Floating-Point Library]
- [section:e_float Using e_float Library]
- __multiprecision was a development from the __e_float library by Christopher Kormanyos.
- e_float can still be used with Boost.Math library via the header:
- <boost/math/bindings/e_float.hpp>
- And the type `boost::math::ef::e_float`:
- this type is a thin wrapper class around ::e_float which provides the necessary
- syntactic sugar to make everything "just work".
- There is also a concept checking test program for e_float support
- [@../../../../libs/math/test/e_float_concept_check.cpp here].
- [*New projects are recommended to use __multiprecision with `cpp_float` backend instead.]
- [endsect] [/section:e_float Using e_float Library]
- [section:use_ntl Using NTL Library]
- [@http://shoup.net/ntl/doc/RR.txt NTL::RR]
- (an arbitrarily-fixed precision floating-point number type),
- can be used via the bindings in
- [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp].
- For details, see [@http://shoup.net/ntl/ NTL: A Library for doing Number Theory by
- Victor Shoup].
- [*New projects are recommended to use __multiprecision instead.]
- Unfortunately `NTL::RR` doesn't quite satisfy our conceptual requirements,
- so there is a very thin wrapper class `boost::math::ntl::RR` defined in
- [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp] that you
- should use in place of `NTL::RR`. The class is intended to be a drop-in
- replacement for the "real" NTL::RR that adds some syntactic sugar to keep
- this library happy, plus some of the standard library functions not implemented
- in NTL.
- For those functions that are based upon the __lanczos, the bindings
- defines a series of approximations with up to 61 terms and accuracy
- up to approximately 3e-113. This therefore sets the upper limit for accuracy
- to the majority of functions defined this library when used with `NTL::RR`.
- There is a concept checking test program for NTL support
- [@../../../../libs/math/test/ntl_concept_check.cpp here].
- [endsect] [/section:use_ntl Using With NTL - a High-Precision Floating-Point Library]
- [section:using_test Using without expression templates for Boost.Test and others]
- As noted in the __multiprecision documentation, certain program constructs will not compile
- when using expression templates. One example that many users may encounter
- is Boost.Test (1.54 and earlier) when using macro BOOST_CHECK_CLOSE and BOOST_CHECK_CLOSE_FRACTION.
- If, for example, you wish to use any multiprecision type like `cpp_dec_float_50`
- in place of `double` to give more precision,
- you will need to override the default `boost::multiprecision::et_on` with
- `boost::multiprecision::et_off`.
- [import ../../example/test_cpp_float_close_fraction.cpp]
- [expression_template_1]
- A full example code is at [@../../example/test_cpp_float_close_fraction.cpp test_cpp_float_close_fraction.cpp]
- [endsect] [/section:using_test Using without expression templates for Boost.Test and others]
- [endsect] [/section:high_precision Using With High-Precision Floating-Point Libraries]
- [section:real_concepts Conceptual Requirements for Real Number Types]
- The functions and statistical distributions in this library can be used with
- any type ['RealType] that meets the conceptual requirements given below. All
- the built-in floating-point types like `double` will meet these requirements.
- (Built-in types are also called __fundamental_types).
- User-defined types that meet the conceptual requirements can also be used.
- For example, with [link math_toolkit.high_precision.use_ntl a thin wrapper class]
- one of the types provided with [@http://shoup.net/ntl/ NTL (RR)] can be used.
- But now that __multiprecision library is available,
- this has become the preferred real-number type,
- typically __cpp_dec_float or __cpp_bin_float.
- Submissions of binding to other extended precision types would also still be welcome.
- The guiding principal behind these requirements is that a ['RealType]
- behaves just like a built-in floating-point type.
- [h4 Basic Arithmetic Requirements]
- These requirements are common to all of the functions in this library.
- In the following table /r/ is an object of type `RealType`, /cr/ and
- /cr2/ are objects
- of type `const RealType`, and /ca/ is an object of type `const arithmetic-type`
- (arithmetic types include all the built in integers and floating point types).
- [table
- [[Expression][Result Type][Notes]]
- [[`RealType(cr)`][RealType]
- [RealType is copy constructible.]]
- [[`RealType(ca)`][RealType]
- [RealType is copy constructible from the arithmetic types.]]
- [[`r = cr`][RealType&][Assignment operator.]]
- [[`r = ca`][RealType&][Assignment operator from the arithmetic types.]]
- [[`r += cr`][RealType&][Adds cr to r.]]
- [[`r += ca`][RealType&][Adds ar to r.]]
- [[`r -= cr`][RealType&][Subtracts cr from r.]]
- [[`r -= ca`][RealType&][Subtracts ca from r.]]
- [[`r *= cr`][RealType&][Multiplies r by cr.]]
- [[`r *= ca`][RealType&][Multiplies r by ca.]]
- [[`r /= cr`][RealType&][Divides r by cr.]]
- [[`r /= ca`][RealType&][Divides r by ca.]]
- [[`-r`][RealType][Unary Negation.]]
- [[`+r`][RealType&][Identity Operation.]]
- [[`cr + cr2`][RealType][Binary Addition]]
- [[`cr + ca`][RealType][Binary Addition]]
- [[`ca + cr`][RealType][Binary Addition]]
- [[`cr - cr2`][RealType][Binary Subtraction]]
- [[`cr - ca`][RealType][Binary Subtraction]]
- [[`ca - cr`][RealType][Binary Subtraction]]
- [[`cr * cr2`][RealType][Binary Multiplication]]
- [[`cr * ca`][RealType][Binary Multiplication]]
- [[`ca * cr`][RealType][Binary Multiplication]]
- [[`cr / cr2`][RealType][Binary Subtraction]]
- [[`cr / ca`][RealType][Binary Subtraction]]
- [[`ca / cr`][RealType][Binary Subtraction]]
- [[`cr == cr2`][bool][Equality Comparison]]
- [[`cr == ca`][bool][Equality Comparison]]
- [[`ca == cr`][bool][Equality Comparison]]
- [[`cr != cr2`][bool][Inequality Comparison]]
- [[`cr != ca`][bool][Inequality Comparison]]
- [[`ca != cr`][bool][Inequality Comparison]]
- [[`cr <= cr2`][bool][Less than equal to.]]
- [[`cr <= ca`][bool][Less than equal to.]]
- [[`ca <= cr`][bool][Less than equal to.]]
- [[`cr >= cr2`][bool][Greater than equal to.]]
- [[`cr >= ca`][bool][Greater than equal to.]]
- [[`ca >= cr`][bool][Greater than equal to.]]
- [[`cr < cr2`][bool][Less than comparison.]]
- [[`cr < ca`][bool][Less than comparison.]]
- [[`ca < cr`][bool][Less than comparison.]]
- [[`cr > cr2`][bool][Greater than comparison.]]
- [[`cr > ca`][bool][Greater than comparison.]]
- [[`ca > cr`][bool][Greater than comparison.]]
- [[`boost::math::tools::digits<RealType>()`][int]
- [The number of digits in the significand of RealType.]]
- [[`boost::math::tools::max_value<RealType>()`][RealType]
- [The largest representable number by type RealType.]]
- [[`boost::math::tools::min_value<RealType>()`][RealType]
- [The smallest representable number by type RealType.]]
- [[`boost::math::tools::log_max_value<RealType>()`][RealType]
- [The natural logarithm of the largest representable number by type RealType.]]
- [[`boost::math::tools::log_min_value<RealType>()`][RealType]
- [The natural logarithm of the smallest representable number by type RealType.]]
- [[`boost::math::tools::epsilon<RealType>()`][RealType]
- [The machine epsilon of RealType.]]
- ]
- Note that:
- # The functions `log_max_value` and `log_min_value` can be
- synthesised from the others, and so no explicit specialisation is required.
- # The function `epsilon` can be synthesised from the others, so no
- explicit specialisation is required provided the precision
- of RealType does not vary at runtime (see the header
- [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp]
- for an example where the precision does vary at runtime).
- # The functions `digits`, `max_value` and `min_value`, all get synthesised
- automatically from `std::numeric_limits`. However, if `numeric_limits`
- is not specialised for type RealType, then you will get a compiler error
- when code tries to use these functions, /unless/ you explicitly specialise them.
- For example if the precision of RealType varies at runtime, then
- `numeric_limits` support may not be appropriate, see
- [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp] for examples.
- [warning
- If `std::numeric_limits<>` is *not specialized*
- for type /RealType/ then the default float precision of 6 decimal digits
- will be used by other Boost programs including:
- Boost.Test: giving misleading error messages like
- ['"difference between {9.79796} and {9.79796} exceeds 5.42101e-19%".]
- Boost.LexicalCast and Boost.Serialization when converting the number
- to a string, causing potentially serious loss of accuracy on output.
- Although it might seem obvious that RealType should require `std::numeric_limits`
- to be specialized, this is not sensible for
- `NTL::RR` and similar classes where the [*number of digits is a runtime parameter]
- (whereas for `numeric_limits` everything has to be fixed at compile time).
- ]
- [h4 Standard Library Support Requirements]
- Many (though not all) of the functions in this library make calls
- to standard library functions, the following table summarises the
- requirements. Note that most of the functions in this library
- will only call a small subset of the functions listed here, so if in
- doubt whether a user-defined type has enough standard library
- support to be useable the best advise is to try it and see!
- In the following table /r/ is an object of type `RealType`,
- /cr1/ and /cr2/ are objects of type `const RealType`, and
- /i/ is an object of type `int`.
- [table
- [[Expression][Result Type]]
- [[`fabs(cr1)`][RealType]]
- [[`abs(cr1)`][RealType]]
- [[`ceil(cr1)`][RealType]]
- [[`floor(cr1)`][RealType]]
- [[`exp(cr1)`][RealType]]
- [[`pow(cr1, cr2)`][RealType]]
- [[`sqrt(cr1)`][RealType]]
- [[`log(cr1)`][RealType]]
- [[`frexp(cr1, &i)`][RealType]]
- [[`ldexp(cr1, i)`][RealType]]
- [[`cos(cr1)`][RealType]]
- [[`sin(cr1)`][RealType]]
- [[`asin(cr1)`][RealType]]
- [[`tan(cr1)`][RealType]]
- [[`atan(cr1)`][RealType]]
- [[`fmod(cr1)`][RealType]]
- [[`round(cr1)`][RealType]]
- [[`iround(cr1)`][int]]
- [[`trunc(cr1)`][RealType]]
- [[`itrunc(cr1)`][int]]
- ]
- Note that the table above lists only those standard library functions known to
- be used (or likely to be used in the near future) by this library.
- The following functions: `acos`, `atan2`, `fmod`, `cosh`, `sinh`, `tanh`, `log10`,
- `lround`, `llround`, `ltrunc`, `lltrunc` and `modf`
- are not currently used, but may be if further special functions are added.
- Note that the `round`, `trunc` and `modf` functions are not part of the
- current C++ standard: they are part of the additions added to C99 which will
- likely be in the next C++ standard. There are Boost versions of these provided
- as a backup, and the functions are always called unqualified so that
- argument-dependent-lookup can take place.
- In addition, for efficient and accurate results, a __lanczos is highly desirable.
- You may be able to adapt an existing approximation from
- [@../../../../boost/math/special_functions/lanczos.hpp
- boost/math/special_functions/lanczos.hpp] or
- [@../../../../boost/math/bindings/detail/big_lanczos.hpp
- boost/math/bindings/detail/big_lanczos.hpp]:
- in the former case you will need change
- `static_cast`'s to `lexical_cast`'s, and the constants to /strings/
- (in order to ensure the coefficients aren't truncated to `long doubl`e)
- and then specialise `lanczos_traits` for type T. Otherwise you may have to hack
- [@../../tools/lanczos_generator.cpp
- libs/math/tools/lanczos_generator.cpp] to find a suitable
- approximation for your RealType. The code will still compile if you don't do
- this, but both accuracy and efficiency will be somewhat compromised in any
- function that makes use of the gamma\/beta\/erf family of functions.
- [endsect] [/section:real_concepts Conceptual Requirements for Real Number Types]
- [section:dist_concept Conceptual Requirements for Distribution Types]
- A ['DistributionType] is a type that implements the following conceptual
- requirements, and encapsulates a statistical distribution.
- Please note that this documentation should not be used as a substitute
- for the
- [link math_toolkit.dist_ref reference documentation], and
- [link math_toolkit.stat_tut tutorial] of the statistical
- distributions.
- In the following table, ['d] is an object of type `DistributionType`,
- ['cd] is an object of type `const DistributionType` and ['cr] is an
- object of a type convertible to `RealType`.
- [table
- [[Expression][Result Type][Notes]]
- [[DistributionType::value_type][RealType]
- [The real-number type /RealType/ upon which the distribution operates.]]
- [[DistributionType::policy_type][RealType]
- [The __Policy to use when evaluating functions that depend on this distribution.]]
- [[d = cd][Distribution&][Distribution types are assignable.]]
- [[Distribution(cd)][Distribution][Distribution types are copy constructible.]]
- [[pdf(cd, cr)][RealType][Returns the PDF of the distribution.]]
- [[cdf(cd, cr)][RealType][Returns the CDF of the distribution.]]
- [[cdf(complement(cd, cr))][RealType]
- [Returns the complement of the CDF of the distribution,
- the same as: `1-cdf(cd, cr)`]]
- [[quantile(cd, cr)][RealType][Returns the quantile (or percentile) of the distribution.]]
- [[quantile(complement(cd, cr))][RealType]
- [Returns the quantile (or percentile) of the distribution, starting from
- the complement of the probability, the same as: `quantile(cd, 1-cr)`]]
- [[chf(cd, cr)][RealType][Returns the cumulative hazard function of the distribution.]]
- [[hazard(cd, cr)][RealType][Returns the hazard function of the distribution.]]
- [[kurtosis(cd)][RealType][Returns the kurtosis of the distribution.]]
- [[kurtosis_excess(cd)][RealType][Returns the kurtosis excess of the distribution.]]
- [[mean(cd)][RealType][Returns the mean of the distribution.]]
- [[mode(cd)][RealType][Returns the mode of the distribution.]]
- [[skewness(cd)][RealType][Returns the skewness of the distribution.]]
- [[standard_deviation(cd)][RealType][Returns the standard deviation of the distribution.]]
- [[variance(cd)][RealType][Returns the variance of the distribution.]]
- ]
- [endsect] [/ section:dist_concept Conceptual Requirements for Distribution Types]
- [section:archetypes Conceptual Archetypes for Reals and Distributions]
- There are a few concept archetypes available:
- * Real concept for floating-point types.
- * Distribution concept for statistical distributions.
- [h5:real_concept Real concept]
- `std_real_concept` is an archetype for theReal types,
- including the built-in float, double, long double.
- ``#include <boost/concepts/std_real_concept.hpp>``
- namespace boost{
- namespace math{
- namespace concepts
- {
- class std_real_concept;
- }
- }} // namespaces
- The main purpose in providing this type is to verify
- that standard library functions are found via a using declaration -
- bringing those functions into the current scope -
- and not just because they happen to be in global scope.
- In order to ensure that a call to say `pow` can be found
- either via argument dependent lookup, or failing that then
- in the std namespace: all calls to standard library functions
- are unqualified, with the std:: versions found via a `using` declaration
- to make them visible in the current scope. Unfortunately it's all
- to easy to forget the `using` declaration, and call the double version of
- the function that happens to be in the global scope by mistake.
- For example if the code calls ::pow rather than std::pow,
- the code will cleanly compile, but truncation of long doubles to
- double will cause a significant loss of precision.
- In contrast a template instantiated with std_real_concept will *only*
- compile if the all the standard library functions used have
- been brought into the current scope with a using declaration.
- [h6 Testing the real concept]
- There is a test program
- [@../../test/std_real_concept_check.cpp libs/math/test/std_real_concept_check.cpp]
- that instantiates every template in this library with type
- `std_real_concept` to verify its usage of standard library functions.
- ``#include <boost/math/concepts/real_concept.hpp>``
- namespace boost{
- namespace math{
- namespace concepts{
- class real_concept;
- }}} // namespaces
- `real_concept` is an archetype for
- [link math_toolkit.real_concepts user defined real types],
- it declares its standard library functions in its own
- namespace: these will only be found if they are called unqualified
- allowing argument dependent lookup to locate them. In addition
- this type is useable at runtime:
- this allows code that would not otherwise be exercised by the built-in
- floating point types to be tested. There is no std::numeric_limits<>
- support for this type, since numeric_limits is not a conceptual requirement
- for [link math_toolkit.real_concepts RealType]s.
- NTL RR is an example of a type meeting the requirements that this type
- models, but note that use of a thin wrapper class is required: refer to
- [link math_toolkit.high_precision.use_ntl "Using With NTL - a High-Precision Floating-Point Library"].
- There is no specific test case for type `real_concept`, instead, since this
- type is usable at runtime, each individual test case as well as testing
- `float`, `double` and `long double`, also tests `real_concept`.
- [h6:distribution_concept Distribution Concept]
- Distribution Concept models statistical distributions.
- ``#include <boost/math/concepts/distribution.hpp>``
- namespace boost{
- namespace math{
- namespace concepts
- {
- template <class RealType>
- class distribution_archetype;
- template <class Distribution>
- struct DistributionConcept;
- }}} // namespaces
- The class template `distribution_archetype` is a model of the
- [link math_toolkit.dist_concept Distribution concept].
- The class template `DistributionConcept` is a
- [@../../../../libs/concept_check/index.html concept checking class]
- for distribution types.
- [h6 Testing the distribution concept]
- The test program
- [@../../test/compile_test/distribution_concept_check.cpp distribution_concept_check.cpp]
- is responsible for using `DistributionConcept` to verify that all the
- distributions in this library conform to the
- [link math_toolkit.dist_concept Distribution concept].
- The class template `DistributionConcept` verifies the existence
- (but not proper function) of the non-member accessors
- required by the [link math_toolkit.dist_concept Distribution concept].
- These are checked by calls like
- v = pdf(dist, x); // (Result v is ignored).
- And in addition, those that accept two arguments do the right thing when the
- arguments are of different types (the result type is always the same as the
- distribution's value_type). (This is implemented by some additional
- forwarding-functions in derived_accessors.hpp, so that there is no need for
- any code changes. Likewise boilerplate versions of the
- hazard\/chf\/coefficient_of_variation functions are implemented in
- there too.)
- [endsect] [/section:archetypes Conceptual Archetypes for Reals and Distributions]
- [/
- Copyright 2006, 2010, 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).
- ]
|