Commit 16bdbf15 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

minimize_nested_blockmodel_dl(): Fix issues with clabel for graphs with filtered vertices

parent fe27ada4
...@@ -181,7 +181,7 @@ class BlockState(object): ...@@ -181,7 +181,7 @@ class BlockState(object):
self.clabel = self.g.own_property(clabel.copy("int")) self.clabel = self.g.own_property(clabel.copy("int"))
else: else:
self.clabel = self.g.new_vertex_property("int") self.clabel = self.g.new_vertex_property("int")
self.clabel.a = clabel self.clabel.fa = clabel
else: else:
self.clabel = self.g.new_vertex_property("int") self.clabel = self.g.new_vertex_property("int")
...@@ -1340,7 +1340,7 @@ def greedy_shrink(state, B, **kwargs): ...@@ -1340,7 +1340,7 @@ def greedy_shrink(state, B, **kwargs):
curr_B = (state.wr.a > 0).sum() curr_B = (state.wr.a > 0).sum()
if _bm_test(): if _bm_test():
assert curr_B == len(set(state.b.a)), (curr_B, len(set(state.b.a))) assert curr_B == len(set(state.b.fa)), (curr_B, len(set(state.b.fa)))
if verbose: if verbose:
print("merging, B=%d" % curr_B, "left:", curr_B - B, print("merging, B=%d" % curr_B, "left:", curr_B - B,
...@@ -1727,7 +1727,7 @@ def multilevel_minimize(state, B, nsweeps=10, adaptive_sweeps=True, epsilon=0, ...@@ -1727,7 +1727,7 @@ def multilevel_minimize(state, B, nsweeps=10, adaptive_sweeps=True, epsilon=0,
# check cache for previous results # check cache for previous results
if b_cache is not None and Bi in b_cache: if b_cache is not None and Bi in b_cache:
if _bm_test(): if _bm_test():
assert (state.clabel.a == b_cache[Bi][1].clabel.a).all(), "wrong clabel in cache" assert (state.clabel.fa == b_cache[Bi][1].clabel.fa).all(), "wrong clabel in cache"
assert state._BlockState__check_clabel(), "clabel already invalidated before cache" assert state._BlockState__check_clabel(), "clabel already invalidated before cache"
assert b_cache[Bi][1]._BlockState__check_clabel(), "clabel already invalidated after cache" assert b_cache[Bi][1]._BlockState__check_clabel(), "clabel already invalidated after cache"
state = b_cache[Bi][1].copy() state = b_cache[Bi][1].copy()
...@@ -1759,7 +1759,7 @@ def multilevel_minimize(state, B, nsweeps=10, adaptive_sweeps=True, epsilon=0, ...@@ -1759,7 +1759,7 @@ def multilevel_minimize(state, B, nsweeps=10, adaptive_sweeps=True, epsilon=0,
nstate = state.copy(b=state.get_nonoverlap_blocks(), overlap=False) nstate = state.copy(b=state.get_nonoverlap_blocks(), overlap=False)
assert nstate.B <= nstate.N assert nstate.B <= nstate.N
nstate = multilevel_minimize(nstate, B=Bi, verbose=verbose, **kwargs) nstate = multilevel_minimize(nstate, B=Bi, verbose=verbose, **kwargs)
nstate = nstate.copy(overlap=True, clabel=state.clabel.a) nstate = nstate.copy(overlap=True, clabel=state.clabel.fa)
unilevel_minimize(nstate, **kwargs) unilevel_minimize(nstate, **kwargs)
if nstate.B > Bi: if nstate.B > Bi:
...@@ -2236,7 +2236,7 @@ def minimize_blockmodel_dl(g, deg_corr=True, overlap=False, ec=None, ...@@ -2236,7 +2236,7 @@ def minimize_blockmodel_dl(g, deg_corr=True, overlap=False, ec=None,
minimize_state.init = False minimize_state.init = False
if min_B is None: if min_B is None:
min_B = state.clabel.a.max() + 1 min_B = state.clabel.fa.max() + 1
if verbose: if verbose:
print("Overlapping minimization starting from B=", max_B) print("Overlapping minimization starting from B=", max_B)
......
...@@ -247,7 +247,7 @@ class CovariateBlockState(BlockState): ...@@ -247,7 +247,7 @@ class CovariateBlockState(BlockState):
max_BE=self.max_BE) max_BE=self.max_BE)
else: else:
base_u, node_index = self.__get_base_u(u) base_u, node_index = self.__get_base_u(u)
state = OverlapBlockState(u, b=u.vp["b"].a, state = OverlapBlockState(u, b=u.vp["b"].fa,
B=B, B=B,
vweight=u.vp["weight"], vweight=u.vp["weight"],
node_index=node_index, node_index=node_index,
...@@ -499,7 +499,7 @@ class CovariateBlockState(BlockState): ...@@ -499,7 +499,7 @@ class CovariateBlockState(BlockState):
vweight=self.vweight if vweight is None else vweight, vweight=self.vweight if vweight is None else vweight,
b=self.b if b is None else b, b=self.b if b is None else b,
B=(self.B if b is None else None) if B is None else B, B=(self.B if b is None else None) if B is None else B,
clabel=(self.clabel.a if self.overlap else self.clabel) if clabel is None else clabel, clabel=(self.clabel.fa if self.overlap else self.clabel) if clabel is None else clabel,
deg_corr=self.deg_corr if deg_corr is None else deg_corr, deg_corr=self.deg_corr if deg_corr is None else deg_corr,
overlap=self.overlap if overlap is None else overlap, overlap=self.overlap if overlap is None else overlap,
layers=self.layers if layers is None else layers, layers=self.layers if layers is None else layers,
...@@ -727,7 +727,7 @@ def init_layer_confined(g, ec): ...@@ -727,7 +727,7 @@ def init_layer_confined(g, ec):
tmp_state = tmp_state.copy(overlap=True) tmp_state = tmp_state.copy(overlap=True)
be = tmp_state.get_edge_blocks() be = tmp_state.get_edge_blocks()
ba = ungroup_vector_property(be, [0])[0] ba = ungroup_vector_property(be, [0])[0]
ba.a = ba.a + ec.a * (ba.a.max() + 1) ba.fa = ba.fa + ec.fa * (ba.fa.max() + 1)
continuous_map(ba) continuous_map(ba)
be = group_vector_property([ba, ba]) be = group_vector_property([ba, ba])
return be return be
\ No newline at end of file
...@@ -111,7 +111,7 @@ class NestedBlockState(object): ...@@ -111,7 +111,7 @@ class NestedBlockState(object):
clabel=self.clabel, clabel=self.clabel,
max_BE=max_BE) max_BE=max_BE)
self.clabel = state.clabel.copy() self.clabel = state.clabel.copy()
state.clabel.a = 0 state.clabel.fa = 0
else: else:
state = BlockState(g, B=Bl, b=bl, state = BlockState(g, B=Bl, b=bl,
eweight=ecount, eweight=ecount,
...@@ -132,7 +132,7 @@ class NestedBlockState(object): ...@@ -132,7 +132,7 @@ class NestedBlockState(object):
max_BE=max_BE) max_BE=max_BE)
if overlap: if overlap:
self.clabel = state.clabel.copy() self.clabel = state.clabel.copy()
state.clabel.a = 0 state.clabel.fa = 0
else: else:
...@@ -170,7 +170,7 @@ class NestedBlockState(object): ...@@ -170,7 +170,7 @@ class NestedBlockState(object):
ec = g.own_property(self.ec.copy()) if self.ec is not None else None ec = g.own_property(self.ec.copy()) if self.ec is not None else None
bstack = self.get_bstack() bstack = self.get_bstack()
return self.copy(g=g, eweight=eweight, vweight=vweight, clabel=clabel, return self.copy(g=g, eweight=eweight, vweight=vweight, clabel=clabel,
ec=ec, bs=[s.vp.b.a for s in bstack]) ec=ec, bs=[s.vp.b.fa for s in bstack])
def copy(self, g=None, eweight=None, vweight=None, bs=None, ec=None, def copy(self, g=None, eweight=None, vweight=None, bs=None, ec=None,
layers=None, deg_corr=None, overlap=None, clabel=None, **kwargs): layers=None, deg_corr=None, overlap=None, clabel=None, **kwargs):
...@@ -178,18 +178,20 @@ class NestedBlockState(object): ...@@ -178,18 +178,20 @@ class NestedBlockState(object):
have the same meaning as in the constructor..""" have the same meaning as in the constructor.."""
if bs is None: if bs is None:
bs = [s.b.a for s in self.levels] bs = [s.b.fa for s in self.levels]
if overlap is None: if overlap is None:
overlap = self.overlap overlap = self.overlap
elif self.overlap and not overlap: elif self.overlap and not overlap:
raise ValueError("Cannot automatically convert overlapping nested state to nonoverlapping") raise ValueError("Cannot automatically convert overlapping nested state to nonoverlapping")
elif not self.overlap and overlap: elif not self.overlap and overlap:
s = self.levels[0].copy(overlap=True) s = self.levels[0].copy(overlap=True)
bs[0] = s.b.a bs[0] = s.b.fa
if deg_corr is None: if deg_corr is None:
deg_corr = self.deg_corr deg_corr = self.deg_corr
if layers is None: if layers is None:
layers = self.layers layers = self.layers
if clabel is None:
clabel = self.clabel
return NestedBlockState(self.g if g is None else g, return NestedBlockState(self.g if g is None else g,
self.eweight if eweight is None else eweight, self.eweight if eweight is None else eweight,
self.vweight if vweight is None else vweight, self.vweight if vweight is None else vweight,
...@@ -206,7 +208,7 @@ class NestedBlockState(object): ...@@ -206,7 +208,7 @@ class NestedBlockState(object):
eweight=self.eweight, eweight=self.eweight,
vweight=self.vweight, vweight=self.vweight,
overlap=self.overlap, overlap=self.overlap,
bs=[array(s.b.a) for s in self.levels], bs=[array(s.b.fa) for s in self.levels],
clabel=self.clabel, clabel=self.clabel,
deg_corr=self.deg_corr, deg_corr=self.deg_corr,
max_BE=self.levels[0].max_BE, max_BE=self.levels[0].max_BE,
...@@ -253,12 +255,12 @@ class NestedBlockState(object): ...@@ -253,12 +255,12 @@ class NestedBlockState(object):
if self.levels[j].wr.a.min() == 0: if self.levels[j].wr.a.min() == 0:
print("WARNING: empty blocks at level", j) print("WARNING: empty blocks at level", j)
if self.levels[j].b.a.max() + 1 != self.levels[j].B: if self.levels[j].b.fa.max() + 1 != self.levels[j].B:
print("WARNING: b.max() + 1 != B at level", j, self.levels[j].b.max() + 1, self.levels[j].B) print("WARNING: b.max() + 1 != B at level", j, self.levels[j].b.fa.max() + 1, self.levels[j].B)
for j in range(len(self.levels) - 1): for j in range(len(self.levels) - 1):
B = self.levels[j].b.a.max() + 1 B = self.levels[j].b.fa.max() + 1
bg_state = self.levels[j].get_block_state(b=self.levels[j+1].b.copy(), bg_state = self.levels[j].get_block_state(b=self.levels[j+1].b.copy(),
overlap=self.overlap == "full", overlap=self.overlap == "full",
deg_corr=self.deg_corr == "full")[0] deg_corr=self.deg_corr == "full")[0]
...@@ -275,20 +277,20 @@ class NestedBlockState(object): ...@@ -275,20 +277,20 @@ class NestedBlockState(object):
print("N, B:", bg_state.N, bg_state.B) print("N, B:", bg_state.N, bg_state.B)
print("N, B:", self.levels[j + 1].N, self.levels[j + 1].B) print("N, B:", self.levels[j + 1].N, self.levels[j + 1].B)
print("similarity:", similarity(bg_state.g, self.levels[j+1].g)) print("similarity:", similarity(bg_state.g, self.levels[j+1].g))
print("b:", bg_state.b.a) print("b:", bg_state.b.fa)
print("b:", self.levels[j+1].b.a) print("b:", self.levels[j+1].b.fa)
print("wr:", bg_state.wr.a) print("wr:", bg_state.wr.fa)
print("wr:", self.levels[j+1].wr.a) print("wr:", self.levels[j+1].wr.fa)
print("mrs:", bg_state.mrs.a) print("mrs:", bg_state.mrs.fa)
print("mrs:", self.levels[j+1].mrs.a) print("mrs:", self.levels[j+1].mrs.fa)
print("eweight:", bg_state.eweight.a) print("eweight:", bg_state.eweight.fa)
print("eweight:", self.levels[j+1].eweight.a) print("eweight:", self.levels[j+1].eweight.fa)
print("vweight:", bg_state.vweight.a) print("vweight:", bg_state.vweight.fa)
print("vweight:", self.levels[j+1].vweight.a) print("vweight:", self.levels[j+1].vweight.fa)
assert abs(S1 - S2) < 1e-6 and not isnan(S2) and not isnan(S1), "inconsistency at level %d after %s of level %d, different entropies (%g, %g)" % (j, op, l, S1, S2) assert abs(S1 - S2) < 1e-6 and not isnan(S2) and not isnan(S1), "inconsistency at level %d after %s of level %d, different entropies (%g, %g)" % (j, op, l, S1, S2)
...@@ -297,15 +299,15 @@ class NestedBlockState(object): ...@@ -297,15 +299,15 @@ class NestedBlockState(object):
# verify hierarchy / clabel consistency # verify hierarchy / clabel consistency
clabel = self.__project_partition(0, j) clabel = self.__project_partition(0, j)
self.levels[0].clabel.a = self.clabel.a self.levels[0].clabel.fa = self.clabel.fa
assert self.levels[0]._BlockState__check_clabel(), "inconsistency at level %d after %s of level %d, clabel invalidated" % (j + 1, op, l) assert self.levels[0]._BlockState__check_clabel(), "inconsistency at level %d after %s of level %d, clabel invalidated" % (j + 1, op, l)
self.levels[0].clabel.a = 0 self.levels[0].clabel.fa = 0
# verify hierarchy consistency # verify hierarchy consistency
clabel = self.__project_partition(j, j + 1) clabel = self.__project_partition(j, j + 1)
self.levels[0].clabel.a = self.clabel.a self.levels[0].clabel.fa = self.clabel.fa
assert self.levels[0]._BlockState__check_clabel(), "inconsistency at level %d after %s of level %d, partition not compatible with upper level" % (j + 1, op, l) assert self.levels[0]._BlockState__check_clabel(), "inconsistency at level %d after %s of level %d, partition not compatible with upper level" % (j + 1, op, l)
self.levels[0].clabel.a = 0 self.levels[0].clabel.fa = 0
def __rebuild_level(self, l, b, clabel=None): def __rebuild_level(self, l, b, clabel=None):
...@@ -320,7 +322,7 @@ class NestedBlockState(object): ...@@ -320,7 +322,7 @@ class NestedBlockState(object):
old_b = b.copy() old_b = b.copy()
state = self.levels[l].copy(b=b, clabel=clabel.a) state = self.levels[l].copy(b=b, clabel=clabel.fa)
self.levels[l] = state self.levels[l] = state
if l == 0: if l == 0:
self.clabel = state.g.own_property(self.clabel) # for CovariateBlockState self.clabel = state.g.own_property(self.clabel) # for CovariateBlockState
...@@ -334,8 +336,8 @@ class NestedBlockState(object): ...@@ -334,8 +336,8 @@ class NestedBlockState(object):
self.levels.append(None) self.levels.append(None)
self.levels[l + 1] = bstate self.levels[l + 1] = bstate
self.levels[l].clabel.a = 0 self.levels[l].clabel.fa = 0
self.levels[l + 1].clabel.a = 0 self.levels[l + 1].clabel.fa = 0
# if l + 1 < len(self.levels) - 1: # if l + 1 < len(self.levels) - 1:
# self.levels[l + 1].clabel = self.__project_partition(l + 1, l + 2) # self.levels[l + 1].clabel = self.__project_partition(l + 1, l + 2)
...@@ -354,22 +356,22 @@ class NestedBlockState(object): ...@@ -354,22 +356,22 @@ class NestedBlockState(object):
if abs(bstate.entropy() - self.levels[l + 2].entropy()) > 1e-6: if abs(bstate.entropy() - self.levels[l + 2].entropy()) > 1e-6:
print("********************** inconsistent rebuild! **************************") print("********************** inconsistent rebuild! **************************")
print(bstate.b.a) print(bstate.b.fa)
print(self.levels[l + 2].b.a) print(self.levels[l + 2].b.fa)
print(bstate.wr.a) print(bstate.wr.a)
print(self.levels[l + 2].wr.a) print(self.levels[l + 2].wr.a)
print(bstate.eweight.a) print(bstate.eweight.fa)
print(self.levels[l + 2].eweight.a) print(self.levels[l + 2].eweight.fa)
nclabel = self.__project_partition(l, l + 1) nclabel = self.__project_partition(l, l + 1)
print(nclabel.a) print(nclabel.fa)
print(clabel.a) print(clabel.fa)
print(self.levels[l].b.a) print(self.levels[l].b.fa)
print(self.levels[l+1].b.a) print(self.levels[l+1].b.fa)
print(self.levels[l+2].b.a) print(self.levels[l+2].b.fa)
print(bstate.b.a) print(bstate.b.fa)
print ("DS", l, l + 1, bstate.entropy(), self.levels[l + 2].entropy()) print ("DS", l, l + 1, bstate.entropy(), self.levels[l + 2].entropy())
B = self.levels[l].B B = self.levels[l].B
...@@ -516,7 +518,7 @@ class NestedBlockState(object): ...@@ -516,7 +518,7 @@ class NestedBlockState(object):
l -= 1 l -= 1
else: else:
b = self.levels[l].b.copy() b = self.levels[l].b.copy()
state = self.levels[0].copy(b=b.a) state = self.levels[0].copy(b=b.fa)
return state return state
def merge_layers(self, l_src, l_tgt, revert=False): def merge_layers(self, l_src, l_tgt, revert=False):
...@@ -624,7 +626,7 @@ def nested_mcmc_sweep(state, beta=1., c=1., dl=False, sequential=True, ...@@ -624,7 +626,7 @@ def nested_mcmc_sweep(state, beta=1., c=1., dl=False, sequential=True,
# propagate externally imposed clabel at the bottom # propagate externally imposed clabel at the bottom
cclabel = state._NestedBlockState__propagate_clabel(l) cclabel = state._NestedBlockState__propagate_clabel(l)
cclabel.a += clabel.a * (cclabel.a.max() + 1) cclabel.fa += clabel.fa * (cclabel.fa.max() + 1)
continuous_map(cclabel) continuous_map(cclabel)
bstate.clabel = cclabel bstate.clabel = cclabel
...@@ -635,7 +637,7 @@ def nested_mcmc_sweep(state, beta=1., c=1., dl=False, sequential=True, ...@@ -635,7 +637,7 @@ def nested_mcmc_sweep(state, beta=1., c=1., dl=False, sequential=True,
sequential=sequential, parallel=parallel, sequential=sequential, parallel=parallel,
verbose=verbose) verbose=verbose)
bstate.clabel.a = 0 bstate.clabel.fa = 0
rets.append(ret) rets.append(ret)
return rets return rets
...@@ -673,7 +675,7 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10, ...@@ -673,7 +675,7 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10,
if l > 0 or max_B is None: if l > 0 or max_B is None:
max_B = bstate.N max_B = bstate.N
min_B = max(min_B, state.clabel.a.max() + 1) min_B = max(min_B, state.clabel.fa.max() + 1)
# constraint partitions not to invalidate upper layers # constraint partitions not to invalidate upper layers
if l < len(state.levels) - 1: if l < len(state.levels) - 1:
...@@ -682,25 +684,25 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10, ...@@ -682,25 +684,25 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10,
clabel = bstate.g.new_vertex_property("int") clabel = bstate.g.new_vertex_property("int")
assert min_B <= max_B, (min_B, max_B, bstate.B, bstate.N, g.num_vertices(), assert min_B <= max_B, (min_B, max_B, bstate.B, bstate.N, g.num_vertices(),
state.clabel.a.max() + 1, clabel.a.max() + 1, l) state.clabel.fa.max() + 1, clabel.fa.max() + 1, l)
# propagate externally imposed clabel at the bottom # propagate externally imposed clabel at the bottom
cclabel = state._NestedBlockState__propagate_clabel(l) cclabel = state._NestedBlockState__propagate_clabel(l)
assert cclabel.a.max() <= state.clabel.a.max(), (cclabel.a.max(), state.clabel.a.max()) assert cclabel.fa.max() <= state.clabel.fa.max(), (cclabel.fa.max(), state.clabel.fa.max())
cclabel.a += clabel.a * (cclabel.a.max() + 1) cclabel.fa += clabel.fa * (cclabel.fa.max() + 1)
continuous_map(cclabel) continuous_map(cclabel)
min_B = max(min_B, cclabel.a.max() + 1) min_B = max(min_B, cclabel.fa.max() + 1)
assert min_B <= max_B, (min_B, max_B, bstate.B, bstate.N, g.num_vertices(), assert min_B <= max_B, (min_B, max_B, bstate.B, bstate.N, g.num_vertices(),
cclabel.a.max() + 1, state.clabel.a.max() + 1, clabel.a.max() + 1, l) cclabel.fa.max() + 1, state.clabel.fa.max() + 1, clabel.fa.max() + 1, l)
if _bm_test(): if _bm_test():
assert bstate._BlockState__check_clabel(), "invalid clabel before minimize!" assert bstate._BlockState__check_clabel(), "invalid clabel before minimize!"
nested_dl = l < len(state.levels) - 1 nested_dl = l < len(state.levels) - 1
state.levels[l].clabel.a = cclabel.a state.levels[l].clabel.fa = cclabel.fa
Sb = get_b_dl(state.levels[l], Sb = get_b_dl(state.levels[l],
dense=(l > 0 and state.deg_corr != "full") or dense, dense=(l > 0 and state.deg_corr != "full") or dense,
...@@ -709,14 +711,14 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10, ...@@ -709,14 +711,14 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10,
nested_overlap=state.overlap == "full", nested_overlap=state.overlap == "full",
dl_ent=dl_ent) dl_ent=dl_ent)
state.levels[l].clabel.a = 0 state.levels[l].clabel.fa = 0
if _bm_test(): if _bm_test():
assert clabel.a.max() + 1 <= min_B assert clabel.fa.max() + 1 <= min_B
if l == 0 and max_b is not None: if l == 0 and max_b is not None:
istate = state.levels[0].copy(b=max_b.copy(), istate = state.levels[0].copy(b=max_b.copy(),
clabel=cclabel.a if state.overlap else cclabel) clabel=cclabel.fa if state.overlap else cclabel)
if _bm_test(): if _bm_test():
assert istate._BlockState__check_clabel(), "invalid clabel!" assert istate._BlockState__check_clabel(), "invalid clabel!"
if istate.B > max_B: if istate.B > max_B:
...@@ -749,7 +751,7 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10, ...@@ -749,7 +751,7 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10,
epsilon=epsilon, epsilon=epsilon,
max_B=max_B, max_B=max_B,
min_B=min_B, min_B=min_B,
clabel=cclabel if not bstate.overlap else cclabel.a, clabel=cclabel if not bstate.overlap else cclabel.fa,
max_BE=bstate.max_BE, max_BE=bstate.max_BE,
dl=dl, dl=dl,
dense=(l > 0 and state.deg_corr != "full") or dense, dense=(l > 0 and state.deg_corr != "full") or dense,
...@@ -769,7 +771,7 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10, ...@@ -769,7 +771,7 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10,
ignore_degrees=state.ignore_degrees if l == 0 else None) ignore_degrees=state.ignore_degrees if l == 0 else None)
if _bm_test(): if _bm_test():
assert (res.clabel.a == cclabel.a).all(), (res.clabel.a, cclabel.a) assert (res.clabel.fa == cclabel.fa).all(), (res.clabel.fa, cclabel.fa)
assert res._BlockState__check_clabel(), "invalid clabel after minimize!" assert res._BlockState__check_clabel(), "invalid clabel after minimize!"
Sf = get_b_dl(res, Sf = get_b_dl(res,
...@@ -779,10 +781,10 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10, ...@@ -779,10 +781,10 @@ def replace_level(l, state, min_B=None, max_B=None, max_b=None, nsweeps=10,
nested_overlap=state.overlap == "full", nested_overlap=state.overlap == "full",
dl_ent=dl_ent) dl_ent=dl_ent)
res.clabel.a = 0 res.clabel.fa = 0
if state.ec is not None: if state.ec is not None:
for s in res.states: for s in res.states:
s.clabel.a = 0 s.clabel.fa = 0
b = res.b b = res.b
kept = False kept = False
...@@ -1331,7 +1333,7 @@ def init_nested_state(g, Bs, ec=None, deg_corr=True, overlap=False, ...@@ -1331,7 +1333,7 @@ def init_nested_state(g, Bs, ec=None, deg_corr=True, overlap=False,
deg_corr=deg_corr == "full")[0] deg_corr=deg_corr == "full")[0]
if B == 1: if B == 1:
bstate.copy(b=bstate.g.new_vertex_property("int").a) bstate.copy(b=bstate.g.new_vertex_property("int").fa)
else: else:
bstate = multilevel_minimize(bstate, B, nsweeps=nsweeps, bstate = multilevel_minimize(bstate, B, nsweeps=nsweeps,
epsilon=epsilon, epsilon=epsilon,
...@@ -1636,12 +1638,12 @@ def minimize_nested_blockmodel_dl(g, Bs=None, bs=None, min_B=None, ...@@ -1636,12 +1638,12 @@ def minimize_nested_blockmodel_dl(g, Bs=None, bs=None, min_B=None,
nmerge_sweeps=nmerge_sweeps, dl=dl, nmerge_sweeps=nmerge_sweeps, dl=dl,
sequential=sequential, parallel=parallel, sequential=sequential, parallel=parallel,
confine_layers=confine_layers) confine_layers=confine_layers)
bs = [array(s.b.a) for s in state.levels] bs = [array(s.b.fa) for s in state.levels]
bs[0] = array(bstate.b.a) bs[0] = array(bstate.b.fa)
del bstate del bstate
else: else:
bstates = [bstate.copy(overlap=True) for bstate in state.levels] bstates = [bstate.copy(overlap=True) for bstate in state.levels]
bs = [array(s.b.a) for s in bstates] bs = [array(s.b.fa) for s in bstates]
del bstates del bstates