To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.
root / any / include / boost / math / distributions / detail / generic_mode.hpp @ 160:cff480c41f97
History | View | Annotate | Download (4.39 KB)
| 1 |
// Copyright John Maddock 2008.
|
|---|---|
| 2 |
|
| 3 |
// Use, modification and distribution are subject to the
|
| 4 |
// Boost Software License, Version 1.0.
|
| 5 |
// (See accompanying file LICENSE_1_0.txt
|
| 6 |
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
| 7 |
|
| 8 |
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
|
| 9 |
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
|
| 10 |
|
| 11 |
#include <boost/math/tools/minima.hpp> // function minimization for mode |
| 12 |
#include <boost/math/policies/error_handling.hpp> |
| 13 |
#include <boost/math/distributions/fwd.hpp> |
| 14 |
|
| 15 |
namespace boost{ namespace math{ namespace detail{ |
| 16 |
|
| 17 |
template <class Dist> |
| 18 |
struct pdf_minimizer
|
| 19 |
{
|
| 20 |
pdf_minimizer(const Dist& d)
|
| 21 |
: dist(d) {}
|
| 22 |
|
| 23 |
typename Dist::value_type operator()(const typename Dist::value_type& x) |
| 24 |
{
|
| 25 |
return -pdf(dist, x);
|
| 26 |
} |
| 27 |
private:
|
| 28 |
Dist dist; |
| 29 |
}; |
| 30 |
|
| 31 |
template <class Dist> |
| 32 |
typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::value_type guess, const char* function, typename Dist::value_type step = 0) |
| 33 |
{
|
| 34 |
BOOST_MATH_STD_USING |
| 35 |
typedef typename Dist::value_type value_type; |
| 36 |
typedef typename Dist::policy_type policy_type; |
| 37 |
//
|
| 38 |
// Need to begin by bracketing the maxima of the PDF:
|
| 39 |
//
|
| 40 |
value_type maxval; |
| 41 |
value_type upper_bound = guess; |
| 42 |
value_type lower_bound; |
| 43 |
value_type v = pdf(dist, guess); |
| 44 |
if(v == 0) |
| 45 |
{
|
| 46 |
//
|
| 47 |
// Oops we don't know how to handle this, or even in which
|
| 48 |
// direction we should move in, treat as an evaluation error:
|
| 49 |
//
|
| 50 |
return policies::raise_evaluation_error(
|
| 51 |
function, |
| 52 |
"Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type());
|
| 53 |
} |
| 54 |
do
|
| 55 |
{
|
| 56 |
maxval = v; |
| 57 |
if(step != 0) |
| 58 |
upper_bound += step; |
| 59 |
else
|
| 60 |
upper_bound *= 2;
|
| 61 |
v = pdf(dist, upper_bound); |
| 62 |
}while(maxval < v);
|
| 63 |
|
| 64 |
lower_bound = upper_bound; |
| 65 |
do
|
| 66 |
{
|
| 67 |
maxval = v; |
| 68 |
if(step != 0) |
| 69 |
lower_bound -= step; |
| 70 |
else
|
| 71 |
lower_bound /= 2;
|
| 72 |
v = pdf(dist, lower_bound); |
| 73 |
}while(maxval < v);
|
| 74 |
|
| 75 |
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>(); |
| 76 |
|
| 77 |
value_type result = tools::brent_find_minima( |
| 78 |
pdf_minimizer<Dist>(dist), |
| 79 |
lower_bound, |
| 80 |
upper_bound, |
| 81 |
policies::digits<value_type, policy_type>(), |
| 82 |
max_iter).first; |
| 83 |
if(max_iter >= policies::get_max_root_iterations<policy_type>())
|
| 84 |
{
|
| 85 |
return policies::raise_evaluation_error<value_type>(
|
| 86 |
function, |
| 87 |
"Unable to locate solution in a reasonable time:"
|
| 88 |
" either there is no answer to the mode of the distribution"
|
| 89 |
" or the answer is infinite. Current best guess is %1%", result, policy_type());
|
| 90 |
} |
| 91 |
return result;
|
| 92 |
} |
| 93 |
//
|
| 94 |
// As above,but confined to the interval [0,1]:
|
| 95 |
//
|
| 96 |
template <class Dist> |
| 97 |
typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function) |
| 98 |
{
|
| 99 |
BOOST_MATH_STD_USING |
| 100 |
typedef typename Dist::value_type value_type; |
| 101 |
typedef typename Dist::policy_type policy_type; |
| 102 |
//
|
| 103 |
// Need to begin by bracketing the maxima of the PDF:
|
| 104 |
//
|
| 105 |
value_type maxval; |
| 106 |
value_type upper_bound = guess; |
| 107 |
value_type lower_bound; |
| 108 |
value_type v = pdf(dist, guess); |
| 109 |
do
|
| 110 |
{
|
| 111 |
maxval = v; |
| 112 |
upper_bound = 1 - (1 - upper_bound) / 2; |
| 113 |
if(upper_bound == 1) |
| 114 |
return 1; |
| 115 |
v = pdf(dist, upper_bound); |
| 116 |
}while(maxval < v);
|
| 117 |
|
| 118 |
lower_bound = upper_bound; |
| 119 |
do
|
| 120 |
{
|
| 121 |
maxval = v; |
| 122 |
lower_bound /= 2;
|
| 123 |
if(lower_bound < tools::min_value<value_type>())
|
| 124 |
return 0; |
| 125 |
v = pdf(dist, lower_bound); |
| 126 |
}while(maxval < v);
|
| 127 |
|
| 128 |
boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>(); |
| 129 |
|
| 130 |
value_type result = tools::brent_find_minima( |
| 131 |
pdf_minimizer<Dist>(dist), |
| 132 |
lower_bound, |
| 133 |
upper_bound, |
| 134 |
policies::digits<value_type, policy_type>(), |
| 135 |
max_iter).first; |
| 136 |
if(max_iter >= policies::get_max_root_iterations<policy_type>())
|
| 137 |
{
|
| 138 |
return policies::raise_evaluation_error<value_type>(
|
| 139 |
function, |
| 140 |
"Unable to locate solution in a reasonable time:"
|
| 141 |
" either there is no answer to the mode of the distribution"
|
| 142 |
" or the answer is infinite. Current best guess is %1%", result, policy_type());
|
| 143 |
} |
| 144 |
return result;
|
| 145 |
} |
| 146 |
|
| 147 |
}}} // namespaces
|
| 148 |
|
| 149 |
#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP |