library of assembled shared sources

http://lass.cocamware.com

distribution.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_DISTRIBUTION_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_NUM_DISTRIBUTION_INL
00047 
00048 #include "num_common.h"
00049 #include "distribution.h"
00050 
00051 namespace lass
00052 {
00053 namespace num
00054 {
00055 namespace impl
00056 {
00057 
00058 template <RangeType rangeType> struct RangePolicy;
00059 
00060 template <>
00061 struct RangePolicy<rtClosed>
00062 {
00063     template <typename T>
00064     static bool isInRange(const T& x, const T& inf, const T& sup) { return x >= inf && x <= sup; }
00065 };
00066 
00067 template <>
00068 struct RangePolicy<rtLeftOpen>
00069 {
00070     template <typename T>
00071     static bool isInRange(const T& x, const T& inf, const T& sup) { return x > inf && x <= sup; }
00072 };
00073 
00074 template <>
00075 struct RangePolicy<rtRightOpen>
00076 {
00077     template <typename T>
00078     static bool isInRange(const T& x, const T& inf, const T& sup) { return x >= inf && x < sup; }
00079 };
00080 
00081 template <>
00082 struct RangePolicy<rtOpen>
00083 {
00084     template <typename T>
00085     static bool isInRange(const T& x, const T& inf, const T& sup) { return x > inf && x < sup; }
00086 };
00087 
00088 }
00089 
00090 
00091 
00092 // --- DistributionUniform -------------------------------------------------------------------------
00093 
00094 /** construct an empty distribution.
00095  *  @warning drawing numbers from an empty distribution results in undefined behaviour, probably
00096  *      causing an access violation.
00097  */
00098 template <typename T, class RG, RangeType RT>
00099 DistributionUniform<T, RG, RT>::DistributionUniform():
00100     generator_(0)
00101 {
00102 }
00103 
00104 /** construct a uniform distribution mapper
00105  *  @param generator random number generator to be used as input.  Lifespan of @a generator must
00106  *                     be at least that of the distribution.
00107  *  @param infimum infimum of the output range: [inf, sup], or (inf, sup] if range is left open.
00108  *  @param supremum supremum of the output range: [inf, sup], or [inf, sup) if range is right open.
00109  */
00110 template <typename T, class RG, RangeType RT>
00111 DistributionUniform<T, RG, RT>::DistributionUniform(
00112         TGenerator& generator, TParam infimum, TParam supremum):
00113     generator_(&generator),
00114     infimum_(infimum),
00115     supremum_(supremum),
00116     scale_(static_cast<long double>(supremum - infimum) / TGenerator::max)
00117 {
00118 }
00119 
00120 
00121 
00122 template <typename T, class RG, RangeType RT> inline
00123 typename DistributionUniform<T, RG, RT>::TValue
00124 DistributionUniform<T, RG, RT>::operator()() const
00125 {
00126     LASS_ASSERT(generator_);
00127     TValue result;
00128     do
00129     {
00130         result = infimum_ + static_cast<TValue>(scale_ * (*generator_)());
00131     }
00132     while (!impl::RangePolicy<RT>::isInRange(result, infimum_, supremum_));
00133     return result;
00134 }
00135 
00136 
00137 
00138 /** draw a random number from generator and transform it by a uniform distribution
00139  *  @relates DistributionUniform
00140  */
00141 template <typename T, typename RandomGenerator> inline
00142 T distributeUniform(RandomGenerator& generator, T infimum, T supremum)
00143 {
00144     DistributionUniform<T, RandomGenerator> distribution(generator, infimum, supremum);
00145     return distribution();
00146 }
00147 
00148 
00149 
00150 // --- DistributionExponential ---------------------------------------------------------------------
00151 
00152 /** construct an empty distribution.
00153  *  @warning drawing numbers from an empty distribution results in undefined behaviour, probably
00154  *      causing an access violation.
00155  */
00156 template <typename T, class RG>
00157 DistributionExponential<T, RG>::DistributionExponential():
00158     generator_(0)
00159 {
00160 }
00161 
00162 
00163 
00164 /** construct a normal distribution mapper
00165  *  @param generator random number generator to be used as input.  Lifespan of @a generator must
00166  *                     be at least that of the distribution.
00167  *  @param mean mean of distribution
00168  *  @param stddev standard deviation of
00169  */
00170 template <typename T, class RG>
00171 DistributionExponential<T, RG>::DistributionExponential(TGenerator& generator, TParam rateOfChange):
00172     generator_(&generator),
00173     rateOfChange_(rateOfChange)
00174 {
00175 }
00176 
00177 
00178 
00179 template <typename T, class RG> inline
00180 typename DistributionExponential<T, RG>::TValue
00181 DistributionExponential<T, RG>::operator()() const
00182 {
00183     LASS_ASSERT(generator_);
00184     TValue temp;
00185     do
00186     {
00187         temp = static_cast<TValue>((*generator_)()) / TGenerator::max;
00188     }
00189     while (temp == TNumTraits::zero);
00190     return -num::log(temp) / rateOfChange_;
00191 }
00192 
00193 
00194 
00195 /** draw a random number from generator and transform it by a exponential distribution
00196  *  @relates DistributionExponential
00197  */
00198 template <typename T, typename RandomGenerator> inline
00199 T distributeExponential(RandomGenerator& generator, T rateOfChange)
00200 {
00201     DistributionExponential<T, RandomGenerator> distribution(generator, rateOfChange);
00202     return distribution();
00203 }
00204 
00205 
00206 
00207 // --- DistributionNormal --------------------------------------------------------------------------
00208 
00209 /** construct an empty distribution.
00210  *  @warning drawing numbers from an empty distribution results in undefined behaviour, probably
00211  *      causing an access violation.
00212  */
00213 template <typename T, class RG>
00214 DistributionNormal<T, RG>::DistributionNormal():
00215     generator_(0)
00216 {
00217 }
00218 
00219     
00220     
00221 /** construct a normal distribution mapper
00222  *  @param generator random number generator to be used as input.  Lifespan of @a generator must
00223  *                     be at least that of the distribution.
00224  *  @param mean mean of distribution
00225  *  @param standardDeviation standard deviation of distribution
00226  */
00227 template <typename T, class RG>
00228 DistributionNormal<T, RG>::DistributionNormal(
00229         TGenerator& generator, TParam mean, TParam standardDeviation):
00230     generator_(&generator),
00231     mean_(mean),
00232     standardDeviation_(standardDeviation),
00233     iset_(false)
00234 {
00235 }
00236 
00237 
00238 
00239 template <typename T, class RG> inline
00240 typename DistributionNormal<T, RG>::TValue
00241 DistributionNormal<T, RG>::operator()() const
00242 {
00243     LASS_ASSERT(generator_);
00244 
00245     if (iset_)
00246     {
00247         iset_ = false;
00248         return mean_ + standardDeviation_ * gset_;
00249     }
00250 
00251     const TValue scale = static_cast<TValue>(2) / TGenerator::max;
00252     TValue rsq,v1,v2;
00253     do
00254     {
00255         v1 = scale * (*generator_)() - TNumTraits::one;
00256         v2 = scale * (*generator_)() - TNumTraits::one;
00257         rsq = v1 * v1 + v2 * v2;
00258     }
00259     while (rsq >= 1.0 || rsq == 0.0);
00260     const TValue fac = num::sqrt(-2 * num::log(rsq) / rsq);
00261 
00262     gset_ = v1 * fac;
00263     iset_ = true;
00264     return mean_ + standardDeviation_ * v2 * fac;
00265 }
00266 
00267 
00268 
00269 /** draw a random number from generator and transform it by a normal distribution
00270  *  @relates DistributionNormal
00271  */
00272 template <typename T, typename RandomGenerator> inline
00273 T distributeNormal(RandomGenerator& generator, T mean, T standardDeviation)
00274 {
00275     DistributionNormal<T, RandomGenerator> distribution(generator, mean, standardDeviation);
00276     return distribution();
00277 }
00278 
00279 
00280 
00281 // --- backwards compatibility ---------------------------------------------------------------------
00282 
00283 /** @ingroup Distribution
00284  *  @return a uniform random sample from [0,1]
00285  */
00286 template<class T,class RG> T uniform(RG& generator)
00287 {
00288     return distributeUniform(generator);
00289 }
00290 
00291 
00292 
00293 /** @ingroup Distribution
00294  *  @return a gaussian distributed (aka normal distributed) random with mean 0 and stddev 1
00295  */
00296 template<class T,class RG> T unitGauss(RG& generator)
00297 {
00298     return distributeNormal(generator);
00299 }
00300 
00301 
00302 
00303 /** @ingroup Distribution
00304  *  @return a gaussian distributed (aka normal distributed) random sample with @a mean and
00305  *      stddev @a stddev
00306  */
00307 template<class T,class RG> T gauss(
00308         RG& generator, typename util::CallTraits<T>::TParam mean, 
00309         typename util::CallTraits<T>::TParam stddev)
00310 {
00311     return distributeNormal(generator, mean, stddev);
00312 }
00313 
00314 
00315 
00316 }
00317 
00318 }
00319 
00320 #endif
00321 
00322 // EOF

Generated on Mon Nov 10 14:20:04 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo