mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 12:30:23 -04:00 
			
		
		
		
	
		
			
	
	
		
			898 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			898 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | 
 | ||
|  | [mathpart policy Policies: Controlling Precision, Error Handling etc] | ||
|  | 
 | ||
|  | [section:pol_overview Policy Overview] | ||
|  | [policy_overview] | ||
|  | [endsect] [/section:pol_overview Policy Overview] | ||
|  | 
 | ||
|  | [include policy_tutorial.qbk] | ||
|  | 
 | ||
|  | [section:pol_ref Policy Reference] | ||
|  | 
 | ||
|  | [section:error_handling_policies Error Handling Policies] | ||
|  | 
 | ||
|  | There are two orthogonal aspects to error handling: | ||
|  | 
 | ||
|  | * What to do (if anything) with the error. | ||
|  | * What kind of error is being raised. | ||
|  | 
 | ||
|  | [h4 Available Actions When an Error is Raised] | ||
|  | 
 | ||
|  | What to do with the error is encapsulated by an enumerated type: | ||
|  | 
 | ||
|  |    namespace boost { namespace math { namespace policies { | ||
|  |     | ||
|  |    enum error_policy_type | ||
|  |    { | ||
|  |       throw_on_error = 0, // throw an exception. | ||
|  |       errno_on_error = 1, // set ::errno & return 0, NaN, infinity or best guess. | ||
|  |       ignore_error = 2, // return 0, NaN, infinity or best guess. | ||
|  |       user_error = 3  // call a user-defined error handler. | ||
|  |    }; | ||
|  | 
 | ||
|  |    }}} // namespaces | ||
|  |     | ||
|  | The various enumerated values have the following meanings: | ||
|  | 
 | ||
|  | [h5 throw_on_error] | ||
|  | 
 | ||
|  | Will throw one of the following exceptions, depending upon the | ||
|  |  type of the error: | ||
|  |     [table | ||
|  |        [[Error Type][Exception]] | ||
|  |        [[Domain Error][std::domain_error]] | ||
|  |        [[Pole Error][std::domain_error]] | ||
|  |        [[Overflow Error][std::overflow_error]] | ||
|  |        [[Underflow Error][std::underflow_error]] | ||
|  |        [[Denorm Error][std::underflow_error]] | ||
|  |        [[Evaluation Error][boost::math::evaluation_error]] | ||
|  |        [[Indeterminate Result Error][std::domain_error]] | ||
|  |     ] | ||
|  | 
 | ||
|  | [h5 errno_on_error] | ||
|  | 
 | ||
|  | Will set global __errno `::errno` to one of the following values depending  | ||
|  | upon the error type (often EDOM = 33 and ERANGE = 34), | ||
|  | and then return the same value as if the error | ||
|  | had been ignored: | ||
|  |  [table | ||
|  |     [[Error Type][errno value]] | ||
|  |     [[Domain Error][EDOM]] | ||
|  |     [[Pole Error][EDOM]] | ||
|  |     [[Overflow Error][ERANGE]] | ||
|  |     [[Underflow Error][ERANGE]] | ||
|  |     [[Denorm Error][ERANGE]] | ||
|  |     [[Evaluation Error][EDOM]] | ||
|  |     [[Indeterminate Result Error][EDOM]] | ||
|  |  ] | ||
|  | 
 | ||
|  | [h5 ignore_error] | ||
|  | 
 | ||
|  | Will return one of the values below depending on the error type (`::errno` is NOT changed):: | ||
|  |  [table | ||
|  |     [[Error Type][Returned Value]] | ||
|  |     [[Domain Error][std::numeric_limits<T>::quiet_NaN()]] | ||
|  |     [[Pole Error][std::numeric_limits<T>::quiet_NaN()]] | ||
|  |     [[Overflow Error][std::numeric_limits<T>::infinity()]] | ||
|  |     [[Underflow Error][0]] | ||
|  |     [[Denorm Error][The denormalised value.]] | ||
|  |     [[Evaluation Error][The best guess (perhaps NaN) as to the result: which | ||
|  |           may be significantly in error.]] | ||
|  |     [[Indeterminate Result Error][Depends on the function where the error occurred]] | ||
|  |  ] | ||
|  | 
 | ||
|  | [h5 user_error] | ||
|  | 
 | ||
|  | Will call a user defined error handler: these are forward declared | ||
|  | in boost/math/policies/error_handling.hpp, but the actual definitions | ||
|  | must be provided by the user: | ||
|  | 
 | ||
|  |    namespace boost{ namespace math{ namespace policies{ | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_domain_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_pole_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_overflow_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_underflow_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_denorm_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_rounding_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_evaluation_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    T user_indeterminate_result_error(const char* function, const char* message, const T& val); | ||
|  | 
 | ||
|  |    }}} // namespaces | ||
|  | 
 | ||
|  | Note that the strings ['function] and ['message] may contain "%1%" format specifiers | ||
|  | designed to be used in conjunction with Boost.Format.   | ||
|  | If these strings are to be presented to the program's end-user then  | ||
|  | the "%1%" format specifier | ||
|  | should be replaced with the name of type T in the ['function] string, and  | ||
|  | if there is a %1% specifier in the ['message] string then it  | ||
|  | should be replaced with the value of ['val]. | ||
|  | 
 | ||
|  | There is more information on user-defined error handlers in | ||
|  | the [link math_toolkit.pol_tutorial.user_def_err_pol  | ||
|  | tutorial here]. | ||
|  | 
 | ||
|  | [h4 Kinds of Error Raised]                   | ||
|  | 
 | ||
|  | There are six kinds of error reported by this library, | ||
|  | which are summarised in the following table: | ||
|  | 
 | ||
|  | [table | ||
|  | [[Error Type] | ||
|  |    [Policy Class] | ||
|  |       [Description]] | ||
|  | [[Domain Error] | ||
|  |    [boost::math::policies::domain_error<['action]>] | ||
|  |       [Raised when more or more arguments are outside the  | ||
|  |       defined range of the function. | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::domain_error<throw_on_error>` | ||
|  | 
 | ||
|  |       When the action is set to ['throw_on_error]  | ||
|  |       then throws `std::domain_error`]] | ||
|  | [[Pole Error] | ||
|  |    [boost::math::policies::pole_error<['action]>] | ||
|  |       [Raised when more or more arguments would cause the function | ||
|  |       to be evaluated at a pole. | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::pole_error<throw_on_error>` | ||
|  | 
 | ||
|  |       When the action is ['throw_on_error] then | ||
|  |       throw a `std::domain_error`]] | ||
|  | [[Overflow Error] | ||
|  |    [boost::math::policies::overflow_error<['action]>] | ||
|  |       [Raised when the result of the function is outside | ||
|  |       the representable range of the floating point type used. | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::overflow_error<throw_on_error>`. | ||
|  | 
 | ||
|  |       When the action is ['throw_on_error] then throws a `std::overflow_error`.]] | ||
|  | [[Underflow Error] | ||
|  |    [boost::math::policies::underflow_error<['action]>] | ||
|  |       [Raised when the result of the function is too small | ||
|  |       to be represented in the floating point type used. | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::underflow_error<ignore_error>` | ||
|  | 
 | ||
|  |       When the specified action is ['throw_on_error] then | ||
|  |       throws a `std::underflow_error`]] | ||
|  | [[Denorm Error] | ||
|  |    [boost::math::policies::denorm_error<['action]>] | ||
|  |       [Raised when the result of the function is a | ||
|  |       denormalised value. | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::denorm_error<ignore_error>` | ||
|  | 
 | ||
|  |       When the action is ['throw_on_error] then throws a `std::underflow_error`]] | ||
|  | [[Rounding Error] | ||
|  |    [boost::math::policies::rounding_error<['action]>] | ||
|  |       [Raised When one of the rounding functions __round, __trunc or __modf is | ||
|  |       called with an argument that has no integer representation, or | ||
|  |       is too large to be represented in the result type | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::rounding_error<throw_on_error>` | ||
|  | 
 | ||
|  |       When the action is ['throw_on_error] then throws `boost::math::rounding_error`]] | ||
|  | [[Evaluation Error] | ||
|  |    [boost::math::policies::evaluation_error<['action]>] | ||
|  |       [Raised when the result of the function is well defined and | ||
|  |       finite, but we were unable to compute it.  Typically | ||
|  |       this occurs when an iterative method fails to converge. | ||
|  |       Of course ideally this error should never be raised: feel free | ||
|  |       to report it as a bug if it is! | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::evaluation_error<throw_on_error>` | ||
|  | 
 | ||
|  |       When the action is ['throw_on_error] then throws `boost::math::evaluation_error`]] | ||
|  | [[Indeterminate Result Error] | ||
|  |    [boost::math::policies::indeterminate_result_error<['action]>] | ||
|  |       [Raised when the result of a function is not defined for the values that | ||
|  |       were passed to it. | ||
|  | 
 | ||
|  |       Defaults to `boost::math::policies::indeterminate_result_error<ignore_error>` | ||
|  | 
 | ||
|  |       When the action is ['throw_on_error] then throws `std::domain_error`]] | ||
|  | ] | ||
|  | 
 | ||
|  | [h4 Examples] | ||
|  | 
 | ||
|  | Suppose we want a call to `tgamma` to behave in a C-compatible way and set global | ||
|  | `::errno` rather than throw an exception, we can achieve this at the call site | ||
|  | using: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip1.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip1] | ||
|  |     | ||
|  | Suppose we want a statistical distribution to return infinities, | ||
|  | rather than throw exceptions, then we can use: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip2.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip2] | ||
|  | 
 | ||
|  | [endsect] [/section:error_handling_policies Error Handling Policies] | ||
|  | 
 | ||
|  | [section:internal_promotion Internal Floating-point Promotion Policies] | ||
|  | 
 | ||
|  | Normally when evaluating a function at say `float` precision, maximal | ||
|  | accuracy is assured by conducting the calculation at `double` precision | ||
|  | internally, and then rounding the result.  There are two policies that | ||
|  | control whether internal promotion to a higher precision floating-point type takes place, or not: | ||
|  | 
 | ||
|  | [table | ||
|  | [[Policy][Meaning]] | ||
|  | [[`boost::math::policies::promote_float<B>`] | ||
|  |    [Indicates whether `float` arguments should be promoted to `double` | ||
|  |    precision internally: defaults to `boost::math::policies::promote_float<true>`]] | ||
|  | [[`boost::math::policies::promote_double<B>`] | ||
|  |    [Indicates whether `double` arguments should be promoted to `long double` | ||
|  |    precision internally: defaults to `boost::math::policies::promote_double<true>`]] | ||
|  | ] | ||
|  | 
 | ||
|  | [h4 Examples] | ||
|  | 
 | ||
|  | Suppose we want `tgamma` to be evaluated without internal promotion to | ||
|  | `long double`, then we could use: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip3.cpp] | ||
|  | [policy_ref_snip3] | ||
|  |     | ||
|  | Alternatively, suppose we want a distribution to perform calculations | ||
|  | without promoting `float` to `double`, then we could use: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip4.cpp] | ||
|  | [policy_ref_snip4] | ||
|  |     | ||
|  | [endsect] [/section:internal_promotion Internal Promotion Policies] | ||
|  | 
 | ||
|  | [section:assert_undefined Mathematically Undefined Function Policies] | ||
|  | 
 | ||
|  | There are some functions that are generic | ||
|  | (they are present for all the statistical distributions supported) | ||
|  | but which may be mathematically undefined for certain distributions, but defined for others. | ||
|  | 
 | ||
|  | For example, the Cauchy distribution does not have a meaningful mean, | ||
|  | so what should | ||
|  | 
 | ||
|  |    mean(cauchy<>()); | ||
|  |     | ||
|  | return, and should such an expression even compile at all? | ||
|  | 
 | ||
|  | The default behaviour is for all such functions to not compile at all | ||
|  |  - in fact they will raise a  | ||
|  | [@http://www.boost.org/libs/static_assert/index.html static assertion] | ||
|  |  - but by changing the policy | ||
|  | we can have them return the result of a domain error instead | ||
|  | (which may well throw an exception, depending on the error handling policy).  | ||
|  | 
 | ||
|  | This behaviour is controlled by the `assert_undefined<>` policy: | ||
|  | 
 | ||
|  |    namespace boost{ namespace math{ namespace policies { | ||
|  | 
 | ||
|  |    template <bool b> | ||
|  |    class assert_undefined; | ||
|  | 
 | ||
|  |    }}} //namespaces | ||
|  | 
 | ||
|  | For example: | ||
|  | 
 | ||
|  |    #include <boost/math/distributions/cauchy.hpp> | ||
|  |     | ||
|  |    using namespace boost::math::policies; | ||
|  |    using namespace boost::math; | ||
|  |     | ||
|  |    // This will not compile, cauchy has no mean! | ||
|  |    double m1 = mean(cauchy());  | ||
|  |     | ||
|  |    // This will compile, but raises a domain error! | ||
|  |    double m2 = mean(cauchy_distribution<double, policy<assert_undefined<false> > >()); | ||
|  | 
 | ||
|  | `policy<assert_undefined<false>` behaviour can also be obtained by defining the macro | ||
|  | 
 | ||
|  |   #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false | ||
|  |    | ||
|  | at the head of the file - see __policy_macros.  | ||
|  |   | ||
|  | [endsect][/section:assert_undefined Mathematically Undefined Function Policies] | ||
|  | 
 | ||
|  | [section:discrete_quant_ref Discrete Quantile Policies] | ||
|  | 
 | ||
|  | If a statistical distribution is ['discrete] then the random variable | ||
|  | can only have integer values - this leaves us with a problem when calculating | ||
|  | quantiles - we can either ignore the discreteness of the distribution and return | ||
|  | a real value, or we can round to an integer.  As it happens, computing integer | ||
|  | values can be substantially faster than calculating a real value, so there are | ||
|  | definite advantages to returning an integer, but we do then need to decide | ||
|  | how best to round the result.  The `discrete_quantile` policy defines how | ||
|  | discrete quantiles work, and how integer results are rounded: | ||
|  | 
 | ||
|  |    enum discrete_quantile_policy_type | ||
|  |    { | ||
|  |       real, | ||
|  |       integer_round_outwards, // default | ||
|  |       integer_round_inwards, | ||
|  |       integer_round_down, | ||
|  |       integer_round_up, | ||
|  |       integer_round_nearest | ||
|  |    }; | ||
|  |     | ||
|  |    template <discrete_quantile_policy_type> | ||
|  |    struct discrete_quantile; | ||
|  |     | ||
|  | The values that `discrete_quantile` can take have the following meanings: | ||
|  | 
 | ||
|  | [h5 real] | ||
|  | 
 | ||
|  | Ignores the discreteness of the distribution, and returns a real-valued  | ||
|  | result.  For example: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip5.cpp] | ||
|  | [policy_ref_snip5] | ||
|  |     | ||
|  | Results in `x = 27.3898` and `y = 68.1584`. | ||
|  | 
 | ||
|  | [h5 integer_round_outwards] | ||
|  | 
 | ||
|  | This is the default policy: an integer value is returned so that: | ||
|  | 
 | ||
|  | * Lower quantiles (where the probability is less than 0.5) are rounded | ||
|  | down. | ||
|  | * Upper quantiles (where the probability is greater than 0.5) are rounded up. | ||
|  | 
 | ||
|  | This is normally the safest rounding policy, since it ensures that both | ||
|  | one and two sided intervals are guaranteed to have ['at least]  | ||
|  | the requested coverage.  For example: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip6.cpp] | ||
|  | [policy_ref_snip6] | ||
|  |     | ||
|  | Results in `x = 27` (rounded down from 27.3898) and `y = 69` (rounded up from 68.1584). | ||
|  | 
 | ||
|  | The variables x and y are now defined so that: | ||
|  | 
 | ||
|  |    cdf(negative_binomial(20), x) <= 0.05 | ||
|  |    cdf(negative_binomial(20), y) >= 0.95 | ||
|  |     | ||
|  | In other words we guarantee ['at least 90% coverage in the central region overall],  | ||
|  | and also ['no more than 5% coverage in each tail]. | ||
|  | 
 | ||
|  | [h5 integer_round_inwards] | ||
|  | 
 | ||
|  | This is the opposite of ['integer_round_outwards]: an integer value is returned so that: | ||
|  | 
 | ||
|  | * Lower quantiles (where the probability is less than 0.5) are rounded | ||
|  | ['up]. | ||
|  | * Upper quantiles (where the probability is greater than 0.5) are rounded ['down]. | ||
|  | 
 | ||
|  | For example: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip7.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip7] | ||
|  |     | ||
|  | Results in `x = 28` (rounded up from 27.3898) and `y = 68` (rounded down from 68.1584). | ||
|  | 
 | ||
|  | The variables x and y are now defined so that: | ||
|  | 
 | ||
|  |    cdf(negative_binomial(20), x) >= 0.05 | ||
|  |    cdf(negative_binomial(20), y) <= 0.95 | ||
|  |     | ||
|  | In other words we guarantee ['at no more than 90% coverage in the central region overall],  | ||
|  | and also ['at least 5% coverage in each tail]. | ||
|  | 
 | ||
|  | [h5 integer_round_down] | ||
|  | 
 | ||
|  | Always rounds down to an integer value, no matter whether it's an upper  | ||
|  | or a lower quantile. | ||
|  | 
 | ||
|  | [h5 integer_round_up] | ||
|  | 
 | ||
|  | Always rounds up to an integer value, no matter whether it's an upper  | ||
|  | or a lower quantile. | ||
|  | 
 | ||
|  | [h5 integer_round_nearest] | ||
|  | 
 | ||
|  | Always rounds to the nearest integer value, no matter whether it's an upper  | ||
|  | or a lower quantile.  This will produce the requested coverage | ||
|  | ['in the average case], but for any specific example may results in | ||
|  | either significantly more or less coverage than the requested amount. | ||
|  | For example: | ||
|  | 
 | ||
|  | For example: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip8.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip8] | ||
|  | 
 | ||
|  | Results in `x = 27` (rounded from 27.3898) and `y = 68` (rounded from 68.1584). | ||
|  | 
 | ||
|  | [endsect][/section:discrete_quant_ref Discrete Quantile Policies] | ||
|  | 
 | ||
|  | [section:precision_pol Precision Policies] | ||
|  | 
 | ||
|  | There are two equivalent policies that effect the ['working precision] | ||
|  | used to calculate results, these policies both default to 0 - meaning | ||
|  | calculate to the maximum precision available in the type being used | ||
|  |  - but can be set to other values to cause lower levels of precision  | ||
|  | to be used. One might want to trade precision for evaluation speed. | ||
|  | 
 | ||
|  |    namespace boost{ namespace math{ namespace policies{ | ||
|  |     | ||
|  |    template <int N> | ||
|  |    digits10; | ||
|  |     | ||
|  |    template <int N> | ||
|  |    digits2; | ||
|  |     | ||
|  |    }}} // namespaces | ||
|  |     | ||
|  | As you would expect, ['digits10] specifies the number of decimal digits | ||
|  | to use, and ['digits2] the number of binary digits.  Internally, whichever | ||
|  | is used, the precision is always converted to ['binary digits]. | ||
|  | 
 | ||
|  | These policies are specified at compile-time, because many of the special | ||
|  | functions use compile-time-dispatch to select which approximation to use | ||
|  | based on the precision requested and the numeric type being used. | ||
|  | 
 | ||
|  | For example we could calculate `tgamma` to approximately 5 decimal digits using: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip9.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip9] | ||
|  |     | ||
|  | Or again using helper function `make_policy`: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip10.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip10] | ||
|  | 
 | ||
|  | And for a quantile of a distribution to approximately 25-bit precision: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip11.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip11] | ||
|  | 
 | ||
|  | [endsect][/section:precision_pol Precision Policies] | ||
|  | 
 | ||
|  | [section:iteration_pol Iteration Limits Policies] | ||
|  | 
 | ||
|  | There are two policies that effect the iterative algorithms | ||
|  | used to implement the special functions in this library: | ||
|  | 
 | ||
|  |    template <unsigned long limit = BOOST_MATH_MAX_SERIES_ITERATION_POLICY> | ||
|  |    class max_series_iterations; | ||
|  |     | ||
|  |    template <unsigned long limit = BOOST_MATH_MAX_ROOT_ITERATION_POLICY> | ||
|  |    class max_root_iterations; | ||
|  | 
 | ||
|  | The class `max_series_iterations` determines the maximum number of | ||
|  | iterations permitted in a series evaluation, before the special | ||
|  | function gives up and returns the result of __evaluation_error. | ||
|  | 
 | ||
|  | The class `max_root_iterations` determines the maximum number | ||
|  | of iterations permitted in a root-finding algorithm before the special | ||
|  | function gives up and returns the result of __evaluation_error. | ||
|  | 
 | ||
|  | [endsect] [/section:iteration_pol Iteration Limits Policies] | ||
|  | 
 | ||
|  | [section:policy_defaults Using Macros to Change the Policy Defaults] | ||
|  | 
 | ||
|  | You can use the various macros below to change any (or all) of the policies. | ||
|  | 
 | ||
|  | You can make a local change by placing a macro definition *before* | ||
|  | a function or distribution #include. | ||
|  | 
 | ||
|  | [caution There is a danger of One-Definition-Rule violations if you  | ||
|  | add ad-hoc macros to more than one source files: these must be set the same in *every  | ||
|  | translation unit*.] | ||
|  | 
 | ||
|  | [caution If you place it after the #include it will have no effect, | ||
|  | (and it will affect only any other following #includes). | ||
|  | This is probably not what you intend!] | ||
|  | 
 | ||
|  | If you want to alter the defaults for any or all of  | ||
|  | the policies for *all* functions and distributions, installation-wide, | ||
|  | then you can do so by defining various macros in | ||
|  | [@../../../../boost/math/tools/user.hpp boost/math/tools/user.hpp]. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_DOMAIN_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when a domain error occurs, if not defined then | ||
|  | defaults to `throw_on_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_POLE_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when a pole error occurs, if not defined then | ||
|  | defaults to `throw_on_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_OVERFLOW_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when an overflow error occurs, if not defined then | ||
|  | defaults to `throw_on_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_ROUNDING_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when a rounding error occurs, if not defined then | ||
|  | defaults to `throw_on_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_EVALUATION_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when an internal evaluation error occurs, if not defined then | ||
|  | defaults to `throw_on_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_UNDERFLOW_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when an overflow error occurs, if not defined then | ||
|  | defaults to `ignore_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_DENORM_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when a denormalisation error occurs, if not defined then | ||
|  | defaults to `ignore_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY] | ||
|  | 
 | ||
|  | Defines what happens when the result is indeterminate, but where there | ||
|  | is none the less a convention for the result.  If not defined then | ||
|  | defaults to `ignore_error`, but can be set to any of the enumerated | ||
|  | actions for error handing: `throw_on_error`, `errno_on_error`,  | ||
|  | `ignore_error` or `user_error`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_DIGITS10_POLICY] | ||
|  | 
 | ||
|  | Defines how many decimal digits to use in internal computations:  | ||
|  | defaults to `0` - meaning use all available digits - but can be set | ||
|  | to some other decimal value.  Since setting this is likely to have | ||
|  | a substantial impact on accuracy, it's not generally recommended | ||
|  | that you change this from the default. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_PROMOTE_FLOAT_POLICY] | ||
|  | 
 | ||
|  | Determines whether `float` types get promoted to `double` | ||
|  | internally to ensure maximum precision in the result, defaults | ||
|  | to `true`, but can be set to `false` to turn promotion of | ||
|  | `float`'s off. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_PROMOTE_DOUBLE_POLICY] | ||
|  | 
 | ||
|  | Determines whether `double` types get promoted to `long double` | ||
|  | internally to ensure maximum precision in the result, defaults | ||
|  | to `true`, but can be set to `false` to turn promotion of | ||
|  | `double`'s off. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_DISCRETE_QUANTILE_POLICY] | ||
|  | 
 | ||
|  | Determines how discrete quantiles return their results: either | ||
|  | as an integer, or as a real value, can be set to one of the | ||
|  | enumerated values: `real`, `integer_round_outwards`, `integer_round_inwards`, | ||
|  | `integer_round_down`, `integer_round_up`, `integer_round_nearest`.  Defaults to | ||
|  | `integer_round_outwards`. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_ASSERT_UNDEFINED_POLICY] | ||
|  | 
 | ||
|  | Determines whether functions that are mathematically undefined | ||
|  | for a specific distribution compile or raise a static (i.e. compile-time) | ||
|  | assertion.  Defaults to `true`: meaning that any mathematically | ||
|  | undefined function will not compile.  When set to `false` then the function | ||
|  | will compile but return the result of a domain error: this can be useful | ||
|  | for some generic code, that needs to work with all distributions and determine | ||
|  | at runtime whether or not a particular property is well defined. | ||
|  | 
 | ||
|  | [h5 BOOST_MATH_MAX_SERIES_ITERATION_POLICY] | ||
|  | 
 | ||
|  | Determines how many series iterations a special function is permitted | ||
|  | to perform before it gives up and returns an __evaluation_error: | ||
|  | Defaults to 1000000. | ||
|  |     | ||
|  | [h5 BOOST_MATH_MAX_ROOT_ITERATION_POLICY] | ||
|  | 
 | ||
|  | Determines how many root-finding iterations a special function is permitted | ||
|  | to perform before it gives up and returns an __evaluation_error: | ||
|  | Defaults to 200. | ||
|  | 
 | ||
|  | [h5 Example] | ||
|  | 
 | ||
|  | Suppose we want overflow errors to set `::errno` and return an infinity, | ||
|  | discrete quantiles to return a real-valued result (rather than round to | ||
|  | integer), and for mathematically undefined functions to compile, but return | ||
|  | a domain error. Then we could add the following to boost/math/tools/user.hpp: | ||
|  | 
 | ||
|  |    #define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error | ||
|  |    #define BOOST_MATH_DISCRETE_QUANTILE_POLICY real | ||
|  |    #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false | ||
|  |     | ||
|  | or we could place these definitions *before* | ||
|  | 
 | ||
|  |    #include <boost/math/distributions/normal.hpp> | ||
|  |      using boost::math::normal_distribution; | ||
|  | 
 | ||
|  | in a source .cpp file. | ||
|  | 
 | ||
|  | [endsect][/section:policy_defaults Changing the Policy Defaults] | ||
|  | 
 | ||
|  | [section:namespace_pol Setting Polices at Namespace Scope] | ||
|  | 
 | ||
|  | Sometimes what you really want to do is bring all the special functions, | ||
|  | or all the distributions into a specific namespace-scope, along with | ||
|  | a specific policy to use with them.  There are two macros defined to | ||
|  | assist with that: | ||
|  | 
 | ||
|  |    BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy) | ||
|  | 
 | ||
|  | and: | ||
|  | 
 | ||
|  |    BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy) | ||
|  |     | ||
|  | You can use either of these macros after including any special function | ||
|  | or distribution header.  For example: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip12.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip12] | ||
|  | 
 | ||
|  | In this example, using BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS results in | ||
|  | a set of thin inline forwarding functions being defined: | ||
|  | 
 | ||
|  |    template <class T> | ||
|  |    inline T tgamma(T a){ return ::boost::math::tgamma(a, mypolicy()); } | ||
|  |     | ||
|  |    template <class T> | ||
|  |    inline T lgamma(T a) ( return ::boost::math::lgamma(a, mypolicy()); } | ||
|  |     | ||
|  | and so on.  Note that while a forwarding function is defined for all the special | ||
|  | functions, however, unless you include the specific header for the special | ||
|  | function you use (or boost/math/special_functions.hpp to include everything),  | ||
|  | you will get linker errors from functions that are forward declared, but not | ||
|  | defined. | ||
|  | 
 | ||
|  | We can do the same thing with the distributions, but this time we need to | ||
|  | specify the floating-point type to use: | ||
|  | 
 | ||
|  | [import ../../example/policy_ref_snip13.cpp] | ||
|  | 
 | ||
|  | [policy_ref_snip13] | ||
|  |     | ||
|  | In this example the result of BOOST_MATH_DECLARE_DISTRIBUTIONS is to | ||
|  | declare a typedef for each distribution like this: | ||
|  | 
 | ||
|  |    typedef boost::math::cauchy_distribution<double, my_policy> cauchy; | ||
|  |    tyepdef boost::math::gamma_distribution<double, my_policy> gamma; | ||
|  |     | ||
|  | and so on.  The name given to each typedef is the name of the distribution | ||
|  | with the "_distribution" suffix removed. | ||
|  | 
 | ||
|  | [endsect][/section Changing the Policy Defaults] | ||
|  | 
 | ||
|  | [section:pol_ref_ref Policy Class Reference] | ||
|  | 
 | ||
|  | There's very little to say here, the `policy` class is just a rag-bag | ||
|  | compile-time container for a collection of policies: | ||
|  | 
 | ||
|  | ```#include <boost/math/policies/policy.hpp>``` | ||
|  | 
 | ||
|  | 
 | ||
|  |    namespace boost{ | ||
|  |    namespace math{ | ||
|  |    namespace policies | ||
|  |     | ||
|  |    template <class A1 = default_policy,  | ||
|  |              class A2 = default_policy,  | ||
|  |              class A3 = default_policy, | ||
|  |              class A4 = default_policy, | ||
|  |              class A5 = default_policy, | ||
|  |              class A6 = default_policy, | ||
|  |              class A7 = default_policy, | ||
|  |              class A8 = default_policy, | ||
|  |              class A9 = default_policy, | ||
|  |              class A10 = default_policy, | ||
|  |              class A11 = default_policy, | ||
|  |              class A12 = default_policy, | ||
|  |              class A13 = default_policy> | ||
|  |    struct policy | ||
|  |    { | ||
|  |    public: | ||
|  |       typedef ``['computed-from-template-arguments]`` domain_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` pole_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` overflow_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` underflow_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` denorm_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` rounding_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` evaluation_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` indeterminate_result_error_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` precision_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` promote_float_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` promote_double_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` discrete_quantile_type; | ||
|  |       typedef ``['computed-from-template-arguments]`` assert_undefined_type; | ||
|  |    }; | ||
|  | 
 | ||
|  |    template <...argument list...> | ||
|  |    typename normalise<policy<>, A1>::type make_policy(...argument list..); | ||
|  | 
 | ||
|  |    template <class Policy,  | ||
|  |              class A1 = default_policy,  | ||
|  |              class A2 = default_policy,  | ||
|  |              class A3 = default_policy, | ||
|  |              class A4 = default_policy, | ||
|  |              class A5 = default_policy, | ||
|  |              class A6 = default_policy, | ||
|  |              class A7 = default_policy, | ||
|  |              class A8 = default_policy, | ||
|  |              class A9 = default_policy, | ||
|  |              class A10 = default_policy, | ||
|  |              class A11 = default_policy, | ||
|  |              class A12 = default_policy, | ||
|  |              class A13 = default_policy> | ||
|  |    struct normalise | ||
|  |    { | ||
|  |       typedef ``computed-from-template-arguments`` type; | ||
|  |    }; | ||
|  | 
 | ||
|  | The member typedefs of class `policy` are intended for internal use | ||
|  | but are documented briefly here for the sake of completeness. | ||
|  | 
 | ||
|  |    policy<...>::domain_error_type | ||
|  |     | ||
|  | Specifies how domain errors are handled, will be an instance of | ||
|  | `boost::math::policies::domain_error<>` with the template argument to | ||
|  | `domain_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::pole_error_type | ||
|  |     | ||
|  | Specifies how pole-errors are handled, will be an instance of | ||
|  | `boost::math::policies::pole_error<>` with the template argument to | ||
|  | `pole_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::overflow_error_type | ||
|  |     | ||
|  | Specifies how overflow errors are handled, will be an instance of | ||
|  | `boost::math::policies::overflow_error<>` with the template argument to | ||
|  | `overflow_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::underflow_error_type | ||
|  |     | ||
|  | Specifies how underflow errors are handled, will be an instance of | ||
|  | `boost::math::policies::underflow_error<>` with the template argument to | ||
|  | `underflow_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::denorm_error_type | ||
|  |     | ||
|  | Specifies how denorm errors are handled, will be an instance of | ||
|  | `boost::math::policies::denorm_error<>` with the template argument to | ||
|  | `denorm_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::rounding_error_type | ||
|  |     | ||
|  | Specifies how rounding errors are handled, will be an instance of | ||
|  | `boost::math::policies::rounding_error<>` with the template argument to | ||
|  | `rounding_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::evaluation_error_type | ||
|  |     | ||
|  | Specifies how evaluation errors are handled, will be an instance of | ||
|  | `boost::math::policies::evaluation_error<>` with the template argument to | ||
|  | `evaluation_error` one of the `error_policy_type` enumerated values. | ||
|  | 
 | ||
|  |    policy<...>::indeterminate_error_type | ||
|  | 
 | ||
|  | Specifies how indeterminate result errors are handled, will be an instance of | ||
|  | `boost::math::policies::indeterminate_result_error<>` with the template argument | ||
|  | to `indeterminate_result_error` one of the `error_policy_type` enumerated | ||
|  | values. | ||
|  | 
 | ||
|  |    policy<...>::precision_type | ||
|  |     | ||
|  | Specifies the internal precision to use in binary digits (uses zero | ||
|  | to represent whatever the default precision is).  Will be an instance | ||
|  | of `boost::math::policies::digits2<N>` which in turn inherits from  | ||
|  | `boost::mpl::int_<N>`. | ||
|  | 
 | ||
|  |    policy<...>::promote_float_type | ||
|  |     | ||
|  | Specifies whether or not to promote `float` arguments to `double` precision | ||
|  | internally.  Will be an instance of `boost::math::policies::promote_float<B>` | ||
|  | which in turn inherits from `boost::mpl::bool_<B>`. | ||
|  | 
 | ||
|  |    policy<...>::promote_double_type | ||
|  |     | ||
|  | Specifies whether or not to promote `double` arguments to `long double` precision | ||
|  | internally.  Will be an instance of `boost::math::policies::promote_float<B>` | ||
|  | which in turn inherits from `boost::mpl::bool_<B>`. | ||
|  | 
 | ||
|  |    policy<...>::discrete_quantile_type | ||
|  |     | ||
|  | Specifies how discrete quantiles are evaluated, will be an instance | ||
|  | of `boost::math::policies::discrete_quantile<>` instantiated with one of | ||
|  | the `discrete_quantile_policy_type` enumerated type. | ||
|  | 
 | ||
|  |    policy<...>::assert_undefined_type | ||
|  |     | ||
|  | Specifies whether mathematically-undefined properties are | ||
|  | asserted as compile-time errors, or treated as runtime errors | ||
|  | instead.  Will be an instance of `boost::math::policies::assert_undefined<B>` | ||
|  | which in turn inherits from `boost::math::mpl::bool_<B>`. | ||
|  | 
 | ||
|  | 
 | ||
|  |    template <...argument list...> | ||
|  |    typename normalise<policy<>, A1>::type make_policy(...argument list..); | ||
|  | 
 | ||
|  | `make_policy` is a helper function that converts a list of policies into | ||
|  | a normalised `policy` class. | ||
|  | 
 | ||
|  |    template <class Policy,  | ||
|  |              class A1 = default_policy,  | ||
|  |              class A2 = default_policy,  | ||
|  |              class A3 = default_policy, | ||
|  |              class A4 = default_policy, | ||
|  |              class A5 = default_policy, | ||
|  |              class A6 = default_policy, | ||
|  |              class A7 = default_policy, | ||
|  |              class A8 = default_policy, | ||
|  |              class A9 = default_policy, | ||
|  |              class A10 = default_policy, | ||
|  |              class A11 = default_policy, | ||
|  |              class A12 = default_policy, | ||
|  |              class A13 = default_policy> | ||
|  |    struct normalise | ||
|  |    { | ||
|  |       typedef ``computed-from-template-arguments`` type; | ||
|  |    }; | ||
|  |     | ||
|  | The `normalise` class template converts one instantiation of the | ||
|  | `policy` class into a normalised form.  This is used internally | ||
|  | to reduce code bloat: so that instantiating a special function | ||
|  | on `policy<A,B>` or `policy<B,A>` actually both generate the same | ||
|  | code internally.   | ||
|  | 
 | ||
|  | Further more, `normalise` can be used to combine | ||
|  | a policy with one or more policies: for example many of the | ||
|  | special functions will use this to set policies which they don't | ||
|  | make use of to their default values, before forwarding to the actual | ||
|  | implementation.  In this way code bloat is reduced, since the | ||
|  | actual implementation depends only on the policy types that they | ||
|  | actually use. | ||
|  | 
 | ||
|  | [endsect][/section:pol_ref_ref Policy Class Reference] | ||
|  | 
 | ||
|  | [endsect][/section:pol_ref Policy Reference] | ||
|  | [endmathpart][/section:policy Policies] | ||
|  | 
 | ||
|  | [/ qbk | ||
|  |   Copyright 2007, 2010 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). | ||
|  | ] | ||
|  | 
 | ||
|  | 
 |