Mercurial > hg > sv-dependency-builds
comparison any/include/boost/math/distributions/detail/generic_mode.hpp @ 160:cff480c41f97
Add some cross-platform Boost headers
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Sat, 16 Feb 2019 16:31:25 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
159:f4b37539fcc7 | 160:cff480c41f97 |
---|---|
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 |