Library of Assembled Shared Sources
distribution.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2022 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_DISTRIBUTION_INL
46#define LASS_GUARDIAN_OF_INCLUSION_NUM_DISTRIBUTION_INL
47
48#include "num_common.h"
49#include "distribution.h"
50
51 // avoid deprecation warnings by the implementation of the deprecated things themselves
52#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
53# pragma warning(push)
54# pragma warning(disable: 4996) // 'deprecated-declaration': deprecation-message (or "was declared deprecated")
55#else
56# pragma GCC diagnostic push
57# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
58#endif
59
60namespace lass
61{
62namespace num
63{
64namespace impl
65{
66
67template <RangeType rangeType> struct RangePolicy;
68
69template <>
70struct RangePolicy<rtClosed>
71{
72 template <typename T>
73 static bool isInRange(const T& x, const T& inf, const T& sup) { return x >= inf && x <= sup; }
74};
75
76template <>
77struct RangePolicy<rtLeftOpen>
78{
79 template <typename T>
80 static bool isInRange(const T& x, const T& inf, const T& sup) { return x > inf && x <= sup; }
81};
82
83template <>
84struct RangePolicy<rtRightOpen>
85{
86 template <typename T>
87 static bool isInRange(const T& x, const T& inf, const T& sup) { return x >= inf && x < sup; }
88};
89
90template <>
91struct RangePolicy<rtOpen>
92{
93 template <typename T>
94 static bool isInRange(const T& x, const T& inf, const T& sup) { return x > inf && x < sup; }
95};
96
97}
98
99
100
101// --- DistributionUniform -------------------------------------------------------------------------
102
103/** construct an empty distribution.
104 * @warning drawing numbers from an empty distribution results in undefined behaviour, probably
105 * causing an access violation.
106 */
107template <typename T, class RG, RangeType RT>
112
113/** construct a uniform distribution mapper
114 * @param generator random number generator to be used as input. Lifespan of @a generator must
115 * be at least that of the distribution.
116 * @param infimum infimum of the output range: [inf, sup], or (inf, sup] if range is left open.
117 * @param supremum supremum of the output range: [inf, sup], or [inf, sup) if range is right open.
118 */
119template <typename T, class RG, RangeType RT>
121 TGenerator& generator, TParam infimum, TParam supremum):
122 generator_(&generator),
123 infimum_(infimum),
124 supremum_(supremum),
125 scale_(static_cast<long double>(supremum - infimum) / TGenerator::max())
126{
127}
128
129
130
131template <typename T, class RG, RangeType RT> inline
133DistributionUniform<T, RG, RT>::operator()() const
134{
135 LASS_ASSERT(generator_);
136 TValue result;
137 do
138 {
139 result = infimum_ + static_cast<TValue>(scale_ * (*generator_)());
140 }
141 while (!impl::RangePolicy<RT>::isInRange(result, infimum_, supremum_));
142 return result;
143}
144
145
146
147/** draw a random number from generator and transform it by a uniform distribution
148 * @relates DistributionUniform
149 */
150template <typename T, typename RandomGenerator> inline
151T distributeUniform(RandomGenerator& generator, T infimum, T supremum)
152{
153 DistributionUniform<T, RandomGenerator> distribution(generator, infimum, supremum);
154 return distribution();
155}
156
157
158
159// --- DistributionExponential ---------------------------------------------------------------------
160
161/** construct an empty distribution.
162 * @warning drawing numbers from an empty distribution results in undefined behaviour, probably
163 * causing an access violation.
164 */
165template <typename T, class RG>
170
171
172
173/** construct a normal distribution mapper
174 * @param generator random number generator to be used as input. Lifespan of @a generator must
175 * be at least that of the distribution.
176 * @param mean mean of distribution
177 * @param stddev standard deviation of
178 */
179template <typename T, class RG>
181 generator_(&generator),
182 rateOfChange_(rateOfChange)
183{
184}
185
186
187
188template <typename T, class RG> inline
190DistributionExponential<T, RG>::operator()() const
191{
192 LASS_ASSERT(generator_);
193 TValue temp;
194 do
195 {
196 temp = static_cast<TValue>((*generator_)()) / TGenerator::max();
197 }
198 while (temp == TNumTraits::zero);
199 return -num::log(temp) / rateOfChange_;
200}
201
202
203
204/** draw a random number from generator and transform it by a exponential distribution
205 * @relates DistributionExponential
206 */
207template <typename T, typename RandomGenerator> inline
208T distributeExponential(RandomGenerator& generator, T rateOfChange)
209{
210 DistributionExponential<T, RandomGenerator> distribution(generator, rateOfChange);
211 return distribution();
212}
213
214
215
216// --- DistributionNormal --------------------------------------------------------------------------
217
218/** construct an empty distribution.
219 * @warning drawing numbers from an empty distribution results in undefined behaviour, probably
220 * causing an access violation.
221 */
222template <typename T, class RG>
227
228
229
230/** construct a normal distribution mapper
231 * @param generator random number generator to be used as input. Lifespan of @a generator must
232 * be at least that of the distribution.
233 * @param mean mean of distribution
234 * @param standardDeviation standard deviation of distribution
235 */
236template <typename T, class RG>
238 TGenerator& generator, TParam mean, TParam standardDeviation):
239 generator_(&generator),
240 mean_(mean),
241 standardDeviation_(standardDeviation),
242 gset_(0),
243 iset_(false)
244{
245}
246
247
248
249template <typename T, class RG> inline
251DistributionNormal<T, RG>::operator()() const
252{
253 LASS_ASSERT(generator_);
254
255 if (iset_)
256 {
257 iset_ = false;
258 return mean_ + standardDeviation_ * gset_;
259 }
260
261 const TValue scale = static_cast<TValue>(2) / TGenerator::max();
262 TValue rsq,v1,v2;
263 do
264 {
265 v1 = scale * (*generator_)() - TNumTraits::one;
266 v2 = scale * (*generator_)() - TNumTraits::one;
267 rsq = v1 * v1 + v2 * v2;
268 }
269 while (rsq >= 1.0 || rsq == 0.0);
270 const TValue fac = num::sqrt(-2 * num::log(rsq) / rsq);
271
272 gset_ = v1 * fac;
273 iset_ = true;
274 return mean_ + standardDeviation_ * v2 * fac;
275}
276
277
278
279/** draw a random number from generator and transform it by a normal distribution
280 * @relates DistributionNormal
281 */
282template <typename T, typename RandomGenerator> inline
283T distributeNormal(RandomGenerator& generator, T mean, T standardDeviation)
284{
285 DistributionNormal<T, RandomGenerator> distribution(generator, mean, standardDeviation);
286 return distribution();
287}
288
289
290
291// --- backwards compatibility ---------------------------------------------------------------------
292
293/** @ingroup Distribution
294 * @return a uniform random sample from [0,1]
295 */
296template<class T,class RG> T uniform(RG& generator)
297{
298 return distributeUniform(generator);
299}
300
301
302
303/** @ingroup Distribution
304 * @return a gaussian distributed (aka normal distributed) random with mean 0 and stddev 1
305 */
306template<class T,class RG> T unitGauss(RG& generator)
307{
308 return distributeNormal(generator);
309}
310
311
312
313/** @ingroup Distribution
314 * @return a gaussian distributed (aka normal distributed) random sample with @a mean and
315 * stddev @a stddev
316 */
317template<class T,class RG> T gauss(
318 RG& generator, typename util::CallTraits<T>::TParam mean,
319 typename util::CallTraits<T>::TParam stddev)
320{
321 return distributeNormal(generator, mean, stddev);
322}
323
324
325
326}
327
328}
329
330#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
331# pragma warning(pop)
332#else
333# pragma GCC diagnostic pop
334#endif
335
336#endif
337
338// EOF
util::CallTraits< T >::TParam TParam
parameter value type
RandomGenerator TGenerator
generator type
util::CallTraits< T >::TValue TValue
value type
DistributionExponential()
construct an empty distribution.
T distributeExponential(RandomGenerator &generator, T rateOfChange)
draw a random number from generator and transform it by a exponential distribution
DistributionNormal()
construct an empty distribution.
T distributeNormal(RandomGenerator &generator, T mean, T standardDeviation)
draw a random number from generator and transform it by a normal distribution
util::CallTraits< T >::TValue TValue
value type
util::CallTraits< T >::TParam TParam
parameter value type
RandomGenerator TGenerator
generator type
util::CallTraits< T >::TParam TParam
parameter value type
T distributeUniform(RandomGenerator &generator, T infimum, T supremum)
draw a random number from generator and transform it by a uniform distribution
RandomGenerator TGenerator
generator type
util::CallTraits< T >::TValue TValue
value type
DistributionUniform()
construct an empty distribution.
T gauss(RG &generator, typename util::CallTraits< T >::TParam mean, typename util::CallTraits< T >::TParam stddev)
T uniform(RG &generator)
T unitGauss(RG &generator)
@ rtRightOpen
range is open to the right: [inf, sup)
@ rtClosed
range is closed on both sides: [inf, sup]
@ rtLeftOpen
range is open to the left: (inf, sup]
@ rtOpen
range is open to both sides: (inf, sup)
numeric types and traits.
Definition basic_ops.h:70
Library for Assembled Shared Sources.
Definition config.h:53