-
Notifications
You must be signed in to change notification settings - Fork 0
/
experimental_design.py
112 lines (95 loc) · 4.03 KB
/
experimental_design.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"""
Functions for generating values according to a WSP file and the Experimental Design method
"""
from itertools import chain
def flatten(l):
"""
inefficiently flattens a list
l: an arbitrary list
"""
if not l:
return list(l)
r = []
for e in l:
if not isinstance(e, list):
r.append(e)
else:
r.extend(flatten(e))
return r
def load_wsp(filename, nrows, ncols):
# Open the file
f = open("%s" % filename)
lines = f.readlines()
f.close()
# The interesting line is the third one
line = lines[2]
split_line = line.split(",")
nums = []
for x in split_line:
nums.append(float(x))
# print(len(split_line))
# print(len(nums))
if len(nums) != nrows*ncols:
raise Exception("wrong number of elements in wsp matrix: %d instead of %d(with %d rows)" % (len(nums), nrows*ncols, nrows))
# print("load matrix")
# The matrix is encoded as an array of nrowsxncols
matrix = []
for i in range(nrows):
row = []
for j in range(ncols):
try:
row.append(nums[i * ncols + j])
except:
print((i * ncols + j))
raise
matrix.append(row)
return matrix
class ParamsGenerator(object):
def __init__(self, params_values, matrix):
self.index = 0
self.params_values = params_values
for k in ('delay_ms_a', 'delay_ms_b'):
if isinstance(params_values.get(k, None), list):
for i in range(len(params_values[k])):
params_values["%s_%d" % (k, i)] = params_values[k][i]
params_values.pop(k, None)
self.param_names = list(sorted(params_values.keys()))
self.ranges_full_name = {self._full_name(key, val.get("count", 1)): val["range"] for key, val in list(params_values.items())}
names = []
for n in list(params_values.keys()):
for key in list(params_values[n]["range"].keys()) if isinstance(params_values[n]["range"], dict) else [None]:
names.append((n, key))
self.param_full_names = sorted(flatten([[self._full_name(name_key[0], i, name_key[1]) for i in range(params_values[name_key[0]].get("count", 1))] for name_key in names]))
# decide for an arbitrary ordering of the parameters
self.params_indexes = {self.param_full_names[i]: i for i in range(len(self.param_full_names))}
self.matrix = matrix
def _full_name(self, name, count, key=None):
if self.params_values[name].get("count", 1) > 1:
return "%s_%d%s" % (name, count, ("_%s" % str(key)) if key is not None else "")
return "%s%s" % (name, ("_%s" % str(key)) if key is not None else "")
def generate_value(self):
retval = self._generate_value_at(self.index)
self.index += 1
return retval
def _generate_value_at(self, i):
retval = {}
for name in self.param_names:
retval[name] = []
for count in range(self.params_values[name].get("count", 1)):
param_range = self.params_values[name]["range"]
if isinstance(param_range, dict):
to_append = {key: self.params_values[name]["type"](
self.matrix[self.params_indexes[self._full_name(name, count, key)]][i] * (param_range[key][1] - param_range[key][0]) + param_range[key][0])
for key in list(param_range.keys())}
else:
full_name = self._full_name(name, count)
param_index = self.params_indexes[full_name]
float_value = self.matrix[param_index][i]
to_append = self.params_values[name]["type"](float_value * (param_range[1] - param_range[0]) + param_range[0])
retval[name].append(to_append)
return retval
def __len__(self):
return len(self.matrix[0])
def generate_all_values(self):
for i in range(len(self.matrix[0])):
yield self._generate_value_at(i)