1 // Copyright John Maddock 2008.
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)
8 #ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
9 #define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
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>
15 namespace boost{ namespace math{ namespace detail{
20 pdf_minimizer(const Dist& d)
23 typename Dist::value_type operator()(const typename Dist::value_type& x)
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)
35 typedef typename Dist::value_type value_type;
36 typedef typename Dist::policy_type policy_type;
38 // Need to begin by bracketing the maxima of the PDF:
41 value_type upper_bound = guess;
42 value_type lower_bound;
43 value_type v = pdf(dist, guess);
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:
50 return policies::raise_evaluation_error(
52 "Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type());
61 v = pdf(dist, upper_bound);
64 lower_bound = upper_bound;
72 v = pdf(dist, lower_bound);
75 boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
77 value_type result = tools::brent_find_minima(
78 pdf_minimizer<Dist>(dist),
81 policies::digits<value_type, policy_type>(),
83 if(max_iter >= policies::get_max_root_iterations<policy_type>())
85 return policies::raise_evaluation_error<value_type>(
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());
94 // As above,but confined to the interval [0,1]:
97 typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function)
100 typedef typename Dist::value_type value_type;
101 typedef typename Dist::policy_type policy_type;
103 // Need to begin by bracketing the maxima of the PDF:
106 value_type upper_bound = guess;
107 value_type lower_bound;
108 value_type v = pdf(dist, guess);
112 upper_bound = 1 - (1 - upper_bound) / 2;
115 v = pdf(dist, upper_bound);
118 lower_bound = upper_bound;
123 if(lower_bound < tools::min_value<value_type>())
125 v = pdf(dist, lower_bound);
128 boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
130 value_type result = tools::brent_find_minima(
131 pdf_minimizer<Dist>(dist),
134 policies::digits<value_type, policy_type>(),
136 if(max_iter >= policies::get_max_root_iterations<policy_type>())
138 return policies::raise_evaluation_error<value_type>(
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());
149 #endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP