-
Notifications
You must be signed in to change notification settings - Fork 0
/
infer_parameters.py
331 lines (293 loc) · 8.87 KB
/
infer_parameters.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
import numpy as np
import measures_on_simple_data as msd
import networkx as nx
import aux_graphical as aux
from random import choice
from network_utils import degreehisto_to_degreeseq
# list of example feeders
examples_list = [13, 34, 37, 123, 124, 125, 126, 127, 128]
examples_nbnodes_list = [13, 34, 37, 123, 36, 36, 19, 16, 16]
def infer_degree_sequence(n):
S = degree_distrib_to_max_size(get_example_degree_distribs()) # matrix of size dmax*nb_examples
nb = np.sum(S, 0) # number of nodes for each example degree sequence
# If there is an example with same nb of nodes, return its degree histogram
nblist = np.asarray(np.transpose(nb))
i = 0
for e in nblist:
if e == n:
histo = np.asarray(np.transpose(S[:, i]))[0]
return histo
i += 1
# Elif n greater than max or lower than min of all known examples, return empty
if n > max(nblist) or n < min(nblist):
print("Cannot infer degree sequence : " + str(n)
+ " not in range of known examples. Number of nodes must be between "
+ min(nblist)+ " and " + max(nblist))
return []
# Else, find two degree sequences examples with nearest number of nodes
n_upper = n * 10000
n_lower = 0
h_upper = []
h_lower = []
i = 0
for e in nblist:
if (e > n) and (e < n_upper):
n_upper = e
histo = np.asarray(np.transpose(S[:, i]))[0]
h_upper = histo
elif (e < n) and (e > n_lower):
n_lower = e
histo = np.asarray(np.transpose(S[:, i]))[0]
h_lower = histo
i += 1
n_lower = n_lower.item(0)
n_upper = n_upper.item(0)
seq_lower = degreehisto_to_degreeseq(h_lower)
seq_upper = degreehisto_to_degreeseq(h_upper)
# prepare my_seq
my_seq = seq_lower
my_seq.extend([0] * (n - n_lower))
my_seq.sort()
### weird!!!!
# print("weird")
# print(my_seq)
# print(nx.is_graphical(my_seq))
# print(aux.is_valid_degree_sequence_erdos_gallai(my_seq))
# s1 = [0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]
# print(s1)
# print(nx.is_graphical(s1))
# calculate weighted average number of edges
w_lower = 1/float(n - n_lower)
w_upper = 1/float(n_upper - n)
s = w_lower + w_upper
w_lower /= s
w_upper /= s
double_edges = round(sum(seq_lower)*w_lower + sum(seq_upper)*w_upper)
# must be even
double_edges += double_edges%2
# loop until reaching desired number of edges
# add degrees, keeping the sequence graphical
while sum(my_seq) < double_edges:
# add a degree to a low degree node
i = 0
while my_seq[i] >= seq_upper[i]:
i += 1
my_seq[i] += 1
# add a degree to a high degree node
j = -1
while my_seq[j] >= seq_upper[j]:
j -= 1
my_seq[j] += 1
my_seq.sort()
# my_seq should be graphical at every loop
"""
print(my_seq)
print(nx.is_graphical(my_seq))
print(nx.is_valid_degree_sequence(my_seq))
print(aux.is_valid_degree_sequence_erdos_gallai(my_seq))"""
return my_seq
def infer_degree_sequence_random(n):
S = degree_distrib_to_max_size(get_example_degree_distribs()) # matrix of size dmax*nb_examples
nb = np.sum(S, 0) # number of nodes for each example degree sequence
# If there is an example with same nb of nodes, return its degree histogram
nblist = np.asarray(np.transpose(nb))
i = 0
for e in nblist:
if e == n:
histo = np.asarray(np.transpose(S[:, i]))[0]
print(histo)
return histo
i += 1
# Elif n greater than max or lower than min of all known examples, return empty
if n > max(nblist) or n < min(nblist):
print("Cannot infer degree sequence : " + str(n)
+ " not in range of known examples. Number of nodes must be between "
+ min(nblist)+ " and " + max(nblist))
return []
# Else, find two degree sequences examples with nearest number of nodes
n_upper = n * 10000
n_lower = 0
h_upper = []
h_lower = []
i = 0
for e in nblist:
if (e > n) and (e < n_upper):
n_upper = e
histo = np.asarray(np.transpose(S[:, i]))[0]
h_upper = histo
elif (e < n) and (e > n_lower):
n_lower = e
histo = np.asarray(np.transpose(S[:, i]))[0]
h_lower = histo
i += 1
n_lower = n_lower.item(0)
n_upper = n_upper.item(0)
seq_lower = degreehisto_to_degreeseq(h_lower)
seq_upper = degreehisto_to_degreeseq(h_upper)
# prepare my_seq
my_seq = seq_lower
my_seq.extend([0] * (n - n_lower))
my_seq.sort()
### weird!!!!
# print("weird")
# print(my_seq)
# print(nx.is_graphical(my_seq))
# print(aux.is_valid_degree_sequence_erdos_gallai(my_seq))
# s1 = [0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]
# print(s1)
# print(nx.is_graphical(s1))
# calculate weighted average number of edges
w_lower = 1/float(n - n_lower)
w_upper = 1/float(n_upper - n)
s = w_lower + w_upper
w_lower /= s
w_upper /= s
double_edges = round(sum(seq_lower)*w_lower + sum(seq_upper)*w_upper)
# must be even
double_edges += double_edges%2
# loop until reaching desired number of edges
# add degrees, keeping the sequence graphical
while sum(my_seq) < double_edges:
# add a degree to a random node
if 0 in my_seq:
my_seq[0] = 1
i1 = 0
else:
k = choice(seq_upper)
while (k-1) not in my_seq:
k = choice(seq_upper)
i1 = my_seq.index(k-1)
my_seq[i1] = k
# add a degree to a distinct node, to keep the sequence graphical
k = choice(seq_upper)
i2 = -1
while (k-1) not in my_seq or i2 == i1:
k = choice(seq_upper)
if (k-1) in my_seq:
i2 = my_seq.index(k-1)
my_seq[i2] = k
my_seq.sort()
# my_seq should be graphical at every loop
"""
print(my_seq)
print(nx.is_graphical(my_seq))
print(nx.is_valid_degree_sequence(my_seq))
print(aux.is_valid_degree_sequence_erdos_gallai(my_seq))"""
return my_seq
def get_example_degree_distribs():
l = []
for k in examples_list:
G = msd.readFeederData(k)
l += [nx.degree_histogram(G)]
return l
def get_example_assortativity_matrices():
l = []
for k in examples_list:
G = msd.readFeederData(k)
l += [nx.degree_mixing_matrix(G)]
return l
def get_example_assortativity_coeffs():
l = []
for k in examples_list:
G = msd.readFeederData(k)
l += [nx.degree_assortativity_coefficient(G)]
return l
# fill with zeros to have same size in all vectors
def degree_distrib_to_max_size(l):
dmax = 0
for e in l:
dmax = max(dmax, len(e))
for e in l:
e += [0] * (dmax - len(e))
S = np.transpose(np.matrix(l))
return S
# fill with zeros to have same size in all matrices
def assort_matrices_to_max_size(l):
dmax = 0
ll = []
for e in l:
dmax = max(dmax, len(e))
for e in l:
if dmax - len(e) > 0:
for k in range(dmax - len(e)):
e = np.insert(e, len(e[0]), 0, axis=1)
for k in range(dmax - len(e)):
e = np.insert(e, len(e), 0, axis=0)
ll += [e]
return ll
def infer_assortativity_matrix(n):
S = assort_matrices_to_max_size(get_example_assortativity_matrices()) # list of matrices of size dmax*dmax
# If there is an example with same nb of nodes, return its assortativity matrix
i = 0
for e in examples_nbnodes_list:
if e == n:
mat = S[i]
return mat
i += 1
# Elif n greater than max or lower than min of all known examples, return empty
if n > max(examples_nbnodes_list) or n < min(examples_nbnodes_list):
print("Cannot infer assortativity matrix : " + str(n)
+ " not in range of known examples. Number of nodes must be between "
+ min(examples_nbnodes_list)+ " and " + max(examples_nbnodes_list))
return []
# Else, find two examples with nearest number of nodes
n_upper = n * 10000
n_lower = 0
mat_upper = []
mat_lower = []
i = 0
for e in examples_nbnodes_list:
if (e > n) and (e < n_upper):
n_upper = e
mat_upper = S[i]
elif (e < n) and (e > n_lower):
n_lower = e
mat_lower = S[i]
i += 1
# calculate weighted average of upper and lower matrices
w_lower = 1/float(n - n_lower)
w_upper = 1/float(n_upper - n)
s = w_lower + w_upper
w_lower /= s
w_upper /= s
ml = np.multiply(mat_lower,w_lower)
mu = np.multiply(mat_upper,w_upper)
my_mat = ml + mu
return my_mat
def infer_assortativity_coeff(n):
C = get_example_assortativity_coeffs() # list of coeffs
# If there is an example with same nb of nodes, return its assortativity matrix
i = 0
for e in examples_nbnodes_list:
if e == n:
coeff = C[i]
return coeff
i += 1
# Elif n greater than max or lower than min of all known examples, return empty
if n > max(examples_nbnodes_list) or n < min(examples_nbnodes_list):
print("Cannot infer assortativity coeff : " + str(n)
+ " not in range of known examples. Number of nodes must be between "
+ min(examples_nbnodes_list)+ " and " + max(examples_nbnodes_list))
return []
# Else, find two examples with nearest number of nodes
n_upper = n * 10000
n_lower = 0
C_upper = 10000
C_lower = -10000
i = 0
for e in examples_nbnodes_list:
if (e > n) and (e < n_upper):
n_upper = e
C_upper = C[i]
elif (e < n) and (e > n_lower):
n_lower = e
C_lower = C[i]
i += 1
# calculate weighted average of upper and lower matrices
w_lower = 1/float(n - n_lower)
w_upper = 1/float(n_upper - n)
s = w_lower + w_upper
w_lower /= s
w_upper /= s
my_coeff = w_lower*C_lower + w_upper*C_upper
return my_coeff