blitz Version 0.10
|
00001 // -*- C++ -*- 00002 // $Id: exponential.h,v 1.4 2011/03/25 22:41:17 julianc Exp $ 00003 00004 /* 00005 * This generator uses the straightforward transformation 00006 * x = - log(y) * m 00007 * 00008 * to turn a uniform (0,1) y into an exponentially distributed 00009 * variable x. x has density function 00010 * 00011 * f(x) = (1/m) exp(-(1/m)x) (x > 0) 00012 * 00013 * and mean m. 00014 * 00015 * NEEDS_WORK: Adapt the method of Ahrens and Dieter. This will 00016 * require extending the precision of the constants. 00017 * 00018 * Ahrens, J.H. and Dieter, U. Computer Methods for Sampling From the 00019 * Exponential and Normal Distributions. Comm. ACM, 15,10 (Oct. 1972), p. 873. 00020 */ 00021 00022 #ifndef BZ_RANDOM_EXPONENTIAL 00023 #define BZ_RANDOM_EXPONENTIAL 00024 00025 #ifndef BZ_RANDOM_UNIFORM 00026 #include <random/uniform.h> 00027 #endif 00028 00029 BZ_NAMESPACE(ranlib) 00030 00031 template<typename T = double, typename IRNG = defaultIRNG, 00032 typename stateTag = defaultState> 00033 class ExponentialUnit : public UniformOpen<T,IRNG,stateTag> 00034 { 00035 public: 00036 typedef T T_numtype; 00037 00038 ExponentialUnit() {} 00039 00040 explicit ExponentialUnit(unsigned int i) : 00041 UniformOpen<T,IRNG,stateTag>(i) {}; 00042 00043 T random() 00044 { 00045 return - log(UniformOpen<T,IRNG,stateTag>::random()); 00046 } 00047 }; 00048 00049 template<typename T = double, typename IRNG = defaultIRNG, 00050 typename stateTag = defaultState> 00051 class Exponential : public ExponentialUnit<T,IRNG,stateTag> { 00052 00053 public: 00054 typedef T T_numtype; 00055 00056 Exponential(T mean) 00057 { 00058 mean_ = mean; 00059 } 00060 00061 Exponential(T mean, unsigned int i) : 00062 UniformOpen<T,IRNG,stateTag>(i) 00063 { 00064 mean_ = mean; 00065 }; 00066 00067 T random() 00068 { 00069 return mean_ * ExponentialUnit<T,IRNG,stateTag>::random(); 00070 } 00071 00072 private: 00073 T mean_; 00074 }; 00075 00076 BZ_NAMESPACE_END 00077 00078 #endif // BZ_RANDOM_EXPONENTIAL