Chris@102
|
1 // boost/math/distributions/arcsine.hpp
|
Chris@102
|
2
|
Chris@102
|
3 // Copyright John Maddock 2014.
|
Chris@102
|
4 // Copyright Paul A. Bristow 2014.
|
Chris@102
|
5
|
Chris@102
|
6 // Use, modification and distribution are subject to the
|
Chris@102
|
7 // Boost Software License, Version 1.0.
|
Chris@102
|
8 // (See accompanying file LICENSE_1_0.txt
|
Chris@102
|
9 // or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
10
|
Chris@102
|
11 // http://en.wikipedia.org/wiki/arcsine_distribution
|
Chris@102
|
12
|
Chris@102
|
13 // The arcsine Distribution is a continuous probability distribution.
|
Chris@102
|
14 // http://en.wikipedia.org/wiki/Arcsine_distribution
|
Chris@102
|
15 // http://www.wolframalpha.com/input/?i=ArcSinDistribution
|
Chris@102
|
16
|
Chris@102
|
17 // Standard arcsine distribution is a special case of beta distribution with both a & b = one half,
|
Chris@102
|
18 // and 0 <= x <= 1.
|
Chris@102
|
19
|
Chris@102
|
20 // It is generalized to include any bounded support a <= x <= b from 0 <= x <= 1
|
Chris@102
|
21 // by Wolfram and Wikipedia,
|
Chris@102
|
22 // but using location and scale parameters by
|
Chris@102
|
23 // Virtual Laboratories in Probability and Statistics http://www.math.uah.edu/stat/index.html
|
Chris@102
|
24 // http://www.math.uah.edu/stat/special/Arcsine.html
|
Chris@102
|
25 // The end-point version is simpler and more obvious, so we implement that.
|
Chris@102
|
26 // TODO Perhaps provide location and scale functions?
|
Chris@102
|
27
|
Chris@102
|
28
|
Chris@102
|
29 #ifndef BOOST_MATH_DIST_ARCSINE_HPP
|
Chris@102
|
30 #define BOOST_MATH_DIST_ARCSINE_HPP
|
Chris@102
|
31
|
Chris@102
|
32 #include <boost/math/distributions/fwd.hpp>
|
Chris@102
|
33 #include <boost/math/distributions/complement.hpp> // complements.
|
Chris@102
|
34 #include <boost/math/distributions/detail/common_error_handling.hpp> // error checks.
|
Chris@102
|
35 #include <boost/math/constants/constants.hpp>
|
Chris@102
|
36
|
Chris@102
|
37 #include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
Chris@102
|
38
|
Chris@102
|
39 #if defined (BOOST_MSVC)
|
Chris@102
|
40 # pragma warning(push)
|
Chris@102
|
41 # pragma warning(disable: 4702) // Unreachable code,
|
Chris@102
|
42 // in domain_error_imp in error_handling.
|
Chris@102
|
43 #endif
|
Chris@102
|
44
|
Chris@102
|
45 #include <utility>
|
Chris@102
|
46 #include <exception> // For std::domain_error.
|
Chris@102
|
47
|
Chris@102
|
48 namespace boost
|
Chris@102
|
49 {
|
Chris@102
|
50 namespace math
|
Chris@102
|
51 {
|
Chris@102
|
52 namespace arcsine_detail
|
Chris@102
|
53 {
|
Chris@102
|
54 // Common error checking routines for arcsine distribution functions:
|
Chris@102
|
55 // Duplicating for x_min and x_max provides specific error messages.
|
Chris@102
|
56 template <class RealType, class Policy>
|
Chris@102
|
57 inline bool check_x_min(const char* function, const RealType& x, RealType* result, const Policy& pol)
|
Chris@102
|
58 {
|
Chris@102
|
59 if (!(boost::math::isfinite)(x))
|
Chris@102
|
60 {
|
Chris@102
|
61 *result = policies::raise_domain_error<RealType>(
|
Chris@102
|
62 function,
|
Chris@102
|
63 "x_min argument is %1%, but must be finite !", x, pol);
|
Chris@102
|
64 return false;
|
Chris@102
|
65 }
|
Chris@102
|
66 return true;
|
Chris@102
|
67 } // bool check_x_min
|
Chris@102
|
68
|
Chris@102
|
69 template <class RealType, class Policy>
|
Chris@102
|
70 inline bool check_x_max(const char* function, const RealType& x, RealType* result, const Policy& pol)
|
Chris@102
|
71 {
|
Chris@102
|
72 if (!(boost::math::isfinite)(x))
|
Chris@102
|
73 {
|
Chris@102
|
74 *result = policies::raise_domain_error<RealType>(
|
Chris@102
|
75 function,
|
Chris@102
|
76 "x_max argument is %1%, but must be finite !", x, pol);
|
Chris@102
|
77 return false;
|
Chris@102
|
78 }
|
Chris@102
|
79 return true;
|
Chris@102
|
80 } // bool check_x_max
|
Chris@102
|
81
|
Chris@102
|
82
|
Chris@102
|
83 template <class RealType, class Policy>
|
Chris@102
|
84 inline bool check_x_minmax(const char* function, const RealType& x_min, const RealType& x_max, RealType* result, const Policy& pol)
|
Chris@102
|
85 { // Check x_min < x_max
|
Chris@102
|
86 if (x_min >= x_max)
|
Chris@102
|
87 {
|
Chris@102
|
88 std::string msg = "x_max argument is %1%, but must be > x_min = " + lexical_cast<std::string>(x_min) + "!";
|
Chris@102
|
89 *result = policies::raise_domain_error<RealType>(
|
Chris@102
|
90 function,
|
Chris@102
|
91 msg.c_str(), x_max, pol);
|
Chris@102
|
92 // "x_max argument is %1%, but must be > x_min !", x_max, pol);
|
Chris@102
|
93 // "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better.
|
Chris@102
|
94 // But would require replication of all helpers functions in /policies/error_handling.hpp for two values,
|
Chris@102
|
95 // as well as two value versions of raise_error, raise_domain_error and do_format ...
|
Chris@102
|
96 // so use slightly hacky lexical_cast to string instead.
|
Chris@102
|
97 return false;
|
Chris@102
|
98 }
|
Chris@102
|
99 return true;
|
Chris@102
|
100 } // bool check_x_minmax
|
Chris@102
|
101
|
Chris@102
|
102 template <class RealType, class Policy>
|
Chris@102
|
103 inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol)
|
Chris@102
|
104 {
|
Chris@102
|
105 if ((p < 0) || (p > 1) || !(boost::math::isfinite)(p))
|
Chris@102
|
106 {
|
Chris@102
|
107 *result = policies::raise_domain_error<RealType>(
|
Chris@102
|
108 function,
|
Chris@102
|
109 "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
Chris@102
|
110 return false;
|
Chris@102
|
111 }
|
Chris@102
|
112 return true;
|
Chris@102
|
113 } // bool check_prob
|
Chris@102
|
114
|
Chris@102
|
115 template <class RealType, class Policy>
|
Chris@102
|
116 inline bool check_x(const char* function, const RealType& x_min, const RealType& x_max, const RealType& x, RealType* result, const Policy& pol)
|
Chris@102
|
117 { // Check x finite and x_min < x < x_max.
|
Chris@102
|
118 if (!(boost::math::isfinite)(x))
|
Chris@102
|
119 {
|
Chris@102
|
120 *result = policies::raise_domain_error<RealType>(
|
Chris@102
|
121 function,
|
Chris@102
|
122 "x argument is %1%, but must be finite !", x, pol);
|
Chris@102
|
123 return false;
|
Chris@102
|
124 }
|
Chris@102
|
125 if ((x < x_min) || (x > x_max))
|
Chris@102
|
126 {
|
Chris@102
|
127 // std::cout << x_min << ' ' << x << x_max << std::endl;
|
Chris@102
|
128 *result = policies::raise_domain_error<RealType>(
|
Chris@102
|
129 function,
|
Chris@102
|
130 "x argument is %1%, but must be x_min < x < x_max !", x, pol);
|
Chris@102
|
131 // For example:
|
Chris@102
|
132 // Error in function boost::math::pdf(arcsine_distribution<double> const&, double) : x argument is -1.01, but must be x_min < x < x_max !
|
Chris@102
|
133 // TODO Perhaps show values of x_min and x_max?
|
Chris@102
|
134 return false;
|
Chris@102
|
135 }
|
Chris@102
|
136 return true;
|
Chris@102
|
137 } // bool check_x
|
Chris@102
|
138
|
Chris@102
|
139 template <class RealType, class Policy>
|
Chris@102
|
140 inline bool check_dist(const char* function, const RealType& x_min, const RealType& x_max, RealType* result, const Policy& pol)
|
Chris@102
|
141 { // Check both x_min and x_max finite, and x_min < x_max.
|
Chris@102
|
142 return check_x_min(function, x_min, result, pol)
|
Chris@102
|
143 && check_x_max(function, x_max, result, pol)
|
Chris@102
|
144 && check_x_minmax(function, x_min, x_max, result, pol);
|
Chris@102
|
145 } // bool check_dist
|
Chris@102
|
146
|
Chris@102
|
147 template <class RealType, class Policy>
|
Chris@102
|
148 inline bool check_dist_and_x(const char* function, const RealType& x_min, const RealType& x_max, RealType x, RealType* result, const Policy& pol)
|
Chris@102
|
149 {
|
Chris@102
|
150 return check_dist(function, x_min, x_max, result, pol)
|
Chris@102
|
151 && arcsine_detail::check_x(function, x_min, x_max, x, result, pol);
|
Chris@102
|
152 } // bool check_dist_and_x
|
Chris@102
|
153
|
Chris@102
|
154 template <class RealType, class Policy>
|
Chris@102
|
155 inline bool check_dist_and_prob(const char* function, const RealType& x_min, const RealType& x_max, RealType p, RealType* result, const Policy& pol)
|
Chris@102
|
156 {
|
Chris@102
|
157 return check_dist(function, x_min, x_max, result, pol)
|
Chris@102
|
158 && check_prob(function, p, result, pol);
|
Chris@102
|
159 } // bool check_dist_and_prob
|
Chris@102
|
160
|
Chris@102
|
161 } // namespace arcsine_detail
|
Chris@102
|
162
|
Chris@102
|
163 template <class RealType = double, class Policy = policies::policy<> >
|
Chris@102
|
164 class arcsine_distribution
|
Chris@102
|
165 {
|
Chris@102
|
166 public:
|
Chris@102
|
167 typedef RealType value_type;
|
Chris@102
|
168 typedef Policy policy_type;
|
Chris@102
|
169
|
Chris@102
|
170 arcsine_distribution(RealType x_min = 0, RealType x_max = 1) : m_x_min(x_min), m_x_max(x_max)
|
Chris@102
|
171 { // Default beta (alpha = beta = 0.5) is standard arcsine with x_min = 0, x_max = 1.
|
Chris@102
|
172 // Generalized to allow x_min and x_max to be specified.
|
Chris@102
|
173 RealType result;
|
Chris@102
|
174 arcsine_detail::check_dist(
|
Chris@102
|
175 "boost::math::arcsine_distribution<%1%>::arcsine_distribution",
|
Chris@102
|
176 m_x_min,
|
Chris@102
|
177 m_x_max,
|
Chris@102
|
178 &result, Policy());
|
Chris@102
|
179 } // arcsine_distribution constructor.
|
Chris@102
|
180 // Accessor functions:
|
Chris@102
|
181 RealType x_min() const
|
Chris@102
|
182 {
|
Chris@102
|
183 return m_x_min;
|
Chris@102
|
184 }
|
Chris@102
|
185 RealType x_max() const
|
Chris@102
|
186 {
|
Chris@102
|
187 return m_x_max;
|
Chris@102
|
188 }
|
Chris@102
|
189
|
Chris@102
|
190 private:
|
Chris@102
|
191 RealType m_x_min; // Two x min and x max parameters of the arcsine distribution.
|
Chris@102
|
192 RealType m_x_max;
|
Chris@102
|
193 }; // template <class RealType, class Policy> class arcsine_distribution
|
Chris@102
|
194
|
Chris@102
|
195 // Convenient typedef to construct double version.
|
Chris@102
|
196 typedef arcsine_distribution<double> arcsine;
|
Chris@102
|
197
|
Chris@102
|
198
|
Chris@102
|
199 template <class RealType, class Policy>
|
Chris@102
|
200 inline const std::pair<RealType, RealType> range(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
201 { // Range of permissible values for random variable x.
|
Chris@102
|
202 using boost::math::tools::max_value;
|
Chris@102
|
203 return std::pair<RealType, RealType>(static_cast<RealType>(dist.x_min()), static_cast<RealType>(dist.x_max()));
|
Chris@102
|
204 }
|
Chris@102
|
205
|
Chris@102
|
206 template <class RealType, class Policy>
|
Chris@102
|
207 inline const std::pair<RealType, RealType> support(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
208 { // Range of supported values for random variable x.
|
Chris@102
|
209 // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
|
Chris@102
|
210 return std::pair<RealType, RealType>(static_cast<RealType>(dist.x_min()), static_cast<RealType>(dist.x_max()));
|
Chris@102
|
211 }
|
Chris@102
|
212
|
Chris@102
|
213 template <class RealType, class Policy>
|
Chris@102
|
214 inline RealType mean(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
215 { // Mean of arcsine distribution .
|
Chris@102
|
216 RealType result;
|
Chris@102
|
217 RealType x_min = dist.x_min();
|
Chris@102
|
218 RealType x_max = dist.x_max();
|
Chris@102
|
219
|
Chris@102
|
220 if (false == arcsine_detail::check_dist(
|
Chris@102
|
221 "boost::math::mean(arcsine_distribution<%1%> const&, %1% )",
|
Chris@102
|
222 x_min,
|
Chris@102
|
223 x_max,
|
Chris@102
|
224 &result, Policy())
|
Chris@102
|
225 )
|
Chris@102
|
226 {
|
Chris@102
|
227 return result;
|
Chris@102
|
228 }
|
Chris@102
|
229 return (x_min + x_max) / 2;
|
Chris@102
|
230 } // mean
|
Chris@102
|
231
|
Chris@102
|
232 template <class RealType, class Policy>
|
Chris@102
|
233 inline RealType variance(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
234 { // Variance of standard arcsine distribution = (1-0)/8 = 0.125.
|
Chris@102
|
235 RealType result;
|
Chris@102
|
236 RealType x_min = dist.x_min();
|
Chris@102
|
237 RealType x_max = dist.x_max();
|
Chris@102
|
238 if (false == arcsine_detail::check_dist(
|
Chris@102
|
239 "boost::math::variance(arcsine_distribution<%1%> const&, %1% )",
|
Chris@102
|
240 x_min,
|
Chris@102
|
241 x_max,
|
Chris@102
|
242 &result, Policy())
|
Chris@102
|
243 )
|
Chris@102
|
244 {
|
Chris@102
|
245 return result;
|
Chris@102
|
246 }
|
Chris@102
|
247 return (x_max - x_min) * (x_max - x_min) / 8;
|
Chris@102
|
248 } // variance
|
Chris@102
|
249
|
Chris@102
|
250 template <class RealType, class Policy>
|
Chris@102
|
251 inline RealType mode(const arcsine_distribution<RealType, Policy>& /* dist */)
|
Chris@102
|
252 { //There are always [*two] values for the mode, at ['x_min] and at ['x_max], default 0 and 1,
|
Chris@102
|
253 // so instead we raise the exception domain_error.
|
Chris@102
|
254 return policies::raise_domain_error<RealType>(
|
Chris@102
|
255 "boost::math::mode(arcsine_distribution<%1%>&)",
|
Chris@102
|
256 "The arcsine distribution has two modes at x_min and x_max: "
|
Chris@102
|
257 "so the return value is %1%.",
|
Chris@102
|
258 std::numeric_limits<RealType>::quiet_NaN(), Policy());
|
Chris@102
|
259 } // mode
|
Chris@102
|
260
|
Chris@102
|
261 template <class RealType, class Policy>
|
Chris@102
|
262 inline RealType median(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
263 { // Median of arcsine distribution (a + b) / 2 == mean.
|
Chris@102
|
264 RealType x_min = dist.x_min();
|
Chris@102
|
265 RealType x_max = dist.x_max();
|
Chris@102
|
266 RealType result;
|
Chris@102
|
267 if (false == arcsine_detail::check_dist(
|
Chris@102
|
268 "boost::math::median(arcsine_distribution<%1%> const&, %1% )",
|
Chris@102
|
269 x_min,
|
Chris@102
|
270 x_max,
|
Chris@102
|
271 &result, Policy())
|
Chris@102
|
272 )
|
Chris@102
|
273 {
|
Chris@102
|
274 return result;
|
Chris@102
|
275 }
|
Chris@102
|
276 return (x_min + x_max) / 2;
|
Chris@102
|
277 }
|
Chris@102
|
278
|
Chris@102
|
279 template <class RealType, class Policy>
|
Chris@102
|
280 inline RealType skewness(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
281 {
|
Chris@102
|
282 RealType result;
|
Chris@102
|
283 RealType x_min = dist.x_min();
|
Chris@102
|
284 RealType x_max = dist.x_max();
|
Chris@102
|
285
|
Chris@102
|
286 if (false == arcsine_detail::check_dist(
|
Chris@102
|
287 "boost::math::skewness(arcsine_distribution<%1%> const&, %1% )",
|
Chris@102
|
288 x_min,
|
Chris@102
|
289 x_max,
|
Chris@102
|
290 &result, Policy())
|
Chris@102
|
291 )
|
Chris@102
|
292 {
|
Chris@102
|
293 return result;
|
Chris@102
|
294 }
|
Chris@102
|
295 return 0;
|
Chris@102
|
296 } // skewness
|
Chris@102
|
297
|
Chris@102
|
298 template <class RealType, class Policy>
|
Chris@102
|
299 inline RealType kurtosis_excess(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
300 {
|
Chris@102
|
301 RealType result;
|
Chris@102
|
302 RealType x_min = dist.x_min();
|
Chris@102
|
303 RealType x_max = dist.x_max();
|
Chris@102
|
304
|
Chris@102
|
305 if (false == arcsine_detail::check_dist(
|
Chris@102
|
306 "boost::math::kurtosis_excess(arcsine_distribution<%1%> const&, %1% )",
|
Chris@102
|
307 x_min,
|
Chris@102
|
308 x_max,
|
Chris@102
|
309 &result, Policy())
|
Chris@102
|
310 )
|
Chris@102
|
311 {
|
Chris@102
|
312 return result;
|
Chris@102
|
313 }
|
Chris@102
|
314 result = -3;
|
Chris@102
|
315 return result / 2;
|
Chris@102
|
316 } // kurtosis_excess
|
Chris@102
|
317
|
Chris@102
|
318 template <class RealType, class Policy>
|
Chris@102
|
319 inline RealType kurtosis(const arcsine_distribution<RealType, Policy>& dist)
|
Chris@102
|
320 {
|
Chris@102
|
321 RealType result;
|
Chris@102
|
322 RealType x_min = dist.x_min();
|
Chris@102
|
323 RealType x_max = dist.x_max();
|
Chris@102
|
324
|
Chris@102
|
325 if (false == arcsine_detail::check_dist(
|
Chris@102
|
326 "boost::math::kurtosis(arcsine_distribution<%1%> const&, %1% )",
|
Chris@102
|
327 x_min,
|
Chris@102
|
328 x_max,
|
Chris@102
|
329 &result, Policy())
|
Chris@102
|
330 )
|
Chris@102
|
331 {
|
Chris@102
|
332 return result;
|
Chris@102
|
333 }
|
Chris@102
|
334
|
Chris@102
|
335 return 3 + kurtosis_excess(dist);
|
Chris@102
|
336 } // kurtosis
|
Chris@102
|
337
|
Chris@102
|
338 template <class RealType, class Policy>
|
Chris@102
|
339 inline RealType pdf(const arcsine_distribution<RealType, Policy>& dist, const RealType& xx)
|
Chris@102
|
340 { // Probability Density/Mass Function arcsine.
|
Chris@102
|
341 BOOST_FPU_EXCEPTION_GUARD
|
Chris@102
|
342 BOOST_MATH_STD_USING // For ADL of std functions.
|
Chris@102
|
343
|
Chris@102
|
344 static const char* function = "boost::math::pdf(arcsine_distribution<%1%> const&, %1%)";
|
Chris@102
|
345
|
Chris@102
|
346 RealType lo = dist.x_min();
|
Chris@102
|
347 RealType hi = dist.x_max();
|
Chris@102
|
348 RealType x = xx;
|
Chris@102
|
349
|
Chris@102
|
350 // Argument checks:
|
Chris@102
|
351 RealType result = 0;
|
Chris@102
|
352 if (false == arcsine_detail::check_dist_and_x(
|
Chris@102
|
353 function,
|
Chris@102
|
354 lo, hi, x,
|
Chris@102
|
355 &result, Policy()))
|
Chris@102
|
356 {
|
Chris@102
|
357 return result;
|
Chris@102
|
358 }
|
Chris@102
|
359 using boost::math::constants::pi;
|
Chris@102
|
360 result = static_cast<RealType>(1) / (pi<RealType>() * sqrt((x - lo) * (hi - x)));
|
Chris@102
|
361 return result;
|
Chris@102
|
362 } // pdf
|
Chris@102
|
363
|
Chris@102
|
364 template <class RealType, class Policy>
|
Chris@102
|
365 inline RealType cdf(const arcsine_distribution<RealType, Policy>& dist, const RealType& x)
|
Chris@102
|
366 { // Cumulative Distribution Function arcsine.
|
Chris@102
|
367 BOOST_MATH_STD_USING // For ADL of std functions.
|
Chris@102
|
368
|
Chris@102
|
369 static const char* function = "boost::math::cdf(arcsine_distribution<%1%> const&, %1%)";
|
Chris@102
|
370
|
Chris@102
|
371 RealType x_min = dist.x_min();
|
Chris@102
|
372 RealType x_max = dist.x_max();
|
Chris@102
|
373
|
Chris@102
|
374 // Argument checks:
|
Chris@102
|
375 RealType result = 0;
|
Chris@102
|
376 if (false == arcsine_detail::check_dist_and_x(
|
Chris@102
|
377 function,
|
Chris@102
|
378 x_min, x_max, x,
|
Chris@102
|
379 &result, Policy()))
|
Chris@102
|
380 {
|
Chris@102
|
381 return result;
|
Chris@102
|
382 }
|
Chris@102
|
383 // Special cases:
|
Chris@102
|
384 if (x == x_min)
|
Chris@102
|
385 {
|
Chris@102
|
386 return 0;
|
Chris@102
|
387 }
|
Chris@102
|
388 else if (x == x_max)
|
Chris@102
|
389 {
|
Chris@102
|
390 return 1;
|
Chris@102
|
391 }
|
Chris@102
|
392 using boost::math::constants::pi;
|
Chris@102
|
393 result = static_cast<RealType>(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
Chris@102
|
394 return result;
|
Chris@102
|
395 } // arcsine cdf
|
Chris@102
|
396
|
Chris@102
|
397 template <class RealType, class Policy>
|
Chris@102
|
398 inline RealType cdf(const complemented2_type<arcsine_distribution<RealType, Policy>, RealType>& c)
|
Chris@102
|
399 { // Complemented Cumulative Distribution Function arcsine.
|
Chris@102
|
400 BOOST_MATH_STD_USING // For ADL of std functions.
|
Chris@102
|
401 static const char* function = "boost::math::cdf(arcsine_distribution<%1%> const&, %1%)";
|
Chris@102
|
402
|
Chris@102
|
403 RealType x = c.param;
|
Chris@102
|
404 arcsine_distribution<RealType, Policy> const& dist = c.dist;
|
Chris@102
|
405 RealType x_min = dist.x_min();
|
Chris@102
|
406 RealType x_max = dist.x_max();
|
Chris@102
|
407
|
Chris@102
|
408 // Argument checks:
|
Chris@102
|
409 RealType result = 0;
|
Chris@102
|
410 if (false == arcsine_detail::check_dist_and_x(
|
Chris@102
|
411 function,
|
Chris@102
|
412 x_min, x_max, x,
|
Chris@102
|
413 &result, Policy()))
|
Chris@102
|
414 {
|
Chris@102
|
415 return result;
|
Chris@102
|
416 }
|
Chris@102
|
417 if (x == x_min)
|
Chris@102
|
418 {
|
Chris@102
|
419 return 0;
|
Chris@102
|
420 }
|
Chris@102
|
421 else if (x == x_max)
|
Chris@102
|
422 {
|
Chris@102
|
423 return 1;
|
Chris@102
|
424 }
|
Chris@102
|
425 using boost::math::constants::pi;
|
Chris@102
|
426 // Naive version x = 1 - x;
|
Chris@102
|
427 // result = static_cast<RealType>(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
Chris@102
|
428 // is less accurate, so use acos instead of asin for complement.
|
Chris@102
|
429 result = static_cast<RealType>(2) * acos(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
Chris@102
|
430 return result;
|
Chris@102
|
431 } // arcine ccdf
|
Chris@102
|
432
|
Chris@102
|
433 template <class RealType, class Policy>
|
Chris@102
|
434 inline RealType quantile(const arcsine_distribution<RealType, Policy>& dist, const RealType& p)
|
Chris@102
|
435 {
|
Chris@102
|
436 // Quantile or Percent Point arcsine function or
|
Chris@102
|
437 // Inverse Cumulative probability distribution function CDF.
|
Chris@102
|
438 // Return x (0 <= x <= 1),
|
Chris@102
|
439 // for a given probability p (0 <= p <= 1).
|
Chris@102
|
440 // These functions take a probability as an argument
|
Chris@102
|
441 // and return a value such that the probability that a random variable x
|
Chris@102
|
442 // will be less than or equal to that value
|
Chris@102
|
443 // is whatever probability you supplied as an argument.
|
Chris@102
|
444 BOOST_MATH_STD_USING // For ADL of std functions.
|
Chris@102
|
445
|
Chris@102
|
446 using boost::math::constants::half_pi;
|
Chris@102
|
447
|
Chris@102
|
448 static const char* function = "boost::math::quantile(arcsine_distribution<%1%> const&, %1%)";
|
Chris@102
|
449
|
Chris@102
|
450 RealType result = 0; // of argument checks:
|
Chris@102
|
451 RealType x_min = dist.x_min();
|
Chris@102
|
452 RealType x_max = dist.x_max();
|
Chris@102
|
453 if (false == arcsine_detail::check_dist_and_prob(
|
Chris@102
|
454 function,
|
Chris@102
|
455 x_min, x_max, p,
|
Chris@102
|
456 &result, Policy()))
|
Chris@102
|
457 {
|
Chris@102
|
458 return result;
|
Chris@102
|
459 }
|
Chris@102
|
460 // Special cases:
|
Chris@102
|
461 if (p == 0)
|
Chris@102
|
462 {
|
Chris@102
|
463 return 0;
|
Chris@102
|
464 }
|
Chris@102
|
465 if (p == 1)
|
Chris@102
|
466 {
|
Chris@102
|
467 return 1;
|
Chris@102
|
468 }
|
Chris@102
|
469
|
Chris@102
|
470 RealType sin2hpip = sin(half_pi<RealType>() * p);
|
Chris@102
|
471 RealType sin2hpip2 = sin2hpip * sin2hpip;
|
Chris@102
|
472 result = -x_min * sin2hpip2 + x_min + x_max * sin2hpip2;
|
Chris@102
|
473
|
Chris@102
|
474 return result;
|
Chris@102
|
475 } // quantile
|
Chris@102
|
476
|
Chris@102
|
477 template <class RealType, class Policy>
|
Chris@102
|
478 inline RealType quantile(const complemented2_type<arcsine_distribution<RealType, Policy>, RealType>& c)
|
Chris@102
|
479 {
|
Chris@102
|
480 // Complement Quantile or Percent Point arcsine function.
|
Chris@102
|
481 // Return the number of expected x for a given
|
Chris@102
|
482 // complement of the probability q.
|
Chris@102
|
483 BOOST_MATH_STD_USING // For ADL of std functions.
|
Chris@102
|
484
|
Chris@102
|
485 using boost::math::constants::half_pi;
|
Chris@102
|
486 static const char* function = "boost::math::quantile(arcsine_distribution<%1%> const&, %1%)";
|
Chris@102
|
487
|
Chris@102
|
488 // Error checks:
|
Chris@102
|
489 RealType q = c.param;
|
Chris@102
|
490 const arcsine_distribution<RealType, Policy>& dist = c.dist;
|
Chris@102
|
491 RealType result = 0;
|
Chris@102
|
492 RealType x_min = dist.x_min();
|
Chris@102
|
493 RealType x_max = dist.x_max();
|
Chris@102
|
494 if (false == arcsine_detail::check_dist_and_prob(
|
Chris@102
|
495 function,
|
Chris@102
|
496 x_min,
|
Chris@102
|
497 x_max,
|
Chris@102
|
498 q,
|
Chris@102
|
499 &result, Policy()))
|
Chris@102
|
500 {
|
Chris@102
|
501 return result;
|
Chris@102
|
502 }
|
Chris@102
|
503 // Special cases:
|
Chris@102
|
504 if (q == 1)
|
Chris@102
|
505 {
|
Chris@102
|
506 return 0;
|
Chris@102
|
507 }
|
Chris@102
|
508 if (q == 0)
|
Chris@102
|
509 {
|
Chris@102
|
510 return 1;
|
Chris@102
|
511 }
|
Chris@102
|
512 // Naive RealType p = 1 - q; result = sin(half_pi<RealType>() * p); loses accuracy, so use a cos alternative instead.
|
Chris@102
|
513 //result = cos(half_pi<RealType>() * q); // for arcsine(0,1)
|
Chris@102
|
514 //result = result * result;
|
Chris@102
|
515 // For generalized arcsine:
|
Chris@102
|
516 RealType cos2hpip = cos(half_pi<RealType>() * q);
|
Chris@102
|
517 RealType cos2hpip2 = cos2hpip * cos2hpip;
|
Chris@102
|
518 result = -x_min * cos2hpip2 + x_min + x_max * cos2hpip2;
|
Chris@102
|
519
|
Chris@102
|
520 return result;
|
Chris@102
|
521 } // Quantile Complement
|
Chris@102
|
522
|
Chris@102
|
523 } // namespace math
|
Chris@102
|
524 } // namespace boost
|
Chris@102
|
525
|
Chris@102
|
526 // This include must be at the end, *after* the accessors
|
Chris@102
|
527 // for this distribution have been defined, in order to
|
Chris@102
|
528 // keep compilers that support two-phase lookup happy.
|
Chris@102
|
529 #include <boost/math/distributions/detail/derived_accessors.hpp>
|
Chris@102
|
530
|
Chris@102
|
531 #if defined (BOOST_MSVC)
|
Chris@102
|
532 # pragma warning(pop)
|
Chris@102
|
533 #endif
|
Chris@102
|
534
|
Chris@102
|
535 #endif // BOOST_MATH_DIST_ARCSINE_HPP
|