latent_multigraph.py 2.47 KB
Newer Older
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
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# graph_tool -- a general graph manipulation python module
#
# 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/>.

from .. import _prop

from .. dl_import import dl_import
dl_import("from . import libgraph_tool_inference as libinference")

from numpy import sqrt

28 29 30
def latent_multigraph(g, epsilon=1e-8, max_niter=0):
    r"""Infer latent Poisson multigraph model given an "erased" simple graph.

31 32 33 34
    Parameters
    ----------
    g : :class:`~graph_tool.Graph`
        Graph to be used.
35 36 37 38
    epsilon : ``float`` (optional, default: ``1e-8``)
        Convergence criterion.
    max_niter : ``int`` (optional, default: ``0``)
        Maximum number of iterations allowed (if ``0``, no maximum is assumed).
39 40 41

    Returns
    -------
42 43 44 45
    u : :class:`~graph_tool.Graph`
        Latent graph.
    w : :class:`~graph_tool.EdgePropertyMap`
        Edge property map with inferred multiplicity parameter.
46 47 48

    Examples
    --------
49 50 51 52 53 54
    >>> g = gt.collection.data["as-22july06"]
    >>> gt.scalar_assortativity(g, "out")
    (-0.198384..., 0.001338...)
    >>> u, w = gt.latent_multigraph(g)
    >>> scalar_assortativity(u, "out", eweight=w)
    (-0.048426..., 0.034526...)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    """

    g = g.copy()
    theta_out = g.degree_property_map("out").copy("double")
    theta_out.fa /= sqrt(theta_out.fa.sum())
    if g.is_directed():
        theta_in = g.degree_property_map("in").copy("double")
        theta_in.fa /= sqrt(theta_in.fa.sum())
    else:
        theta_in = theta_out

    w = g.new_ep("double", 1)

    libinference.latent_multigraph(g._Graph__graph,
                                   _prop("e", g, w),
                                   _prop("v", g, theta_out),
                                   _prop("v", g, theta_in),
                                   epsilon,
                                   max_niter)
    return g, w