00001
00002
00003
00004 #include "stdafx.h"
00005 #include "EvolveTraffic.h"
00006 #include "Distribution.h"
00007
00008 #ifdef _DEBUG
00009 #define new DEBUG_NEW
00010 #undef THIS_FILE
00011 static char THIS_FILE[] = __FILE__;
00012 #endif
00013
00015
00016
00017 IMPLEMENT_SERIAL(CDistribution, CObject, VERSION_NUMBER)
00018
00019 CDistribution::CDistribution():PI(3.14159265359)
00020 {
00021 m_DistributionID = DIST_NORMAL;
00022 m_Location = 10.0;
00023 m_Scale = 2.0;
00024 m_Shape = 0.0;
00025 }
00026
00027 CDistribution::CDistribution(double loc, double sc, double sh):PI(3.14159265359)
00028 {
00029 m_DistributionID = DIST_NORMAL;
00030 m_Location = loc;
00031 m_Scale = sc;
00032 m_Shape = sh;
00033 }
00034
00035 CDistribution::~CDistribution()
00036 {
00037
00038 }
00039
00040 CDistribution::CDistribution(const CDistribution& dist):PI(3.14159265359)
00041 {
00042 this->setDistributionID( dist.getDistributionID() );
00043 this->setLocation( dist.getLocation() );
00044 this->setScale( dist.getScale() );
00045 this->setShape( dist.getShape() );
00046 }
00047
00048
00049 MTRand CDistribution::m_RNG;
00050
00052
00053
00054 #ifdef _DEBUG
00055 void CDistribution::AssertValid() const
00056 {
00057 CObject::AssertValid();
00058 }
00059
00060 void CDistribution::Dump(CDumpContext& dc) const
00061 {
00062 CObject::Dump(dc);
00063 }
00064 #endif //_DEBUG
00065
00067
00068
00069 void CDistribution::Serialize(CArchive& ar)
00070 {
00071 if (ar.IsStoring())
00072 {
00073 ar << m_DistributionID
00074 << m_Location
00075 << m_Scale
00076 << m_Shape;
00077 }
00078 else
00079 {
00080 ar >> m_DistributionID
00081 >> m_Location
00082 >> m_Scale
00083 >> m_Shape;
00084 }
00085 }
00086
00088
00089
00090 CDistribution& CDistribution::operator=(const CDistribution &dist)
00091 {
00092 this->setDistributionID( dist.getDistributionID() );
00093 this->setLocation( dist.getLocation() );
00094 this->setScale( dist.getScale() );
00095 this->setShape( dist.getShape() );
00096
00097 return *this;
00098 }
00099
00100 WORD CDistribution::getDistributionID() const
00101 {
00102 return m_DistributionID;
00103 }
00104
00105 double CDistribution::getLocation() const
00106 {
00107 return m_Location;
00108 }
00109
00110 double CDistribution::getScale() const
00111 {
00112 return m_Scale;
00113 }
00114
00115 double CDistribution::getShape() const
00116 {
00117 return m_Shape;
00118 }
00119
00120 void CDistribution::setDistributionID(WORD id)
00121 {
00122 m_DistributionID = id;
00123 }
00124
00125 void CDistribution::setLocation(double loc)
00126 {
00127 m_Location = loc;
00128 }
00129
00130 void CDistribution::setScale(double sc)
00131 {
00132 m_Scale = sc;
00133 }
00134
00135 void CDistribution::setShape(double sh)
00136 {
00137 m_Shape = sh;
00138 }
00139
00140
00141 double CDistribution::Generate()
00142 {
00143 switch(m_DistributionID)
00144 {
00145 case DIST_EXPONENTIAL:
00146 return GenerateExponential();
00147 case DIST_LOGNORMAL:
00148 return GenerateLogNormal();
00149 case DIST_GAMMA:
00150 return GenerateGamma();
00151 case DIST_GUMBEL:
00152 return GenerateGumbel();
00153 case DIST_POISSON:
00154 return GeneratePoisson();
00155 case DIST_GEV:
00156 return GenerateGEV();
00157 case DIST_NORMAL:
00158 return GenerateNormal();
00159 case DIST_CONST:
00160 return m_Location;
00161 default:
00162 return m_Location;
00163 }
00164 }
00165
00167
00168
00169 double CDistribution::GenerateExponential()
00170 {
00171 double u01 = m_RNG.rand();
00172 double val = -log(u01);
00173 return val;
00174 }
00175
00176 double CDistribution::GenerateLogNormal()
00177 {
00178 double x[2], u[2];
00179 u[0] = m_RNG.rand();
00180 u[1] = m_RNG.rand();
00181 x[0] = m_Location + m_Scale * sqrt(-2 * log(u[0])) * cos(2 * PI * u[1]);
00182 x[1] = m_Location + m_Scale * sqrt(-2 * log(u[0])) * sin(2 * PI * u[1]);
00183 double val = exp( x[ (int)(u[1] + 0.5) ] );
00184
00185 return val;
00186 }
00187
00188 double CDistribution::GenerateGamma()
00189 {
00190 double u[2];
00191 u[0] = m_RNG.rand();
00192 u[1] = m_RNG.rand();
00193 u[2] = m_RNG.rand();
00194 double val = (1/m_Location)
00195 * (-log(u[2]))
00196 * pow( u[0], (1/m_Scale) )
00197 / pow( u[0], (1/m_Scale)
00198 + pow( u[1], (1/(1 - m_Scale)) ) );
00199
00200 return val;
00201 }
00202
00203 double CDistribution::GenerateGumbel()
00204 {
00205 double u01 = m_RNG.rand();
00206 double val = m_Location - (1 / m_Scale) * log(log(1 / u01));
00207
00208 return val;
00209 }
00210
00211 double CDistribution::GeneratePoisson()
00212 {
00213 double x[2], u[2];
00214 u[0] = m_RNG.rand();
00215 u[1] = m_RNG.rand();
00216
00217 double m = m_Location - 0.5;
00218 double sigma = sqrt(m_Scale);
00219
00220 x[0] = m + sigma * sqrt(-2 * log(u[0])) * cos(2 * PI * u[1]);
00221 x[1] = m + sigma * sqrt(-2 * log(u[0])) * sin(2 * PI * u[1]);
00222 double val = x[ (int)(u[1] + 0.5) ];
00223
00224 return val;
00225 }
00226
00227 double CDistribution::GenerateGEV()
00228 {
00229 double u01 = m_RNG.rand();
00230 double val = m_Location + m_Scale * (1 - pow(-log(u01),m_Shape)) / m_Shape;
00231
00232 return val;
00233 }
00234
00235 double CDistribution::GenerateNormal()
00236 {
00237 return m_Location + m_Scale * BoxMuller();
00238 }
00239
00240 double CDistribution::BoxMuller()
00241 {
00242
00243
00244 double x1, x2, w, y1;
00245 static double y2;
00246 static int use_last = 0;
00247
00248 if (use_last)
00249 {
00250 y1 = y2;
00251 use_last = 0;
00252 }
00253 else
00254 {
00255 do {
00256 x1 = 2.0 * m_RNG.rand() - 1.0;
00257 x2 = 2.0 * m_RNG.rand() - 1.0;
00258 w = x1 * x1 + x2 * x2;
00259 } while ( w >= 1.0 );
00260
00261 w = sqrt( (-2.0 * log( w ) ) / w );
00262 y1 = x1 * w;
00263 y2 = x2 * w;
00264 use_last = 1;
00265 }
00266 return( y1 );
00267 }
00268
00269 double CDistribution::GenKeepingCoV(double newLocation)
00270 {
00271 const double zero = 0.0001;
00272 double val = m_Location;
00273 if( (m_Scale > zero || m_Scale < -zero) && (m_Location > zero || m_Location < -zero) )
00274 {
00275 double CoV = m_Scale / m_Location;
00276 double OldScale = m_Scale;
00277 double OldLocation = m_Location;
00278
00279
00280 m_Scale = newLocation * CoV;
00281 m_Location = newLocation;
00282 val = Generate();
00283
00284 m_Scale = OldScale;
00285 m_Location = OldLocation;
00286 }
00287 return val;
00288 }