-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom_variable.py
98 lines (85 loc) · 2.66 KB
/
random_variable.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import sys
import os
import random
import math
import argparse
import numpy as np
import scipy.stats
class CDFentry:
def __init__(self):
cdf_ = 0
val_ = 0
class UniformRandomVariable:
def __init__(self):
self.min_ = 0.0
self.max_ = 1.0
def value(self):
unif0_1 = random.random()
return self.min_ + (self.max_ - self.min_) * unif0_1
class ExponentialRandomVariable:
def __init__(self, avg):
self.avg_ = avg
self.urv = UniformRandomVariable()
def value(self):
return -1.0 * self.avg_ * math.log(self.urv.value())
class EmpiricalRandomVariable:
def __init__(self, filename, smooth):
self.smooth = smooth
self.minCDF_ = 0
self.maxCDF_ = 1
self.table_ = []
for i in range(65536):
self.table_.append(CDFentry())
if(filename != ""):
self.loadCDF(filename)
def loadCDF(self, filename):
numEntry_ = 0
prev_cd = 0
prev_sz = 1
w_sum = 0
file = open(filename, "r")
f = file.readlines()
for line in f:
values = line.split()
self.table_[numEntry_].val_ = float(values[0])
self.table_[numEntry_].cdf_ = float(values[1])
self.table_[numEntry_].cdf_ = float(values[2])
freq = self.table_[numEntry_].cdf_ - prev_cd
flow_sz = 0
if self.smooth:
flow_sz = (self.table_[numEntry_].val_ + prev_sz) / 2.0
else:
flow_sz = self.table_[numEntry_].val_
w_sum += freq * flow_sz
prev_cd = self.table_[numEntry_].cdf_
prev_sz = self.table_[numEntry_].val_
numEntry_ += 1
self.mean_flow_size = w_sum * 1460.0;
file.close()
self.numEntry_ = numEntry_
return numEntry_
def lookup(self, u):
lo = 1
hi = self.numEntry_ - 1
mid = 0
if u <= self.table_[0].cdf_:
return 0
while lo < hi:
mid = int((lo + hi) / 2)
if u > self.table_[mid].cdf_:
lo = mid + 1
else:
hi = mid
return lo
def interpolate(self, x, x1, y1, x2, y2):
value = y1 + (x - x1) * (y2 - y1) / (x2 - x1)
return value
def value(self):
if self.numEntry_ <= 0:
return 0
u = random.random()
mid = self.lookup(u)
if mid != 0 and u < self.table_[mid].cdf_:
return self.interpolate(u, self.table_[mid-1].cdf_, self.table_[mid-1].val_,
self.table_[mid].cdf_, self.table_[mid].val_)
return self.table_[mid].val_