File indexing completed on 2025-01-18 09:51:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
0018 #define BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
0019
0020 #include <boost/config/no_tr1/cmath.hpp>
0021 #include <iosfwd>
0022 #include <ios>
0023 #include <istream>
0024 #include <boost/assert.hpp>
0025 #include <boost/random/detail/config.hpp>
0026 #include <boost/random/detail/operators.hpp>
0027 #include <boost/random/uniform_01.hpp>
0028
0029 namespace boost {
0030 namespace random {
0031
0032
0033
0034
0035
0036
0037
0038 template<class RealType = double>
0039 class triangle_distribution
0040 {
0041 public:
0042 typedef RealType input_type;
0043 typedef RealType result_type;
0044
0045 class param_type
0046 {
0047 public:
0048
0049 typedef triangle_distribution distribution_type;
0050
0051
0052 explicit param_type(RealType a_arg = RealType(0.0),
0053 RealType b_arg = RealType(0.5),
0054 RealType c_arg = RealType(1.0))
0055 : _a(a_arg), _b(b_arg), _c(c_arg)
0056 {
0057 BOOST_ASSERT(_a <= _b && _b <= _c);
0058 }
0059
0060
0061 RealType a() const { return _a; }
0062
0063 RealType b() const { return _b; }
0064
0065 RealType c() const { return _c; }
0066
0067
0068 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
0069 {
0070 os << parm._a << " " << parm._b << " " << parm._c;
0071 return os;
0072 }
0073
0074
0075 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
0076 {
0077 double a_in, b_in, c_in;
0078 if(is >> a_in >> std::ws >> b_in >> std::ws >> c_in) {
0079 if(a_in <= b_in && b_in <= c_in) {
0080 parm._a = a_in;
0081 parm._b = b_in;
0082 parm._c = c_in;
0083 } else {
0084 is.setstate(std::ios_base::failbit);
0085 }
0086 }
0087 return is;
0088 }
0089
0090
0091 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
0092 { return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
0093
0094
0095 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
0096
0097 private:
0098 RealType _a;
0099 RealType _b;
0100 RealType _c;
0101 };
0102
0103
0104
0105
0106
0107
0108
0109 explicit triangle_distribution(RealType a_arg = RealType(0.0),
0110 RealType b_arg = RealType(0.5),
0111 RealType c_arg = RealType(1.0))
0112 : _a(a_arg), _b(b_arg), _c(c_arg)
0113 {
0114 BOOST_ASSERT(_a <= _b && _b <= _c);
0115 init();
0116 }
0117
0118
0119 explicit triangle_distribution(const param_type& parm)
0120 : _a(parm.a()), _b(parm.b()), _c(parm.c())
0121 {
0122 init();
0123 }
0124
0125
0126
0127
0128 result_type a() const { return _a; }
0129
0130 result_type b() const { return _b; }
0131
0132 result_type c() const { return _c; }
0133
0134
0135 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _a; }
0136
0137 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _c; }
0138
0139
0140 param_type param() const { return param_type(_a, _b, _c); }
0141
0142 void param(const param_type& parm)
0143 {
0144 _a = parm.a();
0145 _b = parm.b();
0146 _c = parm.c();
0147 init();
0148 }
0149
0150
0151
0152
0153
0154 void reset() { }
0155
0156
0157
0158
0159
0160 template<class Engine>
0161 result_type operator()(Engine& eng)
0162 {
0163 using std::sqrt;
0164 result_type u = uniform_01<result_type>()(eng);
0165 if( u <= q1 )
0166 return _a + p1*sqrt(u);
0167 else
0168 return _c - d3*sqrt(d2*u-d1);
0169 }
0170
0171
0172
0173
0174
0175 template<class Engine>
0176 result_type operator()(Engine& eng, const param_type& parm)
0177 { return triangle_distribution(parm)(eng); }
0178
0179
0180 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, triangle_distribution, td)
0181 {
0182 os << td.param();
0183 return os;
0184 }
0185
0186
0187 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, triangle_distribution, td)
0188 {
0189 param_type parm;
0190 if(is >> parm) {
0191 td.param(parm);
0192 }
0193 return is;
0194 }
0195
0196
0197
0198
0199
0200 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(triangle_distribution, lhs, rhs)
0201 { return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
0202
0203
0204
0205
0206
0207 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(triangle_distribution)
0208
0209 private:
0210
0211 void init()
0212 {
0213 using std::sqrt;
0214 d1 = _b - _a;
0215 d2 = _c - _a;
0216 d3 = sqrt(_c - _b);
0217 q1 = d1 / d2;
0218 p1 = sqrt(d1 * d2);
0219 }
0220
0221
0222 RealType _a, _b, _c;
0223 RealType d1, d2, d3, q1, p1;
0224 };
0225
0226 }
0227
0228 using random::triangle_distribution;
0229
0230 }
0231
0232 #endif