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

通讯编程

开发平台:

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 <stdio.h>
  42. #include "rng.h"
  43. #define ROOT_2 1.4142135623730950488016887242096980785697 /*2^1/2*/
  44. #define E22    1.7155277699214135929603792825575449562416 /*sqrt(8/e) */
  45. double RNG::gammln (double xx) 
  46. {
  47. int j;
  48. double x, y, tmp, ser;
  49. static double cof[6]={76.18009172947146,-86.50532032941677,
  50.       24.01409824083091,-1.231739572450155,
  51.       0.1208650973866179e-2,-0.5395239384953e-5};
  52. y = x = xx;
  53. tmp = x+5.5;
  54. tmp -= (x+0.5) * log(tmp);
  55. ser = 1.000000000190015;
  56. for (j=0; j<=5; j++) 
  57. ser += cof[j] / ++y;
  58. return (-tmp + log(2.5066282746310005*ser/x));
  59. }
  60. double RNG::pnorm (double q) 
  61. if (q == 0)
  62. return(0.5);
  63. else if (q > 0)
  64. return((1 + erf(q/ROOT_2))/2);
  65. else
  66. return(erfc(-q/ROOT_2)/2);
  67. }
  68. double 
  69. RNG::rnorm (void) 
  70. {
  71. double u, x, y;
  72. do {
  73. u = uniform();
  74. while(u==0)
  75. u = uniform();
  76. x = E22 * (uniform() - 0.5) / u;
  77. y = x * x / 4.0;
  78. } while (y > 1.0 - u && (y > 1.0/u - 1.0 || y > -log(u)));
  79. return(x);
  80. }
  81. int 
  82. RNG::rbernoulli (double p) {
  83. double x; 
  84. int z; 
  85.   
  86. x = uniform();
  87. if (x <= p) 
  88. z=1; 
  89. else 
  90. z=0;
  91. return(z);
  92. }
  93. // this is taken from the R src code
  94. // generate standard exponential variate
  95. double RNG::exp_rand (void)
  96. {
  97. /** q[k-1] = sum(log(2)^k / k!)  k=1,..,n, 
  98.  *  The highest n (here 8) is determined by q[n-1] = 1.0 
  99.  *  within standard precision 
  100.  */
  101. const double q[] = {
  102. 0.6931471805599453,
  103. 0.9333736875190459,
  104. 0.9888777961838675,
  105. 0.9984959252914960,
  106. 0.9998292811061389,
  107. 0.9999833164100727,
  108. 0.9999985691438767,
  109. 0.9999998906925558,
  110. 0.9999999924734159,
  111. 0.9999999995283275,
  112. 0.9999999999728814,
  113. 0.9999999999985598,
  114. 0.9999999999999289,
  115. 0.9999999999999968,
  116. 0.9999999999999999,
  117. 1.0000000000000000
  118. };
  119. double a, u, ustar, umin;
  120. int i;
  121. a = 0.;
  122. u = uniform();
  123. for (;;) {
  124. u += u;
  125. if (u > 1.0)
  126. break;
  127. a += q[0];
  128. }
  129. u -= 1.;
  130. if (u <= q[0])
  131. return a + u;
  132. i = 0;
  133. ustar = uniform();
  134. umin = ustar;
  135. do {
  136. ustar = uniform();
  137. if (ustar < umin)
  138. umin = ustar;
  139. i++;
  140. } while (u > q[i]);
  141. return a + umin * q[0];
  142. }
  143. #define repeat for(;;)
  144. double RNG::rgamma (double a, double scale)
  145. {
  146. /* Constants : */
  147. const double sqrt32 = 5.656854;
  148. const double exp_m1 = 0.36787944117144232159;/* exp(-1) = 1/e */
  149. /** Coefficients q[k] - for q0 = sum(q[k]*a^(-k))
  150.  *  Coefficients a[k] - for q = q0+(t*t/2)*sum(a[k]*v^k)
  151.  *  Coefficients e[k] - for exp(q)-1 = sum(e[k]*q^k)
  152.  */
  153. const double q1 = 0.04166669;
  154. const double q2 = 0.02083148;
  155. const double q3 = 0.00801191;
  156. const double q4 = 0.00144121;
  157. const double q5 = -7.388e-5;
  158. const double q6 = 2.4511e-4;
  159. const double q7 = 2.424e-4;
  160. const double a1 = 0.3333333;
  161. const double a2 = -0.250003;
  162. const double a3 = 0.2000062;
  163. const double a4 = -0.1662921;
  164. const double a5 = 0.1423657;
  165. const double a6 = -0.1367177;
  166. const double a7 = 0.1233795;
  167. const double e1 = 1.0;
  168. const double e2 = 0.4999897;
  169. const double e3 = 0.166829;
  170. const double e4 = 0.0407753;
  171. const double e5 = 0.010293;
  172. /* State variables [FIXME for threading!] :*/
  173. static double aa = 0.;
  174. static double aaa = 0.;
  175. static double s, s2, d;    /* no. 1 (step 1) */
  176. static double q0, b, si, c;/* no. 2 (step 4) */
  177. double e, p, q, r, t, u, v, w, x, ret_val;
  178. if (a < 1.) { /* GS algorithm for parameters a < 1 */
  179. e = 1.0 + exp_m1 * a;
  180. repeat {
  181. p = e * uniform();
  182. if (p >= 1.0) {
  183. x = -log((e - p) / a);
  184. if (exp_rand() >= (1.0 - a) * log(x))
  185. break;
  186. } else {
  187. x = exp(log(p) / a);
  188. if (exp_rand() >= x)
  189. break;
  190. }
  191. }
  192. return scale * x;
  193. }
  194. /* --- a >= 1 : GD algorithm --- */
  195. /* Step 1: Recalculations of s2, s, d if a has changed */
  196. if (a != aa) {
  197. aa = a;
  198. s2 = a - 0.5;
  199. s = sqrt(s2);
  200. d = sqrt32 - s * 12.0;
  201. }
  202. /** Step 2: t = standard normal deviate,
  203.          *     x = (s,1/2) -normal deviate. 
  204.  */
  205. /* immediate acceptance (i) */
  206. t = rnorm();
  207. x = s + 0.5 * t;
  208. ret_val = x * x;
  209. if (t >= 0.0)
  210. return scale * ret_val;
  211. /* Step 3: u = 0,1 - uniform sample. squeeze acceptance (s) */
  212. u = uniform();
  213. if (d * u <= t * t * t)
  214. return scale * ret_val;
  215. /* Step 4: recalculations of q0, b, si, c if necessary */
  216. if (a != aaa) {
  217. aaa = a;
  218. r = 1.0 / a;
  219. q0 = ((((((q7 * r + q6) * r + q5) * r + q4) * r + q3) * r 
  220.        + q2) * r + q1) * r;
  221. /** Approximation depending on size of parameter a 
  222.  * The constants in the expressions for b, si and c 
  223.  * were established by numerical experiments 
  224.  */
  225. if (a <= 3.686) {
  226. b = 0.463 + s + 0.178 * s2;
  227. si = 1.235;
  228. c = 0.195 / s - 0.079 + 0.16 * s;
  229. } else if (a <= 13.022) {
  230. b = 1.654 + 0.0076 * s2;
  231. si = 1.68 / s + 0.275;
  232. c = 0.062 / s + 0.024;
  233. } else {
  234. b = 1.77;
  235. si = 0.75;
  236. c = 0.1515 / s;
  237. }
  238. }
  239. /* Step 5: no quotient test if x not positive */
  240. if (x > 0.0) {
  241. /* Step 6: calculation of v and quotient q */
  242. v = t / (s + s);
  243. if (fabs(v) <= 0.25)
  244. q = q0 + 0.5 * t * t * 
  245. ((((((a7 * v + a6) * v + a5) * v + a4) * 
  246.    v + a3) * v + a2) * v + a1) * v;
  247. else
  248. q = q0 - s * t + 0.25 * t * t + (s2 + s2) * 
  249. log(1.0 + v);
  250. /* Step 7: quotient acceptance (q) */
  251. if (log(1.0 - u) <= q)
  252. return scale * ret_val;
  253. }
  254. repeat {
  255. /** Step 8: e = standard exponential deviate
  256.  * u =  0,1 -uniform deviate
  257.  * t = (b,si)-double exponential (laplace) sample 
  258.  */
  259. e = exp_rand();
  260. u = uniform();
  261. u = u + u - 1.0;
  262. if (u < 0.0)
  263. t = b - si * e;
  264. else
  265. t = b + si * e;
  266. /* Step  9:  rejection if t < tau(1) = -0.71874483771719 */
  267. if (t >= -0.71874483771719) {
  268. /* Step 10:  calculation of v and quotient q */
  269. v = t / (s + s);
  270. if (fabs(v) <= 0.25)
  271. q = q0 + 0.5 * t * t * 
  272. ((((((a7 * v + a6) * v + a5) * v + a4) * 
  273.    v + a3) * v + a2) * v + a1) * v;
  274. else
  275. q = q0 - s * t + 0.25 * t * t + (s2 + s2) * 
  276. log(1.0 + v);
  277. /** Step 11:  hat acceptance (h) 
  278.  * (if q not positive go to step 8) 
  279.  */
  280. if (q > 0.0) {
  281. if (q <= 0.5)
  282. w = ((((e5 * q + e4) * q + e3) * q + e2) * q + e1) * q;
  283. else
  284. w = exp(q) - 1.0;
  285. /* if t is rejected sample again at step 8 */
  286. if (c * fabs(u) <= w * exp(e - 0.5 * t * t))
  287. break;
  288. }
  289. }
  290. }
  291. x = s + 0.5 * t;
  292. return scale * x * x;
  293. }