mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			512 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			512 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
[section:pol_tutorial Policy Tutorial]
 | 
						|
 | 
						|
[section:what_is_a_policy So Just What is a Policy Anyway?]
 | 
						|
 | 
						|
A policy is a compile-time mechanism for customising the behaviour of a
 | 
						|
special function, or a statistical distribution.  With Policies you can
 | 
						|
control:
 | 
						|
 | 
						|
* What action to take when an error occurs.
 | 
						|
* What happens when you call a function that is mathematically undefined
 | 
						|
(for example, if you ask for the mean of a Cauchy distribution).
 | 
						|
* What happens when you ask for a quantile of a discrete distribution.
 | 
						|
* Whether the library is allowed to internally promote `float` to `double`
 | 
						|
and `double` to `long double` in order to improve precision.
 | 
						|
* What precision to use when calculating the result.
 | 
						|
 | 
						|
Some of these policies could arguably be runtime variables, but then we couldn't
 | 
						|
use compile-time dispatch internally to select the best evaluation method
 | 
						|
for the given policies.
 | 
						|
 | 
						|
For this reason a Policy is a /type/: in fact it's an instance of the
 | 
						|
class template `boost::math::policies::policy<>`.  This class is just a
 | 
						|
compile-time-container of user-selected policies (sometimes called a type-list):
 | 
						|
 | 
						|
   using namespace boost::math::policies;
 | 
						|
   //
 | 
						|
   // Define a policy that sets ::errno on overflow, and does
 | 
						|
   // not promote double to long double internally:
 | 
						|
   //
 | 
						|
   typedef policy<domain_error<errno_on_error>, promote_double<false> > mypolicy;
 | 
						|
 | 
						|
[endsect] [/section:what_is_a_policy So Just What is a Policy Anyway?]
 | 
						|
 | 
						|
[section:policy_tut_defaults Policies Have Sensible Defaults]
 | 
						|
 | 
						|
Most of the time you can just ignore the policy framework.
 | 
						|
 | 
						|
['*The defaults for the various policies are as follows,
 | 
						|
if these work OK for you then you can stop reading now!]
 | 
						|
 | 
						|
[variablelist
 | 
						|
[[Domain Error][Throws a `std::domain_error` exception.]]
 | 
						|
[[Pole Error][Occurs when a function is evaluated at a pole: throws a `std::domain_error` exception.]]
 | 
						|
[[Overflow Error][Throws a `std::overflow_error` exception.]]
 | 
						|
[[Underflow][Ignores the underflow, and returns zero.]]
 | 
						|
[[Denormalised Result][Ignores the fact that the result is denormalised, and returns it.]]
 | 
						|
[[Rounding Error][Throws a `boost::math::rounding_error` exception.]]
 | 
						|
[[Internal Evaluation Error][Throws a `boost::math::evaluation_error` exception.]]
 | 
						|
[[Indeterminate Result Error][Returns a result that depends on the function where the error occurred.]]
 | 
						|
[[Promotion of float to double][Does occur by default - gives full float precision results.]]
 | 
						|
[[Promotion of double to long double][Does occur by default if long double offers
 | 
						|
   more precision than double.]]
 | 
						|
[[Precision of Approximation Used][By default uses an approximation that
 | 
						|
   will result in the lowest level of error for the type of the result.]]
 | 
						|
[[Behaviour of Discrete Quantiles]
 | 
						|
   [
 | 
						|
   The quantile function will by default return an integer result that has been
 | 
						|
   /rounded outwards/.  That is to say lower quantiles (where the probability is
 | 
						|
   less than 0.5) are rounded downward, and upper quantiles (where the probability
 | 
						|
   is greater than 0.5) are rounded upwards.  This behaviour
 | 
						|
   ensures that if an X% quantile is requested, then /at least/ the requested
 | 
						|
   coverage will be present in the central region, and /no more than/
 | 
						|
   the requested coverage will be present in the tails.
 | 
						|
 | 
						|
This behaviour can be changed so that the quantile functions are rounded
 | 
						|
   differently, or even return a real-valued result using
 | 
						|
   [link math_toolkit.pol_overview Policies].  It is strongly
 | 
						|
   recommended that you read the tutorial
 | 
						|
   [link math_toolkit.pol_tutorial.understand_dis_quant
 | 
						|
   Understanding Quantiles of Discrete Distributions] before
 | 
						|
   using the quantile function on a discrete distribution.  The
 | 
						|
   [link math_toolkit.pol_ref.discrete_quant_ref reference docs]
 | 
						|
   describe how to change the rounding policy
 | 
						|
   for these distributions.
 | 
						|
]]
 | 
						|
]
 | 
						|
 | 
						|
What's more, if you define your own policy type, then it automatically
 | 
						|
inherits the defaults for any policies not explicitly set, so given:
 | 
						|
 | 
						|
   using namespace boost::math::policies;
 | 
						|
   //
 | 
						|
   // Define a policy that sets ::errno on overflow, and does
 | 
						|
   // not promote double to long double internally:
 | 
						|
   //
 | 
						|
   typedef policy<domain_error<errno_on_error>, promote_double<false> > mypolicy;
 | 
						|
 | 
						|
then `mypolicy` defines a policy where only the overflow error handling and
 | 
						|
`double`-promotion policies differ from the defaults.
 | 
						|
 | 
						|
[endsect][/section:policy_tut_defaults Policies Have Sensible Defaults]
 | 
						|
 | 
						|
[section:policy_usage So How are Policies Used Anyway?]
 | 
						|
 | 
						|
The details follow later, but basically policies can be set by either:
 | 
						|
 | 
						|
* Defining some macros that change the default behaviour: [*this is the
 | 
						|
   recommended method for setting installation-wide policies].
 | 
						|
* By instantiating a distribution object with an explicit policy:
 | 
						|
   this is mainly reserved for ad hoc policy changes.
 | 
						|
* By passing a policy to a special function as an optional final argument:
 | 
						|
   this is mainly reserved for ad hoc policy changes.
 | 
						|
* By using some helper macros to define a set of functions or distributions
 | 
						|
in the current namespace that use a specific policy: [*this is the
 | 
						|
recommended method for setting policies on a project- or translation-unit-wide
 | 
						|
basis].
 | 
						|
 | 
						|
The following sections introduce these methods in more detail.
 | 
						|
 | 
						|
[endsect] [/section:policy_usage So How are Policies Used Anyway?]
 | 
						|
 | 
						|
[section:changing_policy_defaults Changing the Policy Defaults]
 | 
						|
 | 
						|
The default policies used by the library are changed by the usual
 | 
						|
configuration macro method.
 | 
						|
 | 
						|
For example, passing `-DBOOST_MATH_DOMAIN_ERROR_POLICY=errno_on_error` to
 | 
						|
your compiler will cause domain errors to set `::errno` and return a __NaN
 | 
						|
rather than the usual default behaviour of throwing a `std::domain_error`
 | 
						|
exception.
 | 
						|
 | 
						|
[tip For Microsoft Visual Studio,you can add to the Project Property Page,
 | 
						|
C/C++, Preprocessor, Preprocessor definitions like:
 | 
						|
 | 
						|
``BOOST_MATH_ASSERT_UNDEFINED_POLICY=0
 | 
						|
BOOST_MATH_OVERFLOW_ERROR_POLICY=errno_on_error``
 | 
						|
 | 
						|
This may be helpful to avoid complications with pre-compiled headers
 | 
						|
that may mean that the equivalent definitions in source code:
 | 
						|
 | 
						|
``#define BOOST_MATH_ASSERT_UNDEFINED_POLICY false
 | 
						|
#define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error``
 | 
						|
 | 
						|
*may be ignored*.
 | 
						|
 | 
						|
The compiler command line shows:
 | 
						|
 | 
						|
``/D "BOOST_MATH_ASSERT_UNDEFINED_POLICY=0"
 | 
						|
/D "BOOST_MATH_OVERFLOW_ERROR_POLICY=errno_on_error"``
 | 
						|
] [/MSVC tip]
 | 
						|
 | 
						|
There is however a very important caveat to this:
 | 
						|
 | 
						|
[important
 | 
						|
[*['Default policies changed by setting configuration macros must be changed
 | 
						|
uniformly in every translation unit in the program.]]
 | 
						|
 | 
						|
Failure to follow this rule may result in violations of the "One
 | 
						|
Definition Rule (ODR)" and result in unpredictable program behaviour.]
 | 
						|
 | 
						|
That means there are only two safe ways to use these macros:
 | 
						|
 | 
						|
* Edit them in [@../../../../boost/math/tools/user.hpp boost/math/tools/user.hpp],
 | 
						|
so that the defaults are set on an installation-wide basis.
 | 
						|
Unfortunately this may not be convenient if
 | 
						|
you are using a pre-installed Boost distribution (on Linux for example).
 | 
						|
* Set the defines in your project's Makefile or build environment, so that they
 | 
						|
are set uniformly across all translation units.
 | 
						|
 | 
						|
What you should *not* do is:
 | 
						|
 | 
						|
* Set the defines in the source file using `#define` as doing so
 | 
						|
almost certainly will break your program, unless you're absolutely
 | 
						|
certain that the program is restricted to a single translation unit.
 | 
						|
 | 
						|
And, yes, you will find examples in our test programs where we break this
 | 
						|
rule: but only because we know there will always be a single
 | 
						|
translation unit only: ['don't say that you weren't warned!]
 | 
						|
 | 
						|
[import ../../example/error_handling_example.cpp]
 | 
						|
 | 
						|
[error_handling_example]
 | 
						|
 | 
						|
[endsect] [/section:changing_policy_defaults Changing the Policy Defaults]
 | 
						|
 | 
						|
[section:ad_hoc_dist_policies Setting Policies for Distributions on an Ad Hoc Basis]
 | 
						|
 | 
						|
All of the statistical distributions in this library are class templates
 | 
						|
that accept two template parameters:
 | 
						|
real type (float, double ...) and policy (how to handle exceptional events),
 | 
						|
both with sensible defaults, for example:
 | 
						|
 | 
						|
   namespace boost{ namespace math{
 | 
						|
 | 
						|
   template <class RealType = double, class Policy = policies::policy<> >
 | 
						|
   class fisher_f_distribution;
 | 
						|
 | 
						|
   typedef fisher_f_distribution<> fisher_f;
 | 
						|
 | 
						|
   }}
 | 
						|
 | 
						|
This policy gets used by all the accessor functions that accept
 | 
						|
a distribution as an argument, and forwarded to all the functions called
 | 
						|
by these.  So if you use the shorthand-typedef for the distribution, then you get
 | 
						|
`double` precision arithmetic and all the default policies.
 | 
						|
 | 
						|
However, say for example we wanted to evaluate the quantile
 | 
						|
of the binomial distribution at float precision, without internal
 | 
						|
promotion to double, and with the result rounded to the /nearest/
 | 
						|
integer, then here's how it can be done:
 | 
						|
 | 
						|
[import ../../example/policy_eg_3.cpp]
 | 
						|
 | 
						|
[policy_eg_3]
 | 
						|
 | 
						|
Which outputs:
 | 
						|
 | 
						|
[pre quantile is: 40]
 | 
						|
 | 
						|
[endsect][/section:ad_hoc_dist_policies Setting Policies for Distributions on an Ad Hoc Basis]
 | 
						|
 | 
						|
[section:ad_hoc_sf_policies Changing the Policy on an Ad Hoc Basis for the Special Functions]
 | 
						|
 | 
						|
All of the special functions in this library come in two overloaded forms,
 | 
						|
one with a final "policy" parameter, and one without.  For example:
 | 
						|
 | 
						|
   namespace boost{ namespace math{
 | 
						|
 | 
						|
   template <class RealType, class Policy>
 | 
						|
   RealType tgamma(RealType, const Policy&);
 | 
						|
 | 
						|
   template <class RealType>
 | 
						|
   RealType tgamma(RealType);
 | 
						|
 | 
						|
   }} // namespaces
 | 
						|
 | 
						|
Normally, the second version is just a forwarding wrapper to the first
 | 
						|
like this:
 | 
						|
 | 
						|
   template <class RealType>
 | 
						|
   inline RealType tgamma(RealType x)
 | 
						|
   {
 | 
						|
      return tgamma(x, policies::policy<>());
 | 
						|
   }
 | 
						|
 | 
						|
So calling a special function with a specific policy
 | 
						|
is just a matter of defining the policy type to use
 | 
						|
and passing it as the final parameter.  For example,
 | 
						|
suppose we want `tgamma` to behave in a C-compatible
 | 
						|
fashion and set `::errno` when an error occurs, and never
 | 
						|
throw an exception:
 | 
						|
 | 
						|
[import ../../example/policy_eg_1.cpp]
 | 
						|
 | 
						|
[policy_eg_1]
 | 
						|
 | 
						|
which outputs:
 | 
						|
 | 
						|
[pre
 | 
						|
Result of tgamma(30000) is: 1.#INF
 | 
						|
errno = 34
 | 
						|
Result of tgamma(-10) is: 1.#QNAN
 | 
						|
errno = 33
 | 
						|
]
 | 
						|
 | 
						|
Alternatively, for ad hoc use, we can use the `make_policy`
 | 
						|
helper function to create a policy for us: this usage is more
 | 
						|
verbose, so is probably only preferred when a policy is going
 | 
						|
to be used once only:
 | 
						|
 | 
						|
[import ../../example/policy_eg_2.cpp]
 | 
						|
 | 
						|
[policy_eg_2]
 | 
						|
 | 
						|
[endsect] [/section:ad_hoc_sf_policies Changing the Policy on an Ad Hoc Basis for the Special Functions]
 | 
						|
 | 
						|
[section:namespace_policies Setting Policies at Namespace or Translation Unit Scope]
 | 
						|
 | 
						|
Sometimes what you want to do is just change a set of policies within
 | 
						|
the current scope: *the one thing you should not do in this situation
 | 
						|
is use the configuration macros*, as this can lead to "One Definition
 | 
						|
Rule" violations.  Instead this library provides a pair of macros
 | 
						|
especially for this purpose.
 | 
						|
 | 
						|
Let's consider the special functions first: we can declare a set of
 | 
						|
forwarding functions that all use a specific policy using the
 | 
						|
macro BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(['Policy]).  This
 | 
						|
macro should be used either inside a unique namespace set aside for the
 | 
						|
purpose (for example, a C namespace for a C-style policy),
 | 
						|
or an unnamed namespace if you just want the functions
 | 
						|
visible in global scope for the current file only.
 | 
						|
 | 
						|
[import ../../example/policy_eg_4.cpp]
 | 
						|
 | 
						|
[policy_eg_4]
 | 
						|
 | 
						|
The same mechanism works well at file scope as well, by using an unnamed
 | 
						|
namespace, we can ensure that these declarations don't conflict with any
 | 
						|
alternate policies present in other translation units:
 | 
						|
 | 
						|
[import ../../example/policy_eg_5.cpp]
 | 
						|
 | 
						|
[policy_eg_5]
 | 
						|
 | 
						|
Handling policies for the statistical distributions is very similar except that now
 | 
						|
the macro BOOST_MATH_DECLARE_DISTRIBUTIONS accepts two parameters: the
 | 
						|
floating point type to use, and the policy type to apply.  For example:
 | 
						|
 | 
						|
   BOOST_MATH_DECLARE_DISTRIBUTIONS(double, mypolicy)
 | 
						|
 | 
						|
Results a set of typedefs being defined like this:
 | 
						|
 | 
						|
   typedef boost::math::normal_distribution<double, mypolicy> normal;
 | 
						|
 | 
						|
The name of each typedef is the same as the name of the distribution
 | 
						|
class template, but without the "_distribution" suffix.
 | 
						|
 | 
						|
[import ../../example/policy_eg_6.cpp]
 | 
						|
 | 
						|
[policy_eg_6]
 | 
						|
 | 
						|
[note
 | 
						|
There is an important limitation to note: you can *not use the macros
 | 
						|
BOOST_MATH_DECLARE_DISTRIBUTIONS and BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS
 | 
						|
['in the same namespace]*,  as doing so creates ambiguities between functions
 | 
						|
and distributions of the same name.
 | 
						|
]
 | 
						|
 | 
						|
As before, the same mechanism works well at file scope as well: by using an unnamed
 | 
						|
namespace, we can ensure that these declarations don't conflict with any
 | 
						|
alternate policies present in other translation units:
 | 
						|
 | 
						|
[import ../../example/policy_eg_7.cpp]
 | 
						|
 | 
						|
[policy_eg_7]
 | 
						|
 | 
						|
[endsect][/section:namespace_policies Setting Policies at Namespace or Translation Unit Scope]
 | 
						|
 | 
						|
[section:user_def_err_pol Calling User Defined Error Handlers]
 | 
						|
 | 
						|
[import ../../example/policy_eg_8.cpp]
 | 
						|
 | 
						|
[policy_eg_8]
 | 
						|
 | 
						|
[import ../../example/policy_eg_9.cpp]
 | 
						|
 | 
						|
[policy_eg_9]
 | 
						|
 | 
						|
[endsect] [/section:user_def_err_pol Calling User Defined Error Handlers]
 | 
						|
 | 
						|
[section:understand_dis_quant Understanding Quantiles of Discrete Distributions]
 | 
						|
 | 
						|
Discrete distributions present us with a problem when calculating the
 | 
						|
quantile: we are starting from a continuous real-valued variable - the
 | 
						|
probability - but the result (the value of the random variable)
 | 
						|
should really be discrete.
 | 
						|
 | 
						|
Consider for example a Binomial distribution, with a sample size of
 | 
						|
50, and a success fraction of 0.5.  There are a variety of ways
 | 
						|
we can plot a discrete distribution, but if we plot the PDF
 | 
						|
as a step-function then it looks something like this:
 | 
						|
 | 
						|
[$../graphs/binomial_pdf.png]
 | 
						|
 | 
						|
Now lets suppose that the user asks for a the quantile that corresponds
 | 
						|
to a probability of 0.05, if we zoom in on the CDF for that region here's
 | 
						|
what we see:
 | 
						|
 | 
						|
[$../graphs/binomial_quantile_1.png]
 | 
						|
 | 
						|
As can be seen there is no random variable that corresponds to
 | 
						|
a probability of exactly 0.05, so we're left with two choices as
 | 
						|
shown in the figure:
 | 
						|
 | 
						|
* We could round the result down to 18.
 | 
						|
* We could round the result up to 19.
 | 
						|
 | 
						|
In fact there's actually a third choice as well: we could "pretend" that the
 | 
						|
distribution was continuous and return a real valued result: in this case we
 | 
						|
would calculate a result of approximately 18.701 (this accurately
 | 
						|
reflects the fact that the result is nearer to 19 than 18).
 | 
						|
 | 
						|
By using policies we can offer any of the above as options, but that
 | 
						|
still leaves the question: ['What is actually the right thing to do?]
 | 
						|
 | 
						|
And in particular: ['What policy should we use by default?]
 | 
						|
 | 
						|
In coming to an answer we should realise that:
 | 
						|
 | 
						|
* Calculating an integer result is often much faster than
 | 
						|
calculating a real-valued result: in fact in our tests it
 | 
						|
was up to 20 times faster.
 | 
						|
* Normally people calculate quantiles so that they can perform
 | 
						|
a test of some kind: ['"If the random variable is less than N
 | 
						|
then we can reject our null-hypothesis with 90% confidence."]
 | 
						|
 | 
						|
So there is a genuine benefit to calculating an integer result
 | 
						|
as well as it being "the right thing to do" from a philosophical
 | 
						|
point of view.  What's more if someone asks for a quantile at 0.05,
 | 
						|
then we can normally assume that they are asking for
 | 
						|
['[*at least] 95% of the probability to the right of the value chosen,
 | 
						|
and [*no more than] 5% of the probability to the left of the value chosen.]
 | 
						|
 | 
						|
In the above binomial example we would therefore round the result down to 18.
 | 
						|
 | 
						|
The converse applies to upper-quantiles: If the probability is greater than
 | 
						|
0.5 we would want to round the quantile up, ['so that [*at least] the requested
 | 
						|
probability is to the left of the value returned, and [*no more than] 1 - the
 | 
						|
requested probability is to the right of the value returned.]
 | 
						|
 | 
						|
Likewise for two-sided intervals, we would round lower quantiles down,
 | 
						|
and upper quantiles up.  This ensures that we have ['at least the requested
 | 
						|
probability in the central region] and ['no more than 1 minus the requested
 | 
						|
probability in the tail areas.]
 | 
						|
 | 
						|
For example, taking our 50 sample binomial distribution with a success fraction
 | 
						|
of 0.5, if we wanted a two sided 90% confidence interval, then we would ask
 | 
						|
for the 0.05 and 0.95 quantiles with the results ['rounded outwards] so that
 | 
						|
['at least 90% of the probability] is in the central area:
 | 
						|
 | 
						|
[$../graphs/binomial_pdf_3.png]
 | 
						|
 | 
						|
So far so good, but there is in fact a trap waiting for the unwary here:
 | 
						|
 | 
						|
   quantile(binomial(50, 0.5), 0.05);
 | 
						|
 | 
						|
returns 18 as the result, which is what we would expect from the graph above,
 | 
						|
and indeed there is no x greater than 18 for which:
 | 
						|
 | 
						|
   cdf(binomial(50, 0.5), x) <= 0.05;
 | 
						|
 | 
						|
However:
 | 
						|
 | 
						|
   quantile(binomial(50, 0.5), 0.95);
 | 
						|
 | 
						|
returns 31, and indeed while there is no x less than 31 for which:
 | 
						|
 | 
						|
   cdf(binomial(50, 0.5), x) >= 0.95;
 | 
						|
 | 
						|
We might naively expect that for this symmetrical distribution the result
 | 
						|
would be 32 (since 32 = 50 - 18), but we need to remember that the cdf of
 | 
						|
the binomial is /inclusive/ of the random variable.  So while the left tail
 | 
						|
area /includes/ the quantile returned, the right tail area always excludes
 | 
						|
an upper quantile value: since that "belongs" to the central area.
 | 
						|
 | 
						|
Look at the graph above to see what's going on here: the lower quantile
 | 
						|
of 18 belongs to the left tail, so any value <= 18 is in the left tail.
 | 
						|
The upper quantile of 31 on the other hand belongs to the central area,
 | 
						|
so the tail area actually starts at 32, so any value > 31 is in the
 | 
						|
right tail.
 | 
						|
 | 
						|
Therefore if U and L are the upper and lower quantiles respectively, then
 | 
						|
a random variable X is in the tail area - where we would reject the null
 | 
						|
hypothesis if:
 | 
						|
 | 
						|
   X <= L || X > U
 | 
						|
 | 
						|
And the a variable X is inside the central region if:
 | 
						|
 | 
						|
   L < X <= U
 | 
						|
 | 
						|
The moral here is to ['always be very careful with your comparisons
 | 
						|
when dealing with a discrete distribution], and if in doubt,
 | 
						|
['base your comparisons on CDF's instead].
 | 
						|
 | 
						|
[heading Other Rounding Policies are Available]
 | 
						|
 | 
						|
As you would expect from a section on policies, you won't be surprised
 | 
						|
to know that other rounding options are available:
 | 
						|
 | 
						|
[variablelist
 | 
						|
 | 
						|
[[integer_round_outwards]
 | 
						|
   [This is the default policy as described above: lower quantiles
 | 
						|
   are rounded down (probability < 0.5), and upper quantiles
 | 
						|
   (probability > 0.5) are rounded up.
 | 
						|
 | 
						|
   This gives /no more than/ the requested probability
 | 
						|
   in the tails, and /at least/ the requested probability
 | 
						|
   in the central area.]]
 | 
						|
[[integer_round_inwards]
 | 
						|
   [This is the exact opposite of the default policy:
 | 
						|
   lower quantiles
 | 
						|
   are rounded up (probability < 0.5),
 | 
						|
   and upper quantiles (probability > 0.5) are rounded down.
 | 
						|
 | 
						|
   This gives /at least/ the requested probability
 | 
						|
   in the tails, and /no more than/ the requested probability
 | 
						|
   in the central area.]]
 | 
						|
[[integer_round_down][This policy will always round the result down
 | 
						|
   no matter whether it is an upper or lower quantile]]
 | 
						|
[[integer_round_up][This policy will always round the result up
 | 
						|
   no matter whether it is an upper or lower quantile]]
 | 
						|
[[integer_round_nearest][This policy will always round the result
 | 
						|
   to the nearest integer
 | 
						|
   no matter whether it is an upper or lower quantile]]
 | 
						|
[[real][This policy will return a real valued result
 | 
						|
   for the quantile of a discrete distribution: this is
 | 
						|
   generally much slower than finding an integer result
 | 
						|
   but does allow for more sophisticated rounding policies.]]
 | 
						|
 | 
						|
]
 | 
						|
 | 
						|
[import ../../example/policy_eg_10.cpp]
 | 
						|
 | 
						|
[policy_eg_10]
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[endsect] [/section:pol_Tutorial Policy Tutorial]
 | 
						|
 | 
						|
 | 
						|
[/ math.qbk
 | 
						|
  Copyright 2007, 2013 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).
 | 
						|
]
 | 
						|
 | 
						|
 |