graph_community_network.cc 6.04 KB
Newer Older
1 2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2007-2012 Tiago de Paula Peixoto <tiago@skewed.de>
4 5 6
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
Tiago Peixoto's avatar
Tiago Peixoto committed
7
// as published by the Free Software Foundation; either version 3
8 9 10 11 12 13 14 15
// 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
16 17
// along with this program. If not, see <http://www.gnu.org/licenses/>.

18 19 20 21 22
#include "graph_filtering.hh"
#include "graph.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"

23 24 25 26
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/python.hpp>
27

28
#include "graph_community_network.hh"
29 30 31

using namespace std;
using namespace boost;
32

33 34
using namespace graph_tool;

35 36 37 38 39 40 41 42 43 44 45
typedef ConstantPropertyMap<int32_t,GraphInterface::edge_t> no_eweight_map_t;
typedef ConstantPropertyMap<int32_t,GraphInterface::vertex_t> no_vweight_map_t;
typedef DynamicPropertyMapWrap<int32_t,GraphInterface::vertex_t> viweight_map_t;
typedef DynamicPropertyMapWrap<double,GraphInterface::vertex_t> vweight_map_t;
typedef DynamicPropertyMapWrap<int32_t,GraphInterface::edge_t> eiweight_map_t;
typedef DynamicPropertyMapWrap<double,GraphInterface::edge_t> eweight_map_t;
typedef DynamicPropertyMapWrap<python::object,GraphInterface::vertex_t> voweight_map_t;
typedef DynamicPropertyMapWrap<python::object,GraphInterface::edge_t> eoweight_map_t;

struct get_community_network_dispatch
{
46 47 48
    get_community_network_dispatch(bool self_loops): _self_loops(self_loops) {}
    bool _self_loops;

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    template <class Graph, class CommunityGraph, class CommunityMap,
              class VertexWeightMap, class EdgeWeightMap, class EdgeIndex,
              class VertexIndex>
    void operator()(const Graph& g, CommunityGraph& cg,
                    VertexIndex cvertex_index, EdgeIndex cedge_index,
                    CommunityMap s_map, boost::any acs_map,
                    VertexWeightMap vweight, EdgeWeightMap eweight,
                    pair<boost::any,boost::any> count) const
    {
        typedef typename get_prop_type<CommunityMap, VertexIndex>::type
            comm_t;
        comm_t cs_map = boost::any_cast<comm_t>(acs_map);

        typedef typename mpl::if_<is_same<no_vweight_map_t, VertexWeightMap>,
                                  viweight_map_t, VertexWeightMap>::type vweight_t;
        typedef typename mpl::if_<is_same<no_eweight_map_t, EdgeWeightMap>,
                                  eiweight_map_t, EdgeWeightMap>::type eweight_t;

        vweight_t vertex_count = boost::any_cast<vweight_t>(count.first);
        eweight_t edge_count = boost::any_cast<eweight_t>(count.second);

        get_community_network()(g, cg, cvertex_index, cedge_index, s_map,
                                cs_map, vweight, eweight, vertex_count,
72
                                edge_count, _self_loops);
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    }

    struct get_checked_t
    {
        template <class PropertyMap>
        struct apply
        {
            typedef typename PropertyMap::checked_t type;
        };
    };

    struct get_identity
    {
        template <class PropertyMap>
        struct apply
        {
            typedef PropertyMap type;
        };
    };

    template <class PropertyMap, class IndexMap>
    struct get_prop_type
    {
        typedef typename mpl::if_<typename is_same<PropertyMap, IndexMap>::type,
                                  get_identity,
                                  get_checked_t>::type extract;
        typedef typename extract::template apply<PropertyMap>::type type;
    };

};

104 105

void community_network(GraphInterface& gi, GraphInterface& cgi,
106 107 108
                       boost::any community_property,
                       boost::any condensed_community_property,
                       boost::any vertex_count,
109
                       boost::any edge_count, boost::any vweight,
110
                       boost::any eweight, bool self_loops)
111
{
112 113 114 115
    typedef typename mpl::vector<vweight_map_t, voweight_map_t, no_vweight_map_t>::type
        vweight_properties;
    typedef typename mpl::vector<eweight_map_t, eoweight_map_t, no_eweight_map_t>::type
        eweight_properties;
116

117 118 119 120 121
    if (eweight.empty())
    {
        eweight = no_eweight_map_t(1);
        edge_count = eiweight_map_t(edge_count, edge_scalar_properties());
    }
122
    else
123 124 125 126 127 128 129 130 131 132 133 134
    {
        try
        {
            eweight = eweight_map_t(eweight, edge_scalar_properties());
            edge_count = eweight_map_t(edge_count, edge_scalar_properties());
        }
        catch (...)
        {
            eweight = eoweight_map_t(eweight, edge_properties());
            edge_count = eoweight_map_t(edge_count, edge_properties());
        }
    }
135

136
    if (vweight.empty())
137
    {
138 139
        vweight = no_vweight_map_t(1);
        vertex_count = viweight_map_t(vertex_count, vertex_scalar_properties());
140
    }
141
    else
142
    {
143 144 145 146 147 148 149 150 151 152
        try
        {
            vweight = vweight_map_t(vweight, vertex_scalar_properties());
            vertex_count = vweight_map_t(vertex_count, vertex_scalar_properties());
        }
        catch (...)
        {
            vweight = voweight_map_t(vweight, vertex_properties());
            vertex_count = voweight_map_t(vertex_count, vertex_properties());
        }
153
    }
154

155 156
     run_action<>()(gi, bind<void>(get_community_network_dispatch(self_loops),
                                   _1, ref(cgi.GetGraph()), cgi.GetVertexIndex(),
157
                                   cgi.GetEdgeIndex(), _2,
158
                                   condensed_community_property,
159 160 161 162
                                   _3, _4, make_pair(vertex_count, edge_count)),
                    vertex_scalar_properties(), vweight_properties(),
                    eweight_properties())
        (community_property, vweight, eweight);
163
     cgi.ReIndexEdges();
164
}