Commit 39f0cf57 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

inference: Fix issues with rec_type="delta_t"

parent bfd485ee
......@@ -161,7 +161,8 @@ public:
auto mv_entries = [&](auto&&... args)
{
move_entries(v, r, nr, get_b, gs._g, gs._eweight, m_entries,
efilt, is_loop_nop(), args...);
efilt, is_loop_nop(),
std::forward<decltype(args)>(args)...);
};
switch (_rec_type)
......@@ -169,6 +170,7 @@ public:
case weight_type::POSITIVE: // positive weights
case weight_type::DISCRETE_GEOMETRIC:
case weight_type::DISCRETE_POISSON:
case weight_type::DELTA_T:
mv_entries(gs._rec);
break;
case weight_type::SIGNED: // positive and negative weights
......@@ -220,16 +222,17 @@ public:
case weight_type::POSITIVE: // positive weights
case weight_type::DISCRETE_GEOMETRIC:
case weight_type::DISCRETE_POISSON:
case weight_type::DELTA_T:
this->_brec[me] += get<1>(delta);
}
});
if (_rec_type == weight_type::DELTA_T) // waiting times
{
if (_ignore_degrees[v] > 0)
auto& gs = *_gstate;
if (gs._ignore_degrees[v] > 0)
{
double dt = out_degreeS()(v, _g, _rec);
auto r = _b[v];
double dt = out_degreeS()(v, gs._g, gs._rec);
if (Add)
_brecsum[r] += dt;
else
......@@ -474,7 +477,7 @@ public:
if (allow_empty)
return ((_bclabel[r] == _bclabel[nr]) || (_wr[nr] == 0));
else
return ((_bclabel[r] == _bclabel[nr]));
return _bclabel[r] == _bclabel[nr];
}
// move a vertex from its current block to block nr
......@@ -1058,9 +1061,9 @@ public:
});
break;
case weight_type::DELTA_T: // waiting times
if ((r != nr) && _ignore_degrees[v] > 0)
auto& gs = *_gstate;
if ((r != nr) && gs._ignore_degrees[v] > 0)
{
auto& gs = *_gstate;
double dt = out_degreeS()(v, gs._g, gs._rec);
int k = out_degreeS()(v, gs._g, gs._eweight);
if (r != null_group)
......
......@@ -101,6 +101,7 @@ struct Merge
size_t move_proposal(size_t v, bool random, RNG& rng)
{
size_t r = _state._b[v];
assert(r == v);
size_t s;
if (!random)
{
......@@ -112,7 +113,7 @@ struct Merge
s = uniform_sample(_available, rng);
}
if (s == v || !_state.allow_move(r, s, false))
if (s == r || !_state.allow_move(r, s, false))
return _null_move;
return s;
......@@ -126,7 +127,8 @@ struct Merge
void perform_merge(size_t r, size_t s)
{
//assert(_state._vweight[r] > 0 && _state._vweight[s] > 0);
assert(_state._bclabel[r] == _state._bclabel[s]);
assert(_state._ignore_degrees[r] == _state._ignore_degrees[s]);
_state.move_vertex(r, s);
_state.merge_vertices(r, s);
}
......
......@@ -312,6 +312,10 @@ class BlockState(object):
if not self._check_clabel():
raise ValueError("provided clabel is inconsistent with node partition")
if not self._check_clabel(clabel=self.pclabel):
raise ValueError("provided pclabel is inconsistent with node partition")
if not self._check_clabel(b=self.pclabel, clabel=self.clabel):
raise ValueError("provided pclabel and clabel are inconsistent")
self.bclabel = self.get_bclabel()
......@@ -321,9 +325,9 @@ class BlockState(object):
self.ignore_degrees = kwargs.pop("ignore_degrees", None)
if self.ignore_degrees is None:
self.ignore_degrees = g.new_vp("bool", False)
self.ignore_degrees = self.g.new_vp("bool", False)
else:
self.ignore_degrees = self.ignore_degrees.copy("bool")
self.ignore_degrees = self.g.own_property(self.ignore_degrees).copy("bool")
self.merge_map = kwargs.pop("merge_map",
self.g.vertex_index.copy("int"))
......@@ -353,18 +357,17 @@ class BlockState(object):
else:
self.rec_type = rec_type
self.brec = self.bg.ep.rec
self.bdrec = self.bg.ep.drec
if self.rec_type == libinference.rec_type.delta_t: # waiting times
self.brecsum = self.bg.degree_property_map("out", self.bg.ep.rec)
tokens = self.ignore_degrees.fa == 0
token_groups = bincount(self.b.fa[tokens]) > 0
token_groups.resize(self.bg.num_vertices())
self.brecsum.a[token_groups] = 0
self.brecsum = self.bg.degree_property_map("out", self.brec)
mem = self.ignore_degrees.copy()
bmem = self.get_bclabel(clabel=mem)
self.brecsum.a[bmem.a == 0] = 0
else:
self.brecsum = self.bg.new_vp("double")
self.brec = self.bg.ep.rec
self.bdrec = self.bg.ep.drec
self.rec_params = dict(m0=self.rec.fa.mean(), k0=1,
v0=self.rec.fa.std() ** 2, nu0=3)
......@@ -495,8 +498,8 @@ class BlockState(object):
== True`` the nodes of the block state are weighted with the node
counts."""
deg_corr = kwargs.get("deg_corr", self.deg_corr)
copy_bg = extract_arg(kwargs, "copy_bg", True)
deg_corr = kwargs.pop("deg_corr", self.deg_corr)
copy_bg = kwargs.pop("copy_bg", True)
if deg_corr and vweight:
if isinstance(self.degs, libinference.simple_degs_t):
......@@ -566,23 +569,22 @@ class BlockState(object):
r"Returns the total number of nonempty blocks."
return int((self.wr.a > 0).sum())
def get_bclabel(self):
def get_bclabel(self, clabel=None):
r"""Returns a :class:`~graph_tool.PropertyMap` corresponding to constraint
labels for the block graph."""
bclabel = self.bg.new_vertex_property("int")
reverse_map(self.b, bclabel)
pmap(bclabel, self.clabel)
if clabel is None:
clabel = self.clabel
pmap(bclabel, clabel)
return bclabel
def get_bpclabel(self):
r"""Returns a :class:`~graph_tool.PropertyMap`` corresponding to partition
constraint labels for the block graph."""
bclabel = self.bg.new_vertex_property("int")
reverse_map(self.b, bclabel)
pmap(bclabel, self.pclabel)
return bclabel
return self.get_bclabel(self.pclabel)
def _check_clabel(self, clabel=None, b=None):
if b is None:
......
......@@ -36,8 +36,8 @@ import copy
def get_edges_dl(state, hstate_args, hentropy_args):
bclabel = state.get_bclabel()
bstate = state.get_block_state(b=bclabel, **hstate_args)
return bstate.entropy(**overlay(hentropy_args, dl=True, edges_dl=False,
multigraph=True))
return bstate.entropy(**dict(hentropy_args, dl=True, edges_dl=False,
multigraph=True))
class NestedBlockState(object):
......@@ -73,34 +73,37 @@ class NestedBlockState(object):
def __init__(self, g, bs, base_type=BlockState, state_args={},
hstate_args={}, hentropy_args={}, sampling=False, **kwargs):
self.g = g
self.state_args = overlay(kwargs, **state_args)
self.hstate_args = overlay(dict(deg_corr=False), **hstate_args)
self.state_args = dict(kwargs, **state_args)
self.hstate_args = dict(dict(deg_corr=False), **hstate_args)
self.sampling = sampling
if sampling:
self.hstate_args = overlay(self.hstate_args, vweight="nonempty",
copy_bg=False, B=g.num_vertices())
self.state_args = overlay(self.state_args, vweight="unity", eweight="unity",
B=g.num_vertices())
self.hstate_args = dict(self.hstate_args, vweight="nonempty",
copy_bg=False, B=g.num_vertices())
self.state_args = dict(self.state_args, vweight="unity", eweight="unity",
B=g.num_vertices())
nbs = []
for b in bs:
nb = numpy.zeros(g.num_vertices(), dtype="int")
nb[:len(b)] = b
nbs.append(nb)
bs = nbs
self.hentropy_args = overlay(dict(adjacency=True,
dense=True,
multigraph=True,
dl=True,
partition_dl=True,
degree_dl=True,
degree_dl_kind="distributed",
edges_dl=True,
exact=True),
**hentropy_args)
self.hentropy_args = dict(dict(adjacency=True,
dense=True,
multigraph=True,
dl=True,
partition_dl=True,
degree_dl=True,
degree_dl_kind="distributed",
edges_dl=True,
exact=True),
**hentropy_args)
self.levels = [base_type(g, b=bs[0], **self.state_args)]
for b in bs[1:]:
for i, b in enumerate(bs[1:]):
state = self.levels[-1]
bstate = state.get_block_state(b=b, **self.hstate_args)
args = self.hstate_args
if i == len(bs[1:]) - 1:
args = dict(args, clabel=None, pclabel=None)
bstate = state.get_block_state(b=b, **args)
self.levels.append(bstate)
if _bm_test():
......@@ -198,7 +201,10 @@ class NestedBlockState(object):
for l in range(1, len(self.levels)):
b = self.levels[l].b.fa.copy()
state = self.levels[l-1]
bstate = state.get_block_state(b=b, **self.hstate_args)
args = self.hstate_args
if l == len(self.levels) - 1:
args = dict(args, clabel=None, pclabel=None)
bstate = state.get_block_state(b=b, **args)
b2 = bstate.b.fa.copy()
continuous_map(b)
continuous_map(b2)
......@@ -451,13 +457,15 @@ class NestedBlockState(object):
if l < len(self.levels) - 1:
if B_min is None:
min_state = state.copy(b=clabel.fa, clabel=clabel.fa)
B_min = min_state.B
else:
B_min = max(B_min, clabel.fa.max() + 1)
min_state = mcmc_multilevel(max_state, B_min,
**mcmc_multilevel_args)
if _bm_test():
assert min_state.B == self.levels[l+1].B, (min_state.B,
self.levels[l+1].B)
assert (min_state.B == self.levels[l+1].B or
min_state.B == B_min), (B_min, min_state.B,
self.levels[l+1].B)
else:
min_state = state.copy(b=clabel.fa, clabel=clabel.fa)
if B_min is not None and min_state.B > B_min:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment