Commit deafb2f7 authored by Tiago Peixoto's avatar Tiago Peixoto

Implement UncertainState.collect_marginal()

parent b7793fcc
......@@ -57,6 +57,7 @@ libgraph_tool_inference_la_SOURCES = \
uncertain/graph_blockmodel_measured.cc \
uncertain/graph_blockmodel_measured_mcmc.cc \
uncertain/graph_blockmodel_uncertain.cc \
uncertain/graph_blockmodel_uncertain_marginal.cc \
uncertain/graph_blockmodel_uncertain_mcmc.cc \
support/cache.cc \
support/int_part.cc \
......@@ -89,6 +90,7 @@ libgraph_tool_inference_la_include_HEADERS = \
layers/graph_blockmodel_layers_util.hh \
uncertain/graph_blockmodel_measured.hh \
uncertain/graph_blockmodel_uncertain.hh \
uncertain/graph_blockmodel_uncertain_marginal.hh \
uncertain/graph_blockmodel_uncertain_mcmc.hh \
uncertain/graph_blockmodel_sample_edge.hh \
loops/bundled_vacate_loop.hh \
......
......@@ -56,6 +56,8 @@ python::object make_uncertain_state(boost::python::object oblock_state,
return state;
}
void collect_marginal_dispatch(GraphInterface& gi, GraphInterface& ui,
boost::any aecount);
void export_uncertain_state()
{
......@@ -107,4 +109,5 @@ void export_uncertain_state()
});
});
def("collect_marginal", &collect_marginal_dispatch);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_tool.hh"
#include "graph_blockmodel_uncertain_marginal.hh"
using namespace boost;
using namespace graph_tool;
void collect_marginal_dispatch(GraphInterface& gi, GraphInterface& ui,
boost::any aecount)
{
typedef eprop_map_t<int32_t>::type emap_t;
auto ecount = any_cast<emap_t>(aecount);
gt_dispatch<>()
([&](auto& g, auto& u) { collect_marginal(g, u, ecount); },
all_graph_views(), all_graph_views())(gi.get_graph_view(),
ui.get_graph_view());
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GRAPH_BLOCKMODEL_UNCERTAIN_MARGINAL_HH
#define GRAPH_BLOCKMODEL_UNCERTAIN_MARGINAL_HH
#include "config.h"
#include <vector>
#include "../support/graph_state.hh"
#include "../blockmodel/graph_blockmodel_util.hh"
#include "graph_blockmodel_sample_edge.hh"
namespace graph_tool
{
using namespace boost;
using namespace std;
template <class Graph, class UGraph, class Eprop>
void collect_marginal(Graph& g, UGraph& u, Eprop ecount)
{
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
gt_hash_map<std::tuple<vertex_t, vertex_t>, edge_t> emap;
for (auto e : edges_range(g))
{
std::tuple<vertex_t, vertex_t> vs(source(e, g), target(e, g));
if (!graph_tool::is_directed(g) && get<0>(vs) > get<1>(vs))
std::swap(get<0>(vs), get<1>(vs));
emap[vs] = e;
}
for (auto e : edges_range(u))
{
std::tuple<vertex_t, vertex_t> vs(source(e, u), target(e, u));
if (!graph_tool::is_directed(g) && get<0>(vs) > get<1>(vs))
std::swap(get<0>(vs), get<1>(vs));
edge_t ge;
auto iter = emap.find(vs);
if (iter == emap.end())
{
ge = add_edge(get<0>(vs), get<1>(vs), g).first;
emap[vs] = ge;
ecount[ge] = 0;
}
else
{
ge = iter->second;
}
ecount[ge]++;
}
}
} // graph_tool namespace
#endif //GRAPH_BLOCKMODEL_UNCERTAIN_MARGINAL_HH
......@@ -235,6 +235,50 @@ class UncertainBaseState(object):
es.fa != et.fa))
return u
def collect_marginal(self, g=None):
r"""Collect marginal inferred network during MCMC runs.
Parameters
----------
g : :class:`~graph_tool.Graph` (optional, default: ``None``)
Marginal graph.
Returns
-------
g : :class:`~graph_tool.Graph`
New marginal graph, with internal edge :class:`~graph_tool.PropertyMap`
``"eprob"``, containing the marginal probabilities for each edge.
Notes
-----
The posterior marginal likelihood of an edge :math:`(i,j)` is defined as
.. math::
\pi_{ij} = \sum_{\boldsymbol A}A_{ij}P(\boldsymbol A|\boldsymbol D)
where :math:`P(\boldsymbol A|\boldsymbol D)` is the posterior
probability given the data.
"""
if g is None:
g = Graph(directed=self.g.is_directed())
g.add_vertex(self.g.num_vertices())
g.gp.count = g.new_gp("int", 0)
g.ep.count = g.new_ep("int")
if "eprob" not in g.ep:
g.ep.eprob = g.new_ep("double")
libinference.collect_marginal(g._Graph__graph,
self.u._Graph__graph,
_prop("e", g, g.ep.count))
g.gp.count += 1
g.ep.eprob.fa = g.ep.count.fa
g.ep.eprob.fa /= g.gp.count
return g
class UncertainBlockState(UncertainBaseState):
def __init__(self, g, q, q_default=0., aE=numpy.nan, nested=True, state_args={},
bstate=None, self_loops=False, **kwargs):
......
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