]> git.donarmstrong.com Git - rsem.git/blob - boost/random/triangle_distribution.hpp
Updated boost to v1.55.0
[rsem.git] / boost / random / triangle_distribution.hpp
1 /* boost random/triangle_distribution.hpp header file
2  *
3  * Copyright Jens Maurer 2000-2001
4  * Copyright Steven Watanabe 2011
5  * Distributed under the Boost Software License, Version 1.0. (See
6  * accompanying file LICENSE_1_0.txt or copy at
7  * http://www.boost.org/LICENSE_1_0.txt)
8  *
9  * See http://www.boost.org for most recent version including documentation.
10  *
11  * $Id: triangle_distribution.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
12  *
13  * Revision history
14  *  2001-02-18  moved to individual header files
15  */
16
17 #ifndef BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
18 #define BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
19
20 #include <boost/config/no_tr1/cmath.hpp>
21 #include <iosfwd>
22 #include <ios>
23 #include <istream>
24 #include <boost/assert.hpp>
25 #include <boost/random/detail/config.hpp>
26 #include <boost/random/detail/operators.hpp>
27 #include <boost/random/uniform_01.hpp>
28
29 namespace boost {
30 namespace random {
31
32 /**
33  * Instantiations of @c triangle_distribution model a \random_distribution.
34  * A @c triangle_distribution has three parameters, @c a, @c b, and @c c,
35  * which are the smallest, the most probable and the largest values of
36  * the distribution respectively.
37  */
38 template<class RealType = double>
39 class triangle_distribution
40 {
41 public:
42     typedef RealType input_type;
43     typedef RealType result_type;
44
45     class param_type
46     {
47     public:
48
49         typedef triangle_distribution distribution_type;
50
51         /** Constructs the parameters of a @c triangle_distribution. */
52         explicit param_type(RealType a_arg = RealType(0.0),
53                             RealType b_arg = RealType(0.5),
54                             RealType c_arg = RealType(1.0))
55           : _a(a_arg), _b(b_arg), _c(c_arg)
56         {
57             BOOST_ASSERT(_a <= _b && _b <= _c);
58         }
59
60         /** Returns the minimum value of the distribution. */
61         RealType a() const { return _a; }
62         /** Returns the mode of the distribution. */
63         RealType b() const { return _b; }
64         /** Returns the maximum value of the distribution. */
65         RealType c() const { return _c; }
66
67         /** Writes the parameters to a @c std::ostream. */
68         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
69         {
70             os << parm._a << " " << parm._b << " " << parm._c;
71             return os;
72         }
73
74         /** Reads the parameters from a @c std::istream. */
75         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
76         {
77             double a_in, b_in, c_in;
78             if(is >> a_in >> std::ws >> b_in >> std::ws >> c_in) {
79                 if(a_in <= b_in && b_in <= c_in) {
80                     parm._a = a_in;
81                     parm._b = b_in;
82                     parm._c = c_in;
83                 } else {
84                     is.setstate(std::ios_base::failbit);
85                 }
86             }
87             return is;
88         }
89
90         /** Returns true if the two sets of parameters are equal. */
91         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
92         { return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
93
94         /** Returns true if the two sets of parameters are different. */
95         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
96
97     private:
98         RealType _a;
99         RealType _b;
100         RealType _c;
101     };
102
103     /**
104      * Constructs a @c triangle_distribution with the parameters
105      * @c a, @c b, and @c c.
106      *
107      * Preconditions: a <= b <= c.
108      */
109     explicit triangle_distribution(RealType a_arg = RealType(0.0),
110                                    RealType b_arg = RealType(0.5),
111                                    RealType c_arg = RealType(1.0))
112       : _a(a_arg), _b(b_arg), _c(c_arg)
113     {
114         BOOST_ASSERT(_a <= _b && _b <= _c);
115         init();
116     }
117
118     /** Constructs a @c triangle_distribution from its parameters. */
119     explicit triangle_distribution(const param_type& parm)
120       : _a(parm.a()), _b(parm.b()), _c(parm.c())
121     {
122         init();
123     }
124
125     // compiler-generated copy ctor and assignment operator are fine
126
127     /** Returns the @c a parameter of the distribution */
128     result_type a() const { return _a; }
129     /** Returns the @c b parameter of the distribution */
130     result_type b() const { return _b; }
131     /** Returns the @c c parameter of the distribution */
132     result_type c() const { return _c; }
133
134     /** Returns the smallest value that the distribution can produce. */
135     RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _a; }
136     /** Returns the largest value that the distribution can produce. */
137     RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _c; }
138
139     /** Returns the parameters of the distribution. */
140     param_type param() const { return param_type(_a, _b, _c); }
141     /** Sets the parameters of the distribution. */
142     void param(const param_type& parm)
143     {
144         _a = parm.a();
145         _b = parm.b();
146         _c = parm.c();
147         init();
148     }
149
150     /**
151      * Effects: Subsequent uses of the distribution do not depend
152      * on values produced by any engine prior to invoking reset.
153      */
154     void reset() { }
155
156     /**
157      * Returns a random variate distributed according to the
158      * triangle distribution.
159      */
160     template<class Engine>
161     result_type operator()(Engine& eng)
162     {
163         using std::sqrt;
164         result_type u = uniform_01<>()(eng);
165         if( u <= q1 )
166             return _a + p1*sqrt(u);
167         else
168         return _c - d3*sqrt(d2*u-d1);
169     }
170
171     /**
172      * Returns a random variate distributed according to the
173      * triangle distribution with parameters specified by param.
174      */
175     template<class Engine>
176     result_type operator()(Engine& eng, const param_type& parm)
177     { return triangle_distribution(parm)(eng); }
178
179     /** Writes the distribution to a @c std::ostream. */
180     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, triangle_distribution, td)
181     {
182         os << td.param();
183         return os;
184     }
185
186     /** Reads the distribution from a @c std::istream. */
187     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, triangle_distribution, td)
188     {
189         param_type parm;
190         if(is >> parm) {
191             td.param(parm);
192         }
193         return is;
194     }
195
196     /**
197      * Returns true if the two distributions will produce identical
198      * sequences of values given equal generators.
199      */
200     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(triangle_distribution, lhs, rhs)
201     { return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
202
203     /**
204      * Returns true if the two distributions may produce different
205      * sequences of values given equal generators.
206      */
207     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(triangle_distribution)
208
209 private:
210     /// \cond show_private
211     void init()
212     {
213         using std::sqrt;
214         d1 = _b - _a;
215         d2 = _c - _a;
216         d3 = sqrt(_c - _b);
217         q1 = d1 / d2;
218         p1 = sqrt(d1 * d2);
219     }
220     /// \endcond
221
222     RealType _a, _b, _c;
223     RealType d1, d2, d3, q1, p1;
224 };
225
226 } // namespace random
227
228 using random::triangle_distribution;
229
230 } // namespace boost
231
232 #endif // BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP