Changeset 3a5c19
- Timestamp:
- 12/03/08 16:26:18 (4 years ago)
- 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)
- Location:
- src
- Files:
-
- 5 edited
-
graph/community/Makefile.am (modified) (1 diff)
-
graph/community/graph_community.cc (modified) (1 diff)
-
graph/community/graph_community_network.cc (modified) (2 diffs)
-
graph/community/graph_community_network.hh (modified) (2 diffs)
-
graph_tool/community/__init__.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/graph/community/Makefile.am
rc153e0 r3a5c19 16 16 17 17 libgraph_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 113 113 using namespace boost::python; 114 114 115 116 extern 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 115 121 BOOST_PYTHON_MODULE(libgraph_tool_community) 116 122 { 117 123 def("community_structure", &community_structure); 118 124 def("modularity", &modularity); 125 def("community_network", &community_network); 119 126 } -
src/graph/community/graph_community_network.cc
r3cfff0 r3a5c19 16 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 17 18 19 18 #include "graph_filtering.hh" 20 19 #include "graph.hh" 21 #include "histogram.hh"22 20 #include "graph_selectors.hh" 23 21 #include "graph_properties.hh" 24 22 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> 30 28 31 29 #include "graph_community_network.hh" … … 33 31 using namespace std; 34 32 using namespace boost; 35 using namespace boost::lambda; 33 36 34 using namespace graph_tool; 37 35 38 void GraphInterface::GetCommunityNetwork(string property, string size_property, 39 string out_file, string format) const 36 37 void community_network(GraphInterface& gi, GraphInterface& cgi, 38 boost::any community_property, boost::any vertex_count, 39 boost::any edge_count, boost::any weight) 40 40 { 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()); 41 59 try 42 60 { 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 } 44 67 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; 52 72 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); 63 83 } -
src/graph/community/graph_community_network.hh
r3cfff0 r3a5c19 23 23 #include <iomanip> 24 24 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 33 25 namespace graph_tool 34 26 { … … 41 33 struct get_community_network 42 34 { 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 47 42 { 48 43 const Graph& g = *gp; 44 CommunityGraph& cg = *cgp; 49 45 50 46 typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; 51 47 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; 52 54 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> > 55 56 comms; 56 57 57 typename graph_traits<Graph>::vertex_iterator v, v_end; 58 58 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); 60 60 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; 92 64 for (typeof(comms.begin()) iter = comms.begin(); iter != comms.end(); 93 65 ++iter) 94 66 { 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; 99 70 } 100 71 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 { 105 79 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) 149 82 { 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 } 158 104 } 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 else167 {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());176 105 } 177 106 } 178 179 template <class EdgeMap>180 class dynamic_property_map_wrap: public dynamic_property_map181 {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() const201 {202 return typeid(key_t);203 }204 205 const type_info& value() const206 {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 215 107 }; 216 108 -
src/graph_tool/community/__init__.py
rc153e0 r3a5c19 20 20 dl_import("import libgraph_tool_community") 21 21 22 from .. core import _degree, _prop 22 from .. core import _degree, _prop, Graph, libcore 23 23 import random, sys 24 24 25 __all__ = ["community_structure", "modularity" ]25 __all__ = ["community_structure", "modularity", "community_network"] 26 26 27 27 … … 47 47 c = libgraph_tool_clustering.global_clustering(g._Graph__graph) 48 48 return c 49 50 def 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.


