Commit 29b5caa7 authored by Tiago Peixoto's avatar Tiago Peixoto

Simplify BlockState.sample_graph()

parent 2fb6822f
......@@ -2209,8 +2209,7 @@ class BlockState(object):
"vertex_color",
"edge_gradient"]))
def sample_graph(self, canonical=False, niter=100, poisson=True,
multigraph=True, self_loops=True):
def sample_graph(self, canonical=False, multigraph=True, self_loops=True):
r"""Sample a new graph from the fitted model.
Parameters
......@@ -2219,16 +2218,10 @@ class BlockState(object):
If ``canonical == True``, the graph will be sampled from the
maximum-likelihood estimate of the canonical stochastic block
model. Otherwise, it will be sampled from the microcanonical model.
niter : ``int`` (optional, default: ``None``)
Number of MCMC steps. This value is ignored if ``canonical ==
False``.
multigraph : ``bool`` (optional, default: ``True``)
If ``True``, parallel edges will be allowed.
self-loops : ``bool`` (optional, default: ``True``)
If ``True``, self-loops will be allowed.
poisson : ``bool`` (optional, default: ``True``)
If ``True``, the Poisson model will be used, otherwise the graph
will be sampled from the corresponding maximum entropy ensemble.
Returns
-------
......@@ -2238,9 +2231,7 @@ class BlockState(object):
Notes
-----
This function is just a convenience wrapper to
:func:`~graph_tool.generation.random_rewire` (if ``poisson == False``)
and :func:`~graph_tool.generation.generate_sbm` (if ``poisson ==
True``).
:func:`~graph_tool.generation.generate_sbm`.
Examples
--------
......@@ -2264,41 +2255,23 @@ class BlockState(object):
SBM fitted to the original network.
"""
if poisson:
in_degs = out_degs = None
if self.deg_corr:
out_degs = self.g.degree_property_map("out").fa
if self.g.is_directed():
in_degs = self.g.degree_property_map("in").fa
else:
in_degs = None
probs = adjacency(self.bg, weight=self.mrs).T
g = generate_sbm(b=self.b.fa, probs=probs,
in_degs=in_degs, out_degs=out_degs,
directed=self.g.is_directed(),
micro_ers=not canonical,
micro_degs=not canonical and self.deg_corr)
if not multigraph:
remove_parallel_edges(g)
if not self_loops:
remove_self_loops(g)
else:
g = self.g.copy()
if self.deg_corr:
model = "constrained-configuration" if not canonical else "blockmodel-degree"
probs = None
in_degs = out_degs = None
if self.deg_corr:
out_degs = self.g.degree_property_map("out", weight=self.eweight).fa
if self.g.is_directed():
in_degs = self.g.degree_property_map("in", weight=self.eweight).fa
else:
model = "blockmodel"
if multigraph and self_loops:
niter = 1
def probs(r, s):
me = self.bg.edge(r, s)
if me is None:
return 0.
return self.mrs[me]
random_rewire(g, model=model, edge_probs=probs, n_iter=niter,
parallel_edges=multigraph, self_loops=self_loops,
block_membership=self.b)
in_degs = None
probs = adjacency(self.bg, weight=self.mrs).T
g = generate_sbm(b=self.b.fa, probs=probs,
in_degs=in_degs, out_degs=out_degs,
directed=self.g.is_directed(),
micro_ers=not canonical,
micro_degs=not canonical and self.deg_corr)
if not multigraph:
remove_parallel_edges(g)
if not self_loops:
remove_self_loops(g)
return g
def model_entropy(B, N, E, directed=False, nr=None, allow_empty=True):
......
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