packmime_OL_ranvar.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:14k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /* 
  3.  * Copyright 2002, Statistics Research, Bell Labs, Lucent Technologies and
  4.  * The University of North Carolina at Chapel Hill
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without 
  7.  * modification, are permitted provided that the following conditions are met:
  8.  * 
  9.  *    1. Redistributions of source code must retain the above copyright 
  10.  * notice, this list of conditions and the following disclaimer.
  11.  *    2. Redistributions in binary form must reproduce the above copyright 
  12.  * notice, this list of conditions and the following disclaimer in the 
  13.  * documentation and/or other materials provided with the distribution.
  14.  *    3. The name of the author may not be used to endorse or promote 
  15.  * products derived from this software without specific prior written 
  16.  * permission.
  17.  * 
  18.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
  19.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  20.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
  21.  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
  22.  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
  23.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  24.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  25.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  26.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
  27.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
  28.  * POSSIBILITY OF SUCH DAMAGE.
  29.  */
  30. /*
  31.  * Reference
  32.  *     Stochastic Models for Generating Synthetic HTTP Source Traffic 
  33.  *     J. Cao, W.S. Cleveland, Y. Gao, K. Jeffay, F.D. Smith, and M.C. Weigle 
  34.  *     IEEE INFOCOM 2004.
  35.  *
  36.  * Documentation available at http://dirt.cs.unc.edu/packmime/
  37.  * 
  38.  * Contacts: Michele Weigle (mcweigle@cs.unc.edu),
  39.  *           Kevin Jeffay (jeffay@cs.unc.edu)
  40.  */
  41. #include <sys/types.h>
  42. #include <sys/stat.h> 
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <math.h>
  46. #include <assert.h>
  47. #include "packmime_OL_ranvar.h"
  48. /**
  49.  * Reference:
  50.  * Modeling Persistence in Hydrological Time Series Using Fractional 
  51.  * Differencing
  52.  * By J.R.M. Hosking, Water Resources Research, Vol 20, No 12, P1898-1908, 
  53.  * Dec 1984
  54.  *
  55.  * y[t] = sum_j=1^p (AR[j] * y[t-j]) + x[t] - sum_j=1^q (MA[j] * x[t-j]
  56.  */
  57. #define ROOT_2 1.4142135623730950488016887242096980785697 /*2^1/2*/
  58. #define E22    1.7155277699214135929603792825575449562416 /*sqrt(8/e) */
  59. #define EPSILON 1e-2
  60. #define Min(a, b)      ((a) < (b) ? (a) : (b))
  61. /**
  62.  * hard wired model constants from fitting BL-MH packet trace
  63.  * (all tcp, both directions), parameters values from 
  64.  * /home/cao/MySwork/packet/dataObj/superpose/.Data/pac.fit1.para.vs.rate.fit
  65.  * ; the original code to produce parameters is in superpose_par_vs_rate.S
  66.  */
  67. //static struct OL_weibull_params pac_ia_weibull_params = {
  68. //  -0.487,   /* shapeParam0 */
  69. //  0.032,    /* shapeParam1 */
  70. //  1.702     /* shapeParam2 */
  71. //};
  72. static struct OL_arima_params pac_ia_arima_params = {
  73.   0.41,      /* d */
  74.   1000,      /* number of finite AR rep of farima */
  75.   0, 1,      /* pAR=0, qMA */
  76.   -1.345,    /* varRatioParam0 */ 
  77.   0.009,     /* varRatioParam1 */
  78.   2.217      /* varRatioParam2 */
  79. };
  80. /*:::::::::::::::::::::: Packet Inter-Arrival RanVar :::::::::::::::::*/
  81. static class PackMimeOLPacketIARandomVariableClass : public TclClass {
  82. public:
  83. PackMimeOLPacketIARandomVariableClass() : 
  84.   TclClass("RandomVariable/PackMimeOLPacketIA"){}
  85. TclObject* create(int argc, const char*const* argv) {
  86. if (argc == 5) {
  87. // bitrate
  88. return(new PackMimeOLPacketIARandomVariable((double)atof(argv[4])));
  89. } else if (argc == 6) {
  90. // bitrate, RNG       
  91. RNG* rng = (RNG*)TclObject::lookup(argv[5]);
  92. return(new PackMimeOLPacketIARandomVariable((double)atof(argv[4]), rng));
  93. } else if (argc == 7) {
  94. // bitrate, RNG
  95. RNG* rng = (RNG*)TclObject::lookup(argv[5]);
  96. PackMimeOLPacketIARandomVariable *iarng = new PackMimeOLPacketIARandomVariable((double)atof(argv[4]), rng);
  97. RandomVariable *sizerng_ = (RandomVariable*)TclObject::lookup(argv[6]);
  98. iarng->setPktSizeRng(sizerng_);
  99. return(iarng);
  100. } else {
  101. return(new PackMimeOLPacketIARandomVariable());
  102. }
  103.  }
  104. } class_PacketIAranvar;
  105. PackMimeOLPacketIARandomVariable::PackMimeOLPacketIARandomVariable(): 
  106. fARIMA(NULL), myrng(NULL), sizerng(NULL)
  107. {
  108. bind_vars();
  109. }
  110. PackMimeOLPacketIARandomVariable::PackMimeOLPacketIARandomVariable(double bitrate_) :
  111. bitrate(bitrate_), fARIMA(NULL), myrng(NULL), sizerng(NULL)
  112. {
  113. bind_vars();
  114. }
  115. PackMimeOLPacketIARandomVariable::PackMimeOLPacketIARandomVariable(double bitrate_, RNG* rng_) :
  116. bitrate(bitrate_), fARIMA(NULL), myrng(rng_), sizerng(NULL)
  117. {
  118. bind_vars();
  119. }
  120. void PackMimeOLPacketIARandomVariable::bind_vars() {
  121. bind ("bitrate", &bitrate);
  122. bind ("pacrate", &pacrate);
  123. bind ("connum", &connum);
  124. bind ("conbps", &conbps);
  125. bind ("conpacrate", &conpacrate);
  126. }
  127. /* initialize for pac.ia */
  128. void PackMimeOLPacketIARandomVariable::initialize() {
  129. double sigmaTotal;
  130. struct OL_arima_params *arima = &pac_ia_arima_params;
  131. // struct OL_weibull_params *weibull = &pac_ia_weibull_params;
  132. double d = arima->d;
  133. double logit_simia;
  134. assert(arima->N >= arima->qMA);
  135. if (sizerng==NULL)
  136. sizerng = new PackMimeOLPacketSizeRandomVariable();
  137. if (conbps<=0)
  138. conbps = conpacrate * sizerng->avg() * 8;
  139. if (connum<=0)
  140. connum = bitrate/conbps;
  141. if (pacrate<=0)
  142. pacrate = bitrate/sizerng->avg()/8;
  143. /**
  144.  * old method
  145.  * varRatio = 1.0 - pow(2.0, arima->varRatioParam0 - 
  146.  *      arima->varRatioParam1 * pow(log(rate)/LOG2,
  147.  *      arima->varRatioParam2)); 
  148.  */
  149. logit_simia = pow(2.0, -0.6661682 + 0.4192597*log(connum)/LOG2);
  150. varRatio = logit_simia/(1+logit_simia);
  151. sigmaTotal = 1.0;
  152. sigmaNoise = sigmaTotal * pow(varRatio,0.5);
  153. sigmaEpsilon = sigmaTotal * 
  154. pow(exp(2.0*myrng->gammln(1.0-d)-myrng->gammln(1.0-2.0*d))/(2+2*d/(1-d)) * (1-varRatio),
  155.     0.5);
  156. /**
  157.  * shape = 1.0 - pow(2.0, 
  158.  *     weibull->shapeParam0 - 
  159.  *     weibull->shapeParam1 * pow(log(rate)/LOG2, 
  160.  *        weibull->shapeParam2));
  161.  */
  162. logit_simia = pow(2.0, -2.462267 + 0.4920002*log(connum)/LOG2);
  163. shape = logit_simia/(1+logit_simia);
  164. scale = 1.0 / (connum * exp(myrng->gammln(1+1.0/shape)));
  165. if (!myrng)
  166. myrng = new RNG();
  167. fARIMA = new FARIMA(myrng, arima->d, arima->N);
  168. }
  169. PackMimeOLPacketIARandomVariable::~PackMimeOLPacketIARandomVariable() {
  170. delete myrng;
  171. delete fARIMA;
  172. }
  173. /** 
  174.  * generate packet IA according to the marginal distribution 
  175.  */
  176. double PackMimeOLPacketIARandomVariable::transform(double p)
  177. {
  178. double yt;
  179.  
  180. yt = myrng->qweibull(p, shape, scale);
  181.   
  182. return(yt);
  183. }
  184. /**
  185.  * generate packet IA according to Long-Range Dependent plus Noise (LRDN) model 
  186.  */
  187. double PackMimeOLPacketIARandomVariable::value() {
  188. double yt;
  189. if (fARIMA == NULL)
  190. initialize();
  191. yt = fARIMA->Next();
  192. yt = yt * sigmaEpsilon + myrng->rnorm() * sigmaNoise;
  193. yt = transform(myrng->pnorm(yt));
  194. return(yt);
  195. }
  196. double PackMimeOLPacketIARandomVariable::avg() {
  197. if (fARIMA == NULL)
  198. initialize();
  199. if (pacrate!=0)
  200. return (1/pacrate);
  201. else
  202. return 0;
  203. }
  204. /**
  205.  * hard wired model constants from fitting BL-MH packet trace
  206.  */
  207. static struct OL_arima_params pac_size_arima_params = {
  208.   0.41,         /* d */
  209.   1000,         /* number of finite AR rep of farima */
  210.   0, 1,         /* pAR=0, qMA */
  211.   
  212.   -0.051,       /* varRatioParam0 */
  213.   0.08,         /* varRatioParam1 */ 
  214.   1.597         /* varRatioParam2 */
  215. };
  216. /*:::::::::::::::::::::: Packet Size RanVar :::::::::::::::::*/
  217. static class PackMimeOLPacketSizeRandomVariableClass : public TclClass {
  218. public:
  219. PackMimeOLPacketSizeRandomVariableClass() : 
  220.   TclClass("RandomVariable/PackMimeOLPacketSize"){}
  221. TclObject* create(int argc, const char*const* argv) {
  222. if (argc == 5) {
  223. // rate
  224. return(new PackMimeOLPacketSizeRandomVariable((double)atof(argv[4])));
  225. } else if (argc == 6) {
  226. // rate, RNG
  227. RNG* rng = (RNG*)TclObject::lookup(argv[5]);
  228. return(new PackMimeOLPacketSizeRandomVariable((double)atof(argv[4]), rng));
  229. } else if (argc == 7) {
  230. // rate, RNG, filename
  231. RNG* rng = (RNG*)TclObject::lookup(argv[5]);
  232. return(new PackMimeOLPacketSizeRandomVariable((double)atof(argv[4]), rng, argv[6]));
  233. } else {
  234. return(new PackMimeOLPacketSizeRandomVariable());
  235. }
  236.  }
  237. } class_PackMimeOLPacketSizeranvar;
  238. PackMimeOLPacketSizeRandomVariable::PackMimeOLPacketSizeRandomVariable():
  239. pac_size_dist_file(NULL), fARIMA(NULL), myrng(NULL)
  240. {
  241. bind_vars();
  242. }
  243. PackMimeOLPacketSizeRandomVariable::PackMimeOLPacketSizeRandomVariable(double bitrate_):
  244. bitrate(bitrate_), pac_size_dist_file(NULL), fARIMA(NULL), myrng(NULL)
  245. {
  246. bind_vars();
  247. }
  248. PackMimeOLPacketSizeRandomVariable::PackMimeOLPacketSizeRandomVariable(double bitrate_, RNG* rng_):
  249. bitrate(bitrate_), pac_size_dist_file(NULL), fARIMA(NULL), myrng(rng_)
  250. {
  251. bind_vars();
  252. }
  253. PackMimeOLPacketSizeRandomVariable::PackMimeOLPacketSizeRandomVariable(double bitrate_, RNG* rng_, const char *pac_size_dist_file_):
  254. bitrate(bitrate_), fARIMA(NULL), myrng(rng_)
  255. {
  256. bind_vars();
  257. pac_size_dist_file = new char[strlen(pac_size_dist_file_)+1];
  258.         strcpy(pac_size_dist_file, pac_size_dist_file_);
  259. }
  260. void PackMimeOLPacketSizeRandomVariable::bind_vars() {
  261. bind ("bitrate", &bitrate);
  262. bind ("connum", &connum);
  263. bind ("conbps", &conbps);
  264. bind ("conpacrate", &conpacrate);
  265. }
  266. int PackMimeOLPacketSizeRandomVariable::def_size_dist_left[14] =  {40,    41,    44,    45,    48,    49,    52,    53,    85,    221,   576,   577,   1401,  1500};
  267. int PackMimeOLPacketSizeRandomVariable::def_size_dist_right[14] = {40,    43,    44,    47,    48,    51,    52,    84,    220,   575,   576,   1400,  1499,  1500};
  268. double PackMimeOLPacketSizeRandomVariable::def_size_prob[14] =    {0.300, 0.000, 0.030, 0.000, 0.030, 0.010, 0.060, 0.070, 0.050, 0.070, 0.120, 0.060, 0.050, 0.150 };
  269. /**
  270.  * initialise for pac.size
  271.  */
  272. void PackMimeOLPacketSizeRandomVariable::initialize()
  273. {
  274. double sigmaTotal;
  275. struct OL_arima_params *arima = &pac_size_arima_params;
  276. double d = arima->d;
  277. double logit_simsize;
  278.   
  279. assert(arima->N >= arima->qMA);
  280. if (conbps<=0)
  281. conbps = conpacrate * avg() * 8;
  282. if (connum<=0)
  283. connum = bitrate/conbps;
  284. /**
  285.  * old method 
  286.  * varRatio = 1.0 - pow(2.0, 
  287.          *              arima->varRatioParam0 - 
  288.          *              arima->varRatioParam1 * pow(log(rate)/LOG2, 
  289.  *    arima->varRatioParam2));
  290.  */
  291. logit_simsize = pow(2.0, -3.117395 + 0.7224436*log(connum)/LOG2);
  292. varRatio = logit_simsize/(1+logit_simsize);
  293. sigmaTotal = 1.0;
  294. sigmaNoise = sigmaTotal * pow(varRatio,0.5);
  295. sigmaEpsilon = sigmaTotal * 
  296. pow(exp(2.0*myrng->gammln(1.0-d)-myrng->gammln(1.0-2.0*d))/(2+2*d/(1-d)) * (1-varRatio),
  297.     0.5); 
  298. if (!myrng)
  299. myrng = new RNG();
  300. fARIMA = new FARIMA(myrng, arima->d, arima->N);
  301. init_dist();
  302. }
  303. void PackMimeOLPacketSizeRandomVariable::init_dist() {
  304. int n;
  305. if (pac_size_dist_file==NULL) {
  306. size_dist_left = def_size_dist_left;
  307. size_dist_right = def_size_dist_right;
  308. size_prob = def_size_prob;
  309. n_size_dist = sizeof(def_size_dist_left)/sizeof(int);
  310. } else
  311. read_dist();
  312.   
  313. /* cumsum_size_prob = cumsum(prob0, prob1, prob2, ..., prob(n-1))
  314.  * cumsum_size_prob[last] = 1 
  315.  */
  316. cumsum_size_prob = new double[n_size_dist];
  317. for(n=0; n<n_size_dist; n++){
  318. if(n==0) {
  319. cumsum_size_prob[0] = size_prob[0];
  320. } else {
  321. cumsum_size_prob[n] = cumsum_size_prob[n-1] + size_prob[n]; 
  322. }    
  323. }
  324. }
  325. void PackMimeOLPacketSizeRandomVariable::read_dist() {
  326. FILE *fp;
  327. double totalprob;
  328. int n;
  329. if((fp = fopen(pac_size_dist_file, "r")) == NULL) {
  330. fprintf(stderr, "Error: can't open %sn", pac_size_dist_file);
  331. exit(1);
  332. n = 0;   /* line number - 1 */
  333. totalprob = 0;
  334. do {
  335. if(n == 0 ) {
  336. fscanf(fp, "%dn", &n_size_dist);
  337. size_dist_left = new int[n_size_dist];
  338. size_dist_right = new int[n_size_dist];
  339. size_prob = new double[n_size_dist];
  340. } else { 
  341. fscanf(fp, "%d %d %lfn", &size_dist_left[n-1],
  342.        &size_dist_right[n-1], &size_prob[n-1]); 
  343. if(size_dist_right[n-1] < size_dist_left[n-1]) {
  344. fprintf(stderr, 
  345. "Error: size_dist_right must >= size_dist_leftn");
  346. exit(1);
  347. }
  348. if(n>1) {
  349. if(size_dist_left[n-1] != size_dist_right[n-2]+1){
  350. fprintf(stderr, 
  351. "Error: size_dist_left(n) must = size_dist_right(n-1)+1n");
  352. exit(1);
  353. }
  354. }
  355. totalprob += size_prob[n-1];
  356. }
  357. n++;
  358. } while((n <= n_size_dist) && !feof(fp));
  359.     
  360. if(totalprob>1){
  361. fprintf(stderr, "Error: sum of size_prob > 1, check!n");
  362. } else {
  363. if(totalprob < 1-EPSILON) {
  364. fprintf(stderr, 
  365. "size_prob[%d] increase from %g to %g, so sum of prob. is 1n",
  366. n_size_dist-1, size_prob[n_size_dist-1],
  367. size_prob[n_size_dist-1]+(1-totalprob));
  368. }
  369. size_prob[n_size_dist-1] = size_prob[n_size_dist-1]+(1-totalprob);
  370. }
  371. if(n <= n_size_dist) {
  372. fprintf(stderr, "Error: wrong value of n_size_dist in %s!n", 
  373. pac_size_dist_file);
  374. exit(1);
  375. }
  376. fclose(fp);  
  377. }
  378. PackMimeOLPacketSizeRandomVariable::~PackMimeOLPacketSizeRandomVariable() {
  379. delete fARIMA;
  380. if(n_size_dist > 0){
  381. delete size_dist_left;
  382. delete size_dist_right;
  383. delete size_prob;
  384. delete cumsum_size_prob;
  385. }
  386. }
  387. /**
  388.  * generate packet size according to the marginal distribution 
  389.  */
  390. int PackMimeOLPacketSizeRandomVariable::transform(double p) {
  391. int i, size;
  392. double p1;
  393. i = 0;
  394. while(p > cumsum_size_prob[i])  
  395. i++; 
  396.   
  397. p1 = cumsum_size_prob[i]-cumsum_size_prob[i-1];
  398. size = (size_dist_left[i]-1) + (int) (ceil((p-cumsum_size_prob[i-1])/p1 * 
  399.        (size_dist_right[i]-(size_dist_left[i]-1))));
  400. return size;
  401. }
  402. /** 
  403.  * compute the mean of packet size distribution
  404.  */
  405. double PackMimeOLPacketSizeRandomVariable::avg() {
  406. int i;
  407. double m = 0;
  408. if (fARIMA == NULL)
  409. init_dist();
  410. for(i=0; i<n_size_dist; i++)
  411. m += size_prob[i] * (size_dist_left[i]+size_dist_right[i])/2;
  412. return m;
  413. }
  414. /**
  415.  * generate packet size according to Long-Range Dependent plus Noise (LRDN) model 
  416.  */
  417. double PackMimeOLPacketSizeRandomVariable::value(void) {
  418. double yt;
  419. if (fARIMA == NULL)
  420. initialize();
  421. yt = fARIMA->Next();
  422. yt = yt * sigmaEpsilon + myrng->rnorm() * sigmaNoise;
  423. return ((double)transform(myrng->pnorm(yt)));
  424. }