]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/math/distributions/find_scale.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / math / distributions / find_scale.hpp
CommitLineData
7c673cae
FG
1// Copyright John Maddock 2007.
2// Copyright Paul A. Bristow 2007.
3
4// Use, modification and distribution are subject to the
5// Boost Software License, Version 1.0. (See accompanying file
6// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#ifndef BOOST_STATS_FIND_SCALE_HPP
9#define BOOST_STATS_FIND_SCALE_HPP
10
11#include <boost/math/distributions/fwd.hpp> // for all distribution signatures.
12#include <boost/math/distributions/complement.hpp>
13#include <boost/math/policies/policy.hpp>
14// using boost::math::policies::policy;
15#include <boost/math/tools/traits.hpp>
1e59de90 16#include <boost/math/tools/assert.hpp>
7c673cae
FG
17#include <boost/math/special_functions/fpclassify.hpp>
18#include <boost/math/policies/error_handling.hpp>
19// using boost::math::complement; // will be needed by users who want complement,
20// but NOT placed here to avoid putting it in global scope.
21
22namespace boost
23{
24 namespace math
25 {
26 // Function to find location of random variable z
27 // to give probability p (given scale)
28 // Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular),
29 // distributions that have scale.
30 // BOOST_STATIC_ASSERTs, see below, are used to enforce this.
31
32 template <class Dist, class Policy>
33 inline
34 typename Dist::value_type find_scale( // For example, normal mean.
35 typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
36 // For example, a nominal minimum acceptable weight z, so that p * 100 % are > z
37 typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
38 typename Dist::value_type location, // location parameter, for example, normal distribution mean.
39 const Policy& pol
40 )
41 {
1e59de90
TL
42 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
43 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
7c673cae
FG
44 static const char* function = "boost::math::find_scale<Dist, Policy>(%1%, %1%, %1%, Policy)";
45
46 if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
47 {
48 return policies::raise_domain_error<typename Dist::value_type>(
49 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol);
50 }
51 if(!(boost::math::isfinite)(z))
52 {
53 return policies::raise_domain_error<typename Dist::value_type>(
54 function, "find_scale z parameter was %1%, but must be finite!", z, pol);
55 }
56 if(!(boost::math::isfinite)(location))
57 {
58 return policies::raise_domain_error<typename Dist::value_type>(
59 function, "find_scale location parameter was %1%, but must be finite!", location, pol);
60 }
61
62 //cout << "z " << z << ", p " << p << ", quantile(Dist(), p) "
63 //<< quantile(Dist(), p) << ", z - mean " << z - location
64 //<<", sd " << (z - location) / quantile(Dist(), p) << endl;
65
66 //quantile(N01, 0.001) -3.09023
67 //quantile(N01, 0.01) -2.32635
68 //quantile(N01, 0.05) -1.64485
69 //quantile(N01, 0.333333) -0.430728
70 //quantile(N01, 0.5) 0
71 //quantile(N01, 0.666667) 0.430728
72 //quantile(N01, 0.9) 1.28155
73 //quantile(N01, 0.95) 1.64485
74 //quantile(N01, 0.99) 2.32635
75 //quantile(N01, 0.999) 3.09023
76
77 typename Dist::value_type result =
78 (z - location) // difference between desired x and current location.
79 / quantile(Dist(), p); // standard distribution.
80
81 if (result <= 0)
82 { // If policy isn't to throw, return the scale <= 0.
83 policies::raise_evaluation_error<typename Dist::value_type>(function,
84 "Computed scale (%1%) is <= 0!" " Was the complement intended?",
85 result, Policy());
86 }
87 return result;
88 } // template <class Dist, class Policy> find_scale
89
90 template <class Dist>
91 inline // with default policy.
92 typename Dist::value_type find_scale( // For example, normal mean.
93 typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
94 // For example, a nominal minimum acceptable z, so that p * 100 % are > z
95 typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
96 typename Dist::value_type location) // location parameter, for example, mean.
97 { // Forward to find_scale using the default policy.
98 return (find_scale<Dist>(z, p, location, policies::policy<>()));
99 } // find_scale
100
101 template <class Dist, class Real1, class Real2, class Real3, class Policy>
102 inline typename Dist::value_type find_scale(
103 complemented4_type<Real1, Real2, Real3, Policy> const& c)
104 {
105 //cout << "cparam1 q " << c.param1 // q
106 // << ", c.dist z " << c.dist // z
107 // << ", c.param2 l " << c.param2 // l
108 // << ", quantile (Dist(), c.param1 = q) "
109 // << quantile(Dist(), c.param1) //q
110 // << endl;
111
1e59de90
TL
112 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
113 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
7c673cae
FG
114 static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
115
116 // Checks on arguments, as not complemented version,
117 // Explicit policy.
118 typename Dist::value_type q = c.param1;
119 if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
120 {
121 return policies::raise_domain_error<typename Dist::value_type>(
122 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, c.param3);
123 }
124 typename Dist::value_type z = c.dist;
125 if(!(boost::math::isfinite)(z))
126 {
127 return policies::raise_domain_error<typename Dist::value_type>(
128 function, "find_scale z parameter was %1%, but must be finite!", z, c.param3);
129 }
130 typename Dist::value_type location = c.param2;
131 if(!(boost::math::isfinite)(location))
132 {
133 return policies::raise_domain_error<typename Dist::value_type>(
134 function, "find_scale location parameter was %1%, but must be finite!", location, c.param3);
135 }
136
137 typename Dist::value_type result =
138 (c.dist - c.param2) // difference between desired x and current location.
139 / quantile(complement(Dist(), c.param1));
140 // ( z - location) / (quantile(complement(Dist(), q))
141 if (result <= 0)
142 { // If policy isn't to throw, return the scale <= 0.
143 policies::raise_evaluation_error<typename Dist::value_type>(function,
144 "Computed scale (%1%) is <= 0!" " Was the complement intended?",
145 result, Policy());
146 }
147 return result;
148 } // template <class Dist, class Policy, class Real1, class Real2, class Real3> typename Dist::value_type find_scale
149
150 // So the user can start from the complement q = (1 - p) of the probability p,
151 // for example, s = find_scale<normal>(complement(z, q, l));
152
153 template <class Dist, class Real1, class Real2, class Real3>
154 inline typename Dist::value_type find_scale(
155 complemented3_type<Real1, Real2, Real3> const& c)
156 {
157 //cout << "cparam1 q " << c.param1 // q
158 // << ", c.dist z " << c.dist // z
159 // << ", c.param2 l " << c.param2 // l
160 // << ", quantile (Dist(), c.param1 = q) "
161 // << quantile(Dist(), c.param1) //q
162 // << endl;
163
1e59de90
TL
164 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
165 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
7c673cae
FG
166 static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
167
168 // Checks on arguments, as not complemented version,
169 // default policy policies::policy<>().
170 typename Dist::value_type q = c.param1;
171 if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
172 {
173 return policies::raise_domain_error<typename Dist::value_type>(
174 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, policies::policy<>());
175 }
176 typename Dist::value_type z = c.dist;
177 if(!(boost::math::isfinite)(z))
178 {
179 return policies::raise_domain_error<typename Dist::value_type>(
180 function, "find_scale z parameter was %1%, but must be finite!", z, policies::policy<>());
181 }
182 typename Dist::value_type location = c.param2;
183 if(!(boost::math::isfinite)(location))
184 {
185 return policies::raise_domain_error<typename Dist::value_type>(
186 function, "find_scale location parameter was %1%, but must be finite!", location, policies::policy<>());
187 }
188
189 typename Dist::value_type result =
190 (z - location) // difference between desired x and current location.
191 / quantile(complement(Dist(), q));
192 // ( z - location) / (quantile(complement(Dist(), q))
193 if (result <= 0)
194 { // If policy isn't to throw, return the scale <= 0.
195 policies::raise_evaluation_error<typename Dist::value_type>(function,
196 "Computed scale (%1%) is <= 0!" " Was the complement intended?",
197 result, policies::policy<>()); // This is only the default policy - also Want a version with Policy here.
198 }
199 return result;
200 } // template <class Dist, class Real1, class Real2, class Real3> typename Dist::value_type find_scale
201
202 } // namespace boost
203} // namespace math
204
205#endif // BOOST_STATS_FIND_SCALE_HPP