[section:use_ntl Using With NTL - a High-Precision Floating-Point Library]

The special functions and tools in this library can be used with
[@http://shoup.net/ntl/doc/RR.txt NTL::RR (an arbitrary precision number type)],
via the bindings in [@../../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp].
[@http://shoup.net/ntl/ See also NTL: A Library for doing Number Theory by 
Victor Shoup]

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.

Finally there is a high precision __lanczos suitable for use with `boost::math::ntl::RR`,
used at 1000-bit precision in 
[@../../../tools/ntl_rr_lanczos.hpp libs/math/tools/ntl_rr_lanczos.hpp].  
The approximation has a theoretical precision of > 90 decimal digits, 
and an experimental precision of > 100 decimal digits.  To use that 
approximation, just include that header before any of the special 
function headers (if you don't use it, you'll get a slower, but
fully generic implementation for all of the gamma-like functions).

[endsect][/section:use_ntl Using With NTL - a High Precision Floating-Point Library]

[section: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 will meet these requirements.  
User defined types that meet the requirements can also be used.  For example,
with [link math_toolkit.using_udt.use_ntl a thin wrapper class] one of the types 
provided with [@http://shoup.net/ntl/ NTL (RR)] can be used.  Submissions
of binding to other extended precision types would also be most 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 (where as for `numeric_limits` it 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]]
]

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`, `modf` and `log10`
are not currently used, but may be if further special functions are added.

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
[@../../../tools/ntl_rr_lanczos.hpp libs/math/tools/ntl_rr_lanczos.hpp]: 
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 double)
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: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.dist_ref reference documentation], and 
[link math_toolkit.dist.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 of the distribution.]]
[[quantile(complement(cd, cr))][RealType]
      [Returns the quantile 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:archetypes Conceptual Archetypes and Testing]

There are several concept archetypes available:

``#include <boost/concepts/std_real_concept.hpp>``

   namespace boost{
   namespace math{
   namespace concepts{
   
   class std_real_concept;
   
   }}} // namespaces

`std_real_concept` is an archetype for the built-in Real types.

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.

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 it's 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.using_udt.concepts 
user defined real types], it
declares it's standard library functions in it's 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 this is not a conceptual requirement
for [link math_toolkit.using_udt.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.using_udt.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`.

``#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.using_udt.dist_concept Distribution concept].

The class template `DistributionConcept` is a 
[@../../../../../libs/concept_check/index.html concept checking class] 
for distribution types.

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.using_udt.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.using_udt.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 and Testing]


[/ 
  Copyright 2006 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).
]



