mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	
		
			
	
	
		
			637 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			637 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | [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 | ||
|  | * __float128 | ||
|  | 
 | ||
|  | 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 cancellation error. | ||
|  | * 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 closest representable value 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] | ||
|  | 
 | ||
|  | [import ../../example/fft_sines_table.cpp] | ||
|  | 
 | ||
|  | [fft_sines_table_example_1] | ||
|  | 
 | ||
|  | The table output is: | ||
|  | 
 | ||
|  | [fft_sines_table_example_output] | ||
|  | 
 | ||
|  | [fft_sines_table_example_check] | ||
|  | 
 | ||
|  | 
 | ||
|  | [/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 function for type `__float128`and which forward to the libquadmath equivalents. | ||
|  | 
 | ||
|  | Ultimately these facilities should be provided by GCC and `libstdc++`. | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [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; | ||
|  |    } | ||
|  | 
 | ||
|  | 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 either `mpfr_class` or `mpreal`. | ||
|  | 
 | ||
|  | 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 greatly 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). | ||
|  | ] | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 |