-
Notifications
You must be signed in to change notification settings - Fork 2
/
misc.py
136 lines (100 loc) · 3.25 KB
/
misc.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""
misc. functions
"""
from scipy import mean, var
import json
import scipy as sc
def dict_to_string(some_dict):
"""
Takes the {"A":some_value, "B":some_other_value}
to
"Asome_valueBsome_other_value".
This can then be used as a key for a CPT table.
"""
result = ""
sorted_keys = sorted(some_dict, key=lambda key: key)
new_dict = {key: some_dict[key] for key in sorted_keys}
for key in new_dict:
result += str(key) + str(new_dict[key])
return result
def string_to_dict(s):
"""
Partial-inverse of "dict_to_string", will only work
if the state is described by a single digit.
"""
sp = [a for a in s]
n = len(sp)
if n % 2 != 0:
raise ValueError("string has an odd number of characters.")
new_dict = {sp[i]: float(sp[i + 1]) for i in range(0, n - 1, 2)}
return new_dict
def char_fun(A, b):
"""
Returns True if dictionary b is a subset
of dictionary A and False otherwise.
"""
result = b.items() <= A.items()
return result
class weight_average(object):
"""
Class to calculate weighted averages.
Defaults to normal averages if no
weights are provided.
"""
def __init__(self, values, weights=None):
"""
values: iterable of 1xN dimension, the values on
which to evaluate the quantity of interest.
weights: iterable of 1xN dimension or None, the corresponding
weight for each value.
"""
self.values = values
if weights is not None:
self.weights = sc.exp(weights)
self.weights = self.weights / sum(self.weights)
def eval(self, f=lambda x: 1):
""""
evaluate function on the values
and take weighted average.
"""
if self.weights is None:
vec = [f(v) for v in self.values]
result = mean(vec)
variance = var(vec)
else:
v = self.values
vec = [f(v[i]) * w for i, w in enumerate(self.weights)]
result = sum(vec)
variance = var(vec)
return result, variance
def parse_node_file(filename):
"""
Parses a node file and creates the following variables:
graph = {child:{None}, child:{Parent1, Parent2}, ...}
prior = {node: [prior values]}
lambdas = {parent:{child1:lambda1, child2:lambda2, leak_node:lambda0}}
Those can then be used with the samplers, e.g., adaptive, annealed, etc.
"""
with open(filename) as inputfile:
data = json.load(inputfile)
graph = {}
prior = {}
lambdas = {}
for key in data:
# root node
d = data[key]
if len(d["parents"]) == 0:
graph[key] = {None}
prior[key] = d["cpt"]
else:
graph[key] = {p for p in d["parents"]}
t = graph[key]
c = d["cpt"]
lambdas[key] = {node: c[i] for i, node in enumerate(t)}
lambdas[key]["leak_node"] = c[len(t)]
return graph, prior, lambdas
if __name__ == '__main__':
some_dict = {"B": 0, "A": 1}
print(dict_to_string(some_dict))
filename = "data/approximate_network_all_mixed_any_age.json"
graph, prior, lambdas = parse_node_file(filename)