]>
Commit | Line | Data |
---|---|---|
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_LOCATION_HPP | |
9 | #define BOOST_STATS_FIND_LOCATION_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 | #include <boost/math/tools/traits.hpp> | |
7c673cae FG |
15 | #include <boost/math/special_functions/fpclassify.hpp> |
16 | #include <boost/math/policies/error_handling.hpp> | |
17 | // using boost::math::policies::policy; | |
18 | // using boost::math::complement; // will be needed by users who want complement, | |
19 | // but NOT placed here to avoid putting it in global scope. | |
20 | ||
21 | namespace boost | |
22 | { | |
23 | namespace math | |
24 | { | |
25 | // Function to find location of random variable z | |
26 | // to give probability p (given scale) | |
27 | // Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular), | |
1e59de90 | 28 | // enforced by static_assert below. |
7c673cae FG |
29 | |
30 | template <class Dist, class Policy> | |
31 | inline | |
32 | typename Dist::value_type find_location( // For example, normal mean. | |
33 | typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. | |
34 | // For example, a nominal minimum acceptable z, so that p * 100 % are > z | |
35 | typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. | |
36 | typename Dist::value_type scale, // scale parameter, for example, normal standard deviation. | |
37 | const Policy& pol | |
38 | ) | |
39 | { | |
1e59de90 TL |
40 | static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution."); |
41 | 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 |
42 | static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)"; |
43 | ||
44 | if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) | |
45 | { | |
46 | return policies::raise_domain_error<typename Dist::value_type>( | |
47 | function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol); | |
48 | } | |
49 | if(!(boost::math::isfinite)(z)) | |
50 | { | |
51 | return policies::raise_domain_error<typename Dist::value_type>( | |
52 | function, "z parameter was %1%, but must be finite!", z, pol); | |
53 | } | |
54 | if(!(boost::math::isfinite)(scale)) | |
55 | { | |
56 | return policies::raise_domain_error<typename Dist::value_type>( | |
57 | function, "scale parameter was %1%, but must be finite!", scale, pol); | |
58 | } | |
59 | ||
60 | //cout << "z " << z << ", p " << p << ", quantile(Dist(), p) " | |
61 | // << quantile(Dist(), p) << ", quan * scale " << quantile(Dist(), p) * scale << endl; | |
62 | return z - (quantile(Dist(), p) * scale); | |
63 | } // find_location | |
64 | ||
65 | template <class Dist> | |
66 | inline // with default policy. | |
67 | typename Dist::value_type find_location( // For example, normal mean. | |
68 | typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. | |
69 | // For example, a nominal minimum acceptable z, so that p * 100 % are > z | |
70 | typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. | |
71 | typename Dist::value_type scale) // scale parameter, for example, normal standard deviation. | |
72 | { // Forward to find_location with default policy. | |
73 | return (find_location<Dist>(z, p, scale, policies::policy<>())); | |
74 | } // find_location | |
75 | ||
76 | // So the user can start from the complement q = (1 - p) of the probability p, | |
77 | // for example, l = find_location<normal>(complement(z, q, sd)); | |
78 | ||
79 | template <class Dist, class Real1, class Real2, class Real3> | |
80 | inline typename Dist::value_type find_location( // Default policy. | |
81 | complemented3_type<Real1, Real2, Real3> const& c) | |
82 | { | |
83 | static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)"; | |
84 | ||
85 | typename Dist::value_type p = c.param1; | |
86 | if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) | |
87 | { | |
88 | return policies::raise_domain_error<typename Dist::value_type>( | |
89 | function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, policies::policy<>()); | |
90 | } | |
91 | typename Dist::value_type z = c.dist; | |
92 | if(!(boost::math::isfinite)(z)) | |
93 | { | |
94 | return policies::raise_domain_error<typename Dist::value_type>( | |
95 | function, "z parameter was %1%, but must be finite!", z, policies::policy<>()); | |
96 | } | |
97 | typename Dist::value_type scale = c.param2; | |
98 | if(!(boost::math::isfinite)(scale)) | |
99 | { | |
100 | return policies::raise_domain_error<typename Dist::value_type>( | |
101 | function, "scale parameter was %1%, but must be finite!", scale, policies::policy<>()); | |
102 | } | |
103 | // cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl; | |
104 | return z - quantile(Dist(), p) * scale; | |
105 | } // find_location complement | |
106 | ||
107 | ||
108 | template <class Dist, class Real1, class Real2, class Real3, class Real4> | |
109 | inline typename Dist::value_type find_location( // Explicit policy. | |
110 | complemented4_type<Real1, Real2, Real3, Real4> const& c) | |
111 | { | |
112 | static const char* function = "boost::math::find_location<Dist, Policy>&, %1%)"; | |
113 | ||
114 | typename Dist::value_type p = c.param1; | |
115 | if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) | |
116 | { | |
117 | return policies::raise_domain_error<typename Dist::value_type>( | |
118 | function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, c.param3); | |
119 | } | |
120 | typename Dist::value_type z = c.dist; | |
121 | if(!(boost::math::isfinite)(z)) | |
122 | { | |
123 | return policies::raise_domain_error<typename Dist::value_type>( | |
124 | function, "z parameter was %1%, but must be finite!", z, c.param3); | |
125 | } | |
126 | typename Dist::value_type scale = c.param2; | |
127 | if(!(boost::math::isfinite)(scale)) | |
128 | { | |
129 | return policies::raise_domain_error<typename Dist::value_type>( | |
130 | function, "scale parameter was %1%, but must be finite!", scale, c.param3); | |
131 | } | |
132 | // cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl; | |
133 | return z - quantile(Dist(), p) * scale; | |
134 | } // find_location complement | |
135 | ||
136 | } // namespace boost | |
137 | } // namespace math | |
138 | ||
139 | #endif // BOOST_STATS_FIND_LOCATION_HPP | |
140 |