Changeset 3a5c19


Ignore:
Timestamp:
12/03/08 16:26:18 (4 years ago)
Author:
Tiago de Paula Peixoto <tiago@…>
Branches:
master, python3
Children:
8cd708
Parents:
7cdf96
git-author:
Tiago de Paula Peixoto <tiago@…> (12/02/08 00:19:07)
git-committer:
Tiago de Paula Peixoto <tiago@…> (12/03/08 16:26:18)
Message:
Re-implement community graph calculation
Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/graph/community/Makefile.am

    rc153e0 r3a5c19  
    1616 
    1717libgraph_tool_community_la_SOURCES = \ 
    18     graph_community.cc 
     18    graph_community.cc \ 
     19    graph_community_network.cc 
  • src/graph/community/graph_community.cc

    rc153e0 r3a5c19  
    113113using namespace boost::python; 
    114114 
     115 
     116extern void community_network(GraphInterface& gi, GraphInterface& cgi, 
     117                              boost::any community_property, 
     118                              boost::any vertex_count, 
     119                              boost::any edge_count, boost::any weight); 
     120 
    115121BOOST_PYTHON_MODULE(libgraph_tool_community) 
    116122{ 
    117123    def("community_structure", &community_structure); 
    118124    def("modularity", &modularity); 
     125    def("community_network", &community_network); 
    119126} 
  • src/graph/community/graph_community_network.cc

    r3cfff0 r3a5c19  
    1616// along with this program. If not, see <http://www.gnu.org/licenses/>. 
    1717 
    18  
    1918#include "graph_filtering.hh" 
    2019#include "graph.hh" 
    21 #include "histogram.hh" 
    2220#include "graph_selectors.hh" 
    2321#include "graph_properties.hh" 
    2422 
    25  
    26 #include <boost/lambda/bind.hpp> 
    27 #include <tr1/unordered_set> 
    28 #include <iostream> 
    29 #include <iomanip> 
     23//#include <boost/lambda/bind.hpp> 
     24#include <boost/bind.hpp> 
     25#include <boost/bind/placeholders.hpp> 
     26#include <boost/mpl/push_back.hpp> 
     27#include <boost/python.hpp> 
    3028 
    3129#include "graph_community_network.hh" 
     
    3331using namespace std; 
    3432using namespace boost; 
    35 using namespace boost::lambda; 
     33 
    3634using namespace graph_tool; 
    3735 
    38 void GraphInterface::GetCommunityNetwork(string property, string size_property, 
    39                                          string out_file, string format) const 
     36 
     37void community_network(GraphInterface& gi, GraphInterface& cgi, 
     38                       boost::any community_property, boost::any vertex_count, 
     39                       boost::any edge_count, boost::any weight) 
    4040{ 
     41    // using boost::lambda::bind; 
     42    // using boost::lambda::_1; 
     43    // using boost::lambda::_2; 
     44    // using boost::lambda::_3; 
     45    // using boost::lambda::_4; 
     46 
     47    typedef DynamicPropertyMapWrap<double,GraphInterface::edge_t> weight_map_t; 
     48    typedef ConstantPropertyMap<double,GraphInterface::edge_t> no_weight_map_t; 
     49    typedef mpl::vector<weight_map_t,no_weight_map_t> weight_properties; 
     50 
     51    if (weight.empty()) 
     52        weight = no_weight_map_t(1.0); 
     53    else 
     54        weight = weight_map_t(weight, edge_scalar_properties()); 
     55 
     56    typedef vector_property_map<int32_t,GraphInterface::vertex_index_map_t> 
     57        vcount_t; 
     58    vcount_t vcount(gi.GetVertexIndex()); 
    4159    try 
    4260    { 
    43         boost::any vertex_prop = prop(property, _vertex_index, _properties); 
     61        vcount = any_cast<vcount_t>(vertex_count); 
     62    } 
     63    catch (bad_any_cast&) 
     64    { 
     65        throw GraphException("invalid vertex count property"); 
     66    } 
    4467 
    45         dynamic_properties_copy edge_properties; 
    46         for (typeof(_properties.begin()) iter = _properties.begin(); 
    47              iter != _properties.end(); ++iter) 
    48             if (iter->second->key() == typeid(edge_t)) 
    49                 edge_properties.insert(iter->first, 
    50                                        auto_ptr<dynamic_property_map> 
    51                                            (iter->second)); 
     68    typedef property_map_types::apply<mpl::vector<int32_t,double>, 
     69                                      GraphInterface::edge_index_map_t, 
     70                                      mpl::bool_<false> >::type 
     71        ecount_properties; 
    5272 
    53         run_action<>()(*this, 
    54                        bind<void>(get_community_network(), _1, _2, property, 
    55                                   size_property, var(edge_properties), 
    56                                   out_file, format), vertex_scalar_properties()) 
    57             (vertex_prop); 
    58     } 
    59     catch (property_not_found) 
    60     { 
    61         throw GraphException("edge property " + property + " not found"); 
    62     } 
     73    if (!belongs<ecount_properties>()(edge_count)) 
     74        throw GraphException("invalid edge count property"); 
     75 
     76     run_action<>()(gi, bind<void>(get_community_network(), _1, 
     77                                          &cgi.GetGraph(), cgi.GetVertexIndex(), 
     78                                          cgi.GetEdgeIndex(), _2, 
     79                                          _3, vcount, _4), 
     80                   vertex_properties(), weight_properties(), 
     81                   ecount_properties()) 
     82        (community_property, weight, edge_count); 
    6383} 
  • src/graph/community/graph_community_network.hh

    r3cfff0 r3a5c19  
    2323#include <iomanip> 
    2424 
    25 #include <boost/graph/graphviz.hpp> 
    26 #include <boost/graph/graphml.hpp> 
    27 #include <boost/algorithm/string.hpp> 
    28 #include <boost/iostreams/filtering_stream.hpp> 
    29 #include <boost/iostreams/filter/gzip.hpp> 
    30 #include <boost/iostreams/filter/bzip2.hpp> 
    31 #include <boost/iostreams/device/file.hpp> 
    32  
    3325namespace graph_tool 
    3426{ 
     
    4133struct get_community_network 
    4234{ 
    43     template <class Graph, class CommunityMap> 
    44     void operator()(const Graph* gp, CommunityMap s, string property, 
    45                     string size_property, dynamic_properties& edge_properties, 
    46                     string file, string format) const 
     35    template <class Graph, class CommunityGraph, class CommunityMap, 
     36              class WeightMap, class EdgeIndex, class VertexIndex, 
     37              class VertexProperty, class EdgeProperty> 
     38    void operator()(const Graph* gp, CommunityGraph* cgp, 
     39                    VertexIndex cvertex_index, EdgeIndex cedge_index, 
     40                    CommunityMap s_map, WeightMap weight, 
     41                    VertexProperty vertex_count, EdgeProperty edge_count) const 
    4742    { 
    4843        const Graph& g = *gp; 
     44        CommunityGraph& cg = *cgp; 
    4945 
    5046        typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; 
    5147        typedef typename graph_traits<Graph>::edge_descriptor edge_t; 
     48        typedef typename graph_traits<CommunityGraph>::vertex_descriptor 
     49            cvertex_t; 
     50        typedef typename graph_traits<CommunityGraph>::edge_descriptor 
     51            cedge_t; 
     52        typedef typename boost::property_traits<CommunityMap>::value_type 
     53            s_type; 
    5254 
    53         tr1::unordered_map 
    54             <typename boost::property_traits<CommunityMap>::value_type, size_t> 
     55        tr1::unordered_map<s_type, vector<vertex_t>, boost::hash<s_type> > 
    5556            comms; 
    56  
    5757        typename graph_traits<Graph>::vertex_iterator v, v_end; 
    5858        for (tie(v, v_end) = vertices(g); v != v_end; ++v) 
    59             comms[get(s, *v)]++; 
     59            comms[get(s_map, *v)].push_back(*v); 
    6060 
    61         typedef boost::property<edge_index_t, size_t> EdgeProperty; 
    62  
    63         typedef typename graph_traits<Graph>::directed_category 
    64             directed_category; 
    65         typedef typename mpl::if_<typename is_convertible<directed_category, 
    66                                                           directed_tag>::type, 
    67                                   bidirectionalS, 
    68                                   undirectedS>::type directed_selector; 
    69  
    70         typedef adjacency_list <vecS, // edges 
    71                                 vecS, // vertices 
    72                                 directed_selector, 
    73                                 no_property, 
    74                                 EdgeProperty > comm_graph_t; 
    75  
    76         comm_graph_t comm_graph; 
    77  
    78         typedef typename property_map<comm_graph_t, vertex_index_t>::type 
    79             comm_vertex_index_map_t; 
    80         comm_vertex_index_map_t 
    81             comm_vertex_index(get(vertex_index, comm_graph)); 
    82  
    83         vector_property_map<typename property_traits<CommunityMap>::value_type, 
    84                             comm_vertex_index_map_t> 
    85             comm_map(comm_vertex_index); 
    86         vector_property_map<size_t, comm_vertex_index_map_t> 
    87             comm_size_map(comm_vertex_index); 
    88         tr1::unordered_map 
    89             <typename property_traits<CommunityMap>::value_type, 
    90             typename graph_traits<comm_graph_t>::vertex_descriptor> 
    91             comm_vertex_map; 
     61        // create vertices 
     62        tr1::unordered_map<s_type, cvertex_t, boost::hash<s_type> > 
     63            comm_vertices; 
    9264        for (typeof(comms.begin()) iter = comms.begin(); iter != comms.end(); 
    9365             ++iter) 
    9466        { 
    95             comm_vertex_map[iter->first] = add_vertex(comm_graph); 
    96             comm_map[comm_vertex_map[iter->first]] = iter->first; 
    97             if (size_property != "") 
    98                 comm_size_map[comm_vertex_map[iter->first]] = iter->second; 
     67            cvertex_t v = add_vertex(cg); 
     68            vertex_count[v] = iter->second.size(); 
     69            comm_vertices[iter->first] = v; 
    9970        } 
    10071 
    101         dynamic_properties dp; 
    102         dp.property(property, comm_map); 
    103         if (size_property != "") 
    104             dp.property(size_property, comm_size_map); 
     72        // create edges 
     73        tr1::unordered_map<pair<size_t, size_t>, 
     74                           cedge_t, boost::hash<pair<size_t, size_t> > > 
     75            comm_edges; 
     76        for (typeof(comms.begin()) iter = comms.begin(); iter != comms.end(); 
     77             ++iter) 
     78        { 
    10579 
    106         typedef typename property_map<comm_graph_t,edge_index_t>::type 
    107             comm_edge_index_map_t; 
    108         comm_edge_index_map_t comm_edge_index(get(edge_index_t(), comm_graph)); 
    109  
    110         typedef HashedDescriptorMap<comm_edge_index_map_t, edge_t> edge_map_t; 
    111         edge_map_t edge_map(comm_edge_index); 
    112  
    113         size_t e_index = 0; 
    114         typename graph_traits<Graph>::edge_iterator e, e_end; 
    115         for (tie(e, e_end) = edges(g); e != e_end; ++e) 
    116         { 
    117             typename graph_traits<comm_graph_t>::edge_descriptor edge; 
    118             edge  = add_edge(comm_vertex_map[get(s,source(*e, g))], 
    119                              comm_vertex_map[get(s,target(*e, g))], 
    120                              comm_graph).first; 
    121             edge_map[edge] = *e; 
    122             comm_edge_index[edge] = e_index++; 
    123         } 
    124  
    125         for (typeof(edge_properties.begin()) iter = edge_properties.begin(); 
    126              iter != edge_properties.end(); ++iter) 
    127             dp.insert(iter->first, 
    128                       auto_ptr<dynamic_property_map> 
    129                           (new dynamic_property_map_wrap<edge_map_t> 
    130                            (edge_map, *iter->second))); 
    131  
    132         bool graphviz = false; 
    133         if (format == "") 
    134             graphviz = ends_with(file,".dot") || ends_with(file,".dot.gz") || 
    135                 ends_with(file,".dot.bz2"); 
    136         else if (format == "dot") 
    137             graphviz = true; 
    138         else if (format != "xml") 
    139             throw GraphException("error writing to file '" + file + 
    140                                  "': requested invalid format '" + 
    141                                  format + "'"); 
    142         try 
    143         { 
    144             iostreams::filtering_stream<iostreams::output> stream; 
    145             ofstream file_stream; 
    146             if (file == "-") 
    147                 stream.push(cout); 
    148             else 
     80            cvertex_t cs = comm_vertices[iter->first]; 
     81            for (size_t i = 0; i < iter->second.size(); ++i) 
    14982            { 
    150                 file_stream.open(file.c_str(), ios_base::out | 
    151                                  ios_base::binary); 
    152                 file_stream.exceptions(ios_base::badbit | ios_base::failbit); 
    153                 if (ends_with(file,".gz")) 
    154                     stream.push(iostreams::gzip_compressor()); 
    155                 if (ends_with(file,".bz2")) 
    156                     stream.push(iostreams::bzip2_compressor()); 
    157                 stream.push(file_stream); 
     83                vertex_t s = iter->second[i]; 
     84                typename graph_traits<Graph>::out_edge_iterator e, e_end; 
     85                for (tie(e, e_end) = out_edges(s, g); e != e_end; ++e) 
     86                { 
     87                    vertex_t t = target(*e, g); 
     88                    cvertex_t ct = comm_vertices[get(s_map, t)]; 
     89                    if (ct == cs) // self-loops are pointless 
     90                        continue; 
     91                    cedge_t ce; 
     92                    if (comm_edges.find(make_pair(cs, ct)) != comm_edges.end()) 
     93                        ce = comm_edges[make_pair(cs, ct)]; 
     94                    else if (!is_directed::apply<Graph>::type::value && 
     95                             comm_edges.find(make_pair(ct, cs)) != comm_edges.end()) 
     96                        ce = comm_edges[make_pair(ct, cs)]; 
     97                    else 
     98                    { 
     99                        ce = add_edge(cs,ct,cg).first; 
     100                        comm_edges[make_pair(cs, ct)] = ce; 
     101                    } 
     102                    edge_count[ce] += get(weight, *e); 
     103                } 
    158104            } 
    159             stream.exceptions(ios_base::badbit | ios_base::failbit); 
    160  
    161             if (graphviz) 
    162             { 
    163                 dp.property("vertex_id", comm_vertex_index); 
    164                 write_graphviz(stream, comm_graph, dp, string("vertex_id")); 
    165             } 
    166             else 
    167             { 
    168                 write_graphml(stream, comm_graph, comm_vertex_index, dp, true); 
    169             } 
    170             stream.reset(); 
    171         } 
    172         catch (ios_base::failure &e) 
    173         { 
    174             throw GraphException("error writing to file '" + file + "':" + 
    175                                  e.what()); 
    176105        } 
    177106    } 
    178  
    179     template <class EdgeMap> 
    180     class dynamic_property_map_wrap: public dynamic_property_map 
    181     { 
    182     public: 
    183         dynamic_property_map_wrap(EdgeMap& edge_map, dynamic_property_map& dm): 
    184             _edge_map(edge_map), _dm(dm) {} 
    185         any get(const any& key) 
    186         { 
    187             return _dm.get(_edge_map[any_cast<key_t>(key)]); 
    188         } 
    189  
    190         string get_string(const any& key) 
    191         { 
    192             return _dm.get_string(_edge_map[any_cast<key_t>(key)]); 
    193         } 
    194  
    195         void put(const any& key, const any& value) 
    196         { 
    197             return _dm.put(_edge_map[any_cast<key_t>(key)], value); 
    198         } 
    199  
    200         const type_info& key() const 
    201         { 
    202             return typeid(key_t); 
    203         } 
    204  
    205         const type_info& value() const 
    206         { 
    207             return _dm.value(); 
    208         } 
    209     private: 
    210         EdgeMap& _edge_map; 
    211         typedef typename property_traits<EdgeMap>::key_type key_t; 
    212         dynamic_property_map& _dm; 
    213     }; 
    214  
    215107}; 
    216108 
  • src/graph_tool/community/__init__.py

    rc153e0 r3a5c19  
    2020dl_import("import libgraph_tool_community") 
    2121 
    22 from .. core import _degree, _prop 
     22from .. core import _degree, _prop, Graph, libcore 
    2323import random, sys 
    2424 
    25 __all__ = ["community_structure", "modularity"] 
     25__all__ = ["community_structure", "modularity", "community_network"] 
    2626 
    2727 
     
    4747    c = libgraph_tool_clustering.global_clustering(g._Graph__graph) 
    4848    return c 
     49 
     50def community_network(g, prop, weight=None): 
     51    gp = Graph() 
     52    vcount = g.new_vertex_property("int32_t") 
     53    if weight != None: 
     54        ecount = g.new_edge_property("double") 
     55        weight = _prop("e", g, weight) 
     56    else: 
     57        ecount = g.new_edge_property("int32_t") 
     58        weight = libcore.any() 
     59    libgraph_tool_community.community_network(g._Graph__graph, 
     60                                              gp._Graph__graph, 
     61                                              _prop("v", g, prop), 
     62                                              _prop("v", g, vcount), 
     63                                              _prop("e", g, ecount), 
     64                                              weight) 
     65    return gp, vcount, ecount 
     66 
Note: See TracChangeset for help on using the changeset viewer.