diff --git a/src/graph/centrality/graph_katz.cc b/src/graph/centrality/graph_katz.cc index bfbd8b12beac44937ae932183b2d928f066301c2..26d763629bfec567243b45f94436e9dfa590a3e3 100644 --- a/src/graph/centrality/graph_katz.cc +++ b/src/graph/centrality/graph_katz.cc @@ -39,19 +39,19 @@ void katz(GraphInterface& g, boost::any w, boost::any c, boost::any beta, throw ValueException("personalization vertex property must be of floating point" " value type"); - typedef ConstantPropertyMap weight_map_t; + typedef ConstantPropertyMap weight_map_t; typedef mpl::push_back::type weight_props_t; if(w.empty()) - w = weight_map_t(1); + w = weight_map_t(1.); - typedef ConstantPropertyMap beta_map_t; + typedef ConstantPropertyMap beta_map_t; typedef mpl::push_back::type beta_props_t; if(beta.empty()) - beta = beta_map_t(1); + beta = beta_map_t(1.); run_action<>()(g, bind (get_katz(), _1, g.GetVertexIndex(), _2, diff --git a/src/graph/centrality/graph_katz.hh b/src/graph/centrality/graph_katz.hh index aca3772afa9d6b48517fa8123451f51d6baa088b..ebb40f597d08c1d81846ac56ae0978ee542a47db 100644 --- a/src/graph/centrality/graph_katz.hh +++ b/src/graph/centrality/graph_katz.hh @@ -44,14 +44,12 @@ struct get_katz CentralityMap c_temp(vertex_index, num_vertices(g)); t_type delta = epsilon + 1; - t_type norm = 0; size_t iter = 0; int i, N = num_vertices(g); while (delta >= epsilon) { - norm = 0; #pragma omp parallel for default(shared) private(i) \ - schedule(static) if (N > 100) reduction(+:norm) + schedule(static) if (N > 100) for (i = 0; i < N; ++i) { typename graph_traits::vertex_descriptor v = @@ -66,14 +64,12 @@ struct get_katz { typename graph_traits::vertex_descriptor s; if (is_directed::apply::type::value) - s = source(*e,g); + s = source(*e, g); else - s = target(*e,g); + s = target(*e, g); c_temp[v] += alpha * get(w, *e) * c[s]; } - norm += power(c_temp[v], 2); } - norm = sqrt(norm); delta = 0; #pragma omp parallel for default(shared) private(i) \ @@ -84,13 +80,12 @@ struct get_katz vertex(i, g); if (v == graph_traits::null_vertex()) continue; - c_temp[v] /= norm; delta += abs(c_temp[v] - c[v]); } swap(c_temp, c); ++iter; - if (max_iter > 0 && iter== max_iter) + if (max_iter > 0 && iter == max_iter) break; } @@ -104,7 +99,7 @@ struct get_katz vertex(i, g); if (v == graph_traits::null_vertex()) continue; - c[v] = c_temp[v]; + c_temp[v] = c[v]; } } } diff --git a/src/graph_tool/centrality/__init__.py b/src/graph_tool/centrality/__init__.py index 6bc5a4f53c7b42a85c34953d20a3a9946983f273..9e18c13622a2790d4de26ffcf4d4cc0c0d6bd6ab 100644 --- a/src/graph_tool/centrality/__init__.py +++ b/src/graph_tool/centrality/__init__.py @@ -53,6 +53,7 @@ from .. import _prop, ungroup_vector_property from .. topology import shortest_distance import sys import numpy +import numpy.linalg __all__ = ["pagerank", "betweenness", "central_point_dominance", "closeness", "eigentrust", "eigenvector", "katz", "hits", "trust_transitivity"] @@ -622,7 +623,8 @@ def eigenvector(g, weight=None, vprop=None, epsilon=1e-6, max_iter=None): return ee, vprop -def katz(g, alpha=0.01, beta=None, weight=None, vprop=None, epsilon=1e-6, max_iter=None): +def katz(g, alpha=0.01, beta=None, weight=None, vprop=None, epsilon=1e-6, + max_iter=None, norm=True): r""" Calculate the Katz centrality of each vertex in the graph. @@ -646,6 +648,8 @@ def katz(g, alpha=0.01, beta=None, weight=None, vprop=None, epsilon=1e-6, max_it vertices are below this value. max_iter : int, optional (default: ``None``) If supplied, this will limit the total number of iterations. + norm : bool, optional (default: ``True``) + Whether or not the centrality values should be normalized. Returns ------- @@ -723,15 +727,15 @@ def katz(g, alpha=0.01, beta=None, weight=None, vprop=None, epsilon=1e-6, max_it Weblogging Ecosystem (2005). :DOI:`10.1145/1134271.1134277` """ - if vprop == None: + if vprop is None: vprop = g.new_vertex_property("double") - N = len(vprop.a) - vprop.a = beta.a[:N] if beta is not None else 1. if max_iter is None: max_iter = 0 - ee = libgraph_tool_centrality.\ + libgraph_tool_centrality.\ get_katz(g._Graph__graph, _prop("e", g, weight), _prop("v", g, vprop), - _prop("v", beta, vprop), float(alpha), epsilon, max_iter) + _prop("v", g, beta), float(alpha), epsilon, max_iter) + if norm: + vprop.fa = vprop.fa / numpy.linalg.norm(vprop.fa) return vprop