Commit a9a2ba7f authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement graph_tool::is_directed()

parent 314bc212
...@@ -43,7 +43,7 @@ struct get_eigentrust ...@@ -43,7 +43,7 @@ struct get_eigentrust
// Norm c values // Norm c values
InferredTrustMap c_sum(vertex_index); InferredTrustMap c_sum(vertex_index);
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
{ {
TrustMap c_temp(edge_index, c.get_storage().size()); TrustMap c_temp(edge_index, c.get_storage().size());
parallel_vertex_loop parallel_vertex_loop
...@@ -93,11 +93,11 @@ struct get_eigentrust ...@@ -93,11 +93,11 @@ struct get_eigentrust
for (const auto& e : in_or_out_edges_range(v, g)) for (const auto& e : in_or_out_edges_range(v, g))
{ {
typename graph_traits<Graph>::vertex_descriptor s; typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
s = source(e, g); s = source(e, g);
else else
s = target(e, g); s = target(e, g);
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(g))
t_temp[v] += get(c, e) * t[s] / abs(c_sum[s]); t_temp[v] += get(c, e) * t[s] / abs(c_sum[s]);
else else
t_temp[v] += get(c, e) * t[s]; t_temp[v] += get(c, e) * t[s];
......
...@@ -68,7 +68,7 @@ struct get_eigenvector ...@@ -68,7 +68,7 @@ struct get_eigenvector
for (const auto& e : in_or_out_edges_range(v, g)) for (const auto& e : in_or_out_edges_range(v, g))
{ {
typename graph_traits<Graph>::vertex_descriptor s; typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
s = source(e, g); s = source(e, g);
else else
s = target(e, g); s = target(e, g);
......
...@@ -79,7 +79,7 @@ struct get_hits ...@@ -79,7 +79,7 @@ struct get_hits
for (const auto& ie : in_or_out_edges_range(v, g)) for (const auto& ie : in_or_out_edges_range(v, g))
{ {
typename graph_traits<Graph>::vertex_descriptor s; typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
s = source(ie, g); s = source(ie, g);
else else
s = target(ie, g); s = target(ie, g);
......
...@@ -65,7 +65,7 @@ struct get_katz ...@@ -65,7 +65,7 @@ struct get_katz
for (const auto& e : in_or_out_edges_range(v, g)) for (const auto& e : in_or_out_edges_range(v, g))
{ {
typename graph_traits<Graph>::vertex_descriptor s; typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
s = source(e, g); s = source(e, g);
else else
s = target(e, g); s = target(e, g);
......
...@@ -64,7 +64,7 @@ struct get_pagerank ...@@ -64,7 +64,7 @@ struct get_pagerank
for (const auto& e : in_or_out_edges_range(v, g)) for (const auto& e : in_or_out_edges_range(v, g))
{ {
typename graph_traits<Graph>::vertex_descriptor s; typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
s = source(e, g); s = source(e, g);
else else
s = target(e, g); s = target(e, g);
......
...@@ -75,7 +75,7 @@ get_triangles(typename graph_traits<Graph>::vertex_descriptor v, VProp& mark, ...@@ -75,7 +75,7 @@ get_triangles(typename graph_traits<Graph>::vertex_descriptor v, VProp& mark,
mark[n] = false; mark[n] = false;
size_t k = out_degree(v, g); size_t k = out_degree(v, g);
if (is_directed::apply<Graph>::type::value) if (graph_tool::is_directed(g))
return make_pair(triangles, (k * (k - 1))); return make_pair(triangles, (k * (k - 1)));
else else
return make_pair(triangles / 2, (k * (k - 1)) / 2); return make_pair(triangles / 2, (k * (k - 1)) / 2);
......
...@@ -212,7 +212,7 @@ void make_subgraph ...@@ -212,7 +212,7 @@ void make_subgraph
auto viter = lower_bound(vlist.begin(), vlist.end(), ot); auto viter = lower_bound(vlist.begin(), vlist.end(), ot);
size_t ot_index = viter - vlist.begin(); size_t ot_index = viter - vlist.begin();
if (viter != vlist.end() && vlist[ot_index] == ot && if (viter != vlist.end() && vlist[ot_index] == ot &&
(is_directed::apply<Graph>::type::value || ot < ov)) (graph_tool::is_directed(g) || ot < ov))
add_edge(nv, vertex(ot_index, sub), sub); add_edge(nv, vertex(ot_index, sub), sub);
} }
} }
...@@ -283,12 +283,12 @@ void get_sig(Graph& g, std::vector<size_t>& sig) ...@@ -283,12 +283,12 @@ void get_sig(Graph& g, std::vector<size_t>& sig)
sig.clear(); sig.clear();
size_t N = num_vertices(g); size_t N = num_vertices(g);
if (N > 0) if (N > 0)
sig.resize(is_directed::apply<Graph>::type::value ? 2 * N : N); sig.resize(graph_tool::is_directed(g) ? 2 * N : N);
for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
{ {
auto v = vertex(i, g); auto v = vertex(i, g);
sig[i] = out_degree(v, g); sig[i] = out_degree(v, g);
if(is_directed::apply<Graph>::type::value) if(graph_tool::is_directed(g))
sig[i + N] = in_degreeS()(v, g); sig[i + N] = in_degreeS()(v, g);
} }
sort(sig.begin(), sig.end()); sort(sig.begin(), sig.end());
......
...@@ -92,7 +92,7 @@ struct get_assortativity_coefficient ...@@ -92,7 +92,7 @@ struct get_assortativity_coefficient
// "jackknife" variance // "jackknife" variance
double err = 0; double err = 0;
size_t one = (is_directed::apply<Graph>::type::value) ? 1 : 2; size_t one = (graph_tool::is_directed(g)) ? 1 : 2;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \ #pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:err) reduction(+:err)
parallel_vertex_loop_no_spawn parallel_vertex_loop_no_spawn
...@@ -114,7 +114,7 @@ struct get_assortativity_coefficient ...@@ -114,7 +114,7 @@ struct get_assortativity_coefficient
err += (r - rl) * (r - rl); err += (r - rl) * (r - rl);
} }
}); });
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(g))
err /= 2; err /= 2;
#if (BOOST_VERSION >= 106000) #if (BOOST_VERSION >= 106000)
if (boost::math::relative_difference(1., t2) > 1e-8) if (boost::math::relative_difference(1., t2) > 1e-8)
...@@ -194,7 +194,7 @@ struct get_scalar_assortativity_coefficient ...@@ -194,7 +194,7 @@ struct get_scalar_assortativity_coefficient
r_err = 0.0; r_err = 0.0;
double err = 0.0; double err = 0.0;
size_t one = (is_directed::apply<Graph>::type::value) ? 1 : 2; size_t one = (graph_tool::is_directed(g)) ? 1 : 2;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \ #pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:err) reduction(+:err)
parallel_vertex_loop_no_spawn parallel_vertex_loop_no_spawn
...@@ -219,7 +219,7 @@ struct get_scalar_assortativity_coefficient ...@@ -219,7 +219,7 @@ struct get_scalar_assortativity_coefficient
err += (r - rl) * (r - rl); err += (r - rl) * (r - rl);
} }
}); });
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(g))
err /= 2; err /= 2;
if (stda*stdb > 0) if (stda*stdb > 0)
r_err = sqrt(err); r_err = sqrt(err);
......
...@@ -140,7 +140,7 @@ struct get_community_network_edges ...@@ -140,7 +140,7 @@ struct get_community_network_edges
} }
else else
{ {
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(g))
{ {
iter = comm_edges[ct].find(cs); iter = comm_edges[ct].find(cs);
if (iter != comm_edges[ct].end()) if (iter != comm_edges[ct].end())
...@@ -296,7 +296,7 @@ struct get_edge_community_property_sum ...@@ -296,7 +296,7 @@ struct get_edge_community_property_sum
continue; // self-loops not allowed continue; // self-loops not allowed
auto* ces = &comm_edges[make_pair(cs, ct)]; auto* ces = &comm_edges[make_pair(cs, ct)];
if (ces->empty() && !is_directed::apply<Graph>::type::value) if (ces->empty() && !graph_tool::is_directed(g))
ces = &comm_edges[make_pair(ct, cs)]; ces = &comm_edges[make_pair(ct, cs)];
if (ces->empty()) if (ces->empty())
{ {
......
...@@ -574,7 +574,7 @@ struct gen_graph ...@@ -574,7 +574,7 @@ struct gen_graph
typename graph_traits<Graph>::vertex_descriptor t = typename graph_traits<Graph>::vertex_descriptor t =
vertex(vertices[t_i].index, g); vertex(vertices[t_i].index, g);
if ((s == t) && (!is_directed::apply<Graph>::type::value && if ((s == t) && (!graph_tool::is_directed(g) &&
s_deg.second < 2)) s_deg.second < 2))
continue; continue;
......
...@@ -47,7 +47,7 @@ struct get_line_graph ...@@ -47,7 +47,7 @@ struct get_line_graph
vertex_map[v] = edge_index[e]; vertex_map[v] = edge_index[e];
} }
if (boost::is_directed(g)) if (graph_tool::is_directed(g))
{ {
for (auto v : vertices_range(g)) for (auto v : vertices_range(g))
{ {
......
...@@ -62,18 +62,18 @@ target(const pair<size_t, bool>& e, ...@@ -62,18 +62,18 @@ target(const pair<size_t, bool>& e,
template <class Nmap, class Graph> template <class Nmap, class Graph>
void add_count(size_t s, size_t t, Nmap& nvmap, Graph&) void add_count(size_t s, size_t t, Nmap& nvmap, Graph& g)
{ {
if (!is_directed::apply<Graph>::type::value && s > t) if (!graph_tool::is_directed(g) && s > t)
std::swap(s, t); std::swap(s, t);
auto& nmap = nvmap[s]; auto& nmap = nvmap[s];
nmap[t]++; nmap[t]++;
} }
template <class Nmap, class Graph> template <class Nmap, class Graph>
void remove_count(size_t s, size_t t, Nmap& nvmap, Graph&) void remove_count(size_t s, size_t t, Nmap& nvmap, Graph& g)
{ {
if (!is_directed::apply<Graph>::type::value && s > t) if (!graph_tool::is_directed(g) && s > t)
std::swap(s, t); std::swap(s, t);
auto& nmap = nvmap[s]; auto& nmap = nvmap[s];
auto iter = nmap.find(t); auto iter = nmap.find(t);
...@@ -83,9 +83,9 @@ void remove_count(size_t s, size_t t, Nmap& nvmap, Graph&) ...@@ -83,9 +83,9 @@ void remove_count(size_t s, size_t t, Nmap& nvmap, Graph&)
} }
template <class Nmap, class Graph> template <class Nmap, class Graph>
size_t get_count(size_t s, size_t t, Nmap& nvmap, Graph&) size_t get_count(size_t s, size_t t, Nmap& nvmap, Graph& g)
{ {
if (!is_directed::apply<Graph>::type::value && s > t) if (!graph_tool::is_directed(g) && s > t)
std::swap(s, t); std::swap(s, t);
auto& nmap = nvmap[s]; auto& nmap = nvmap[s];
auto iter = nmap.find(t); auto iter = nmap.find(t);
...@@ -157,12 +157,12 @@ struct swap_edge ...@@ -157,12 +157,12 @@ struct swap_edge
remove_edge(edges[e.first], g); remove_edge(edges[e.first], g);
remove_edge(edges[te.first], g); remove_edge(edges[te.first], g);
if (is_directed::apply<Graph>::type::value || !e.second) if (graph_tool::is_directed(g) || !e.second)
ne = add_edge(s_e, t_te, g).first; ne = add_edge(s_e, t_te, g).first;
else // keep invertedness (only for undirected graphs) else // keep invertedness (only for undirected graphs)
ne = add_edge(t_te, s_e, g).first; ne = add_edge(t_te, s_e, g).first;
edges[e.first] = ne; edges[e.first] = ne;
if (is_directed::apply<Graph>::type::value || !te.second) if (graph_tool::is_directed(g) || !te.second)
nte = add_edge(s_te, t_e, g).first; nte = add_edge(s_te, t_e, g).first;
else // keep invertedness (only for undirected graphs) else // keep invertedness (only for undirected graphs)
nte = add_edge(t_e, s_te, g).first; nte = add_edge(t_e, s_te, g).first;
...@@ -402,7 +402,7 @@ public: ...@@ -402,7 +402,7 @@ public:
size_t e_s = source(_edges[ei], _g); size_t e_s = source(_edges[ei], _g);
size_t e_t = target(_edges[ei], _g); size_t e_t = target(_edges[ei], _g);
if (!is_directed::apply<Graph>::type::value && e_s > e_t) if (!graph_tool::is_directed(_g) && e_s > e_t)
std::swap(e_s, e_t); std::swap(e_s, e_t);
//try randomly drawn pairs of vertices //try randomly drawn pairs of vertices
...@@ -418,7 +418,7 @@ public: ...@@ -418,7 +418,7 @@ public:
continue; continue;
} }
else if (!is_directed::apply<Graph>::type::value && self_loops) else if (!graph_tool::is_directed(_g) && self_loops)
{ {
// sample self-loops w/ correct probability for undirected // sample self-loops w/ correct probability for undirected
// graphs // graphs
...@@ -429,7 +429,7 @@ public: ...@@ -429,7 +429,7 @@ public:
break; break;
} }
if (!is_directed::apply<Graph>::type::value && s > t) if (!graph_tool::is_directed(_g) && s > t)
std::swap(s, t); std::swap(s, t);
if (s == e_s && t == e_t) if (s == e_s && t == e_t)
...@@ -540,7 +540,7 @@ public: ...@@ -540,7 +540,7 @@ public:
double a = 0; double a = 0;
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(_g))
{ {
a -= log(2 + (s == t) + (ts == tt)); a -= log(2 + (s == t) + (ts == tt));
a += log(2 + (s == tt) + (ts == t)); a += log(2 + (s == tt) + (ts == t));
...@@ -562,7 +562,7 @@ public: ...@@ -562,7 +562,7 @@ public:
int d = e_d.second; int d = e_d.second;
size_t m = get_count(u, v, _nmap, _g); size_t m = get_count(u, v, _nmap, _g);
a -= lgamma(m + 1) - lgamma((m + 1) + d); a -= lgamma(m + 1) - lgamma((m + 1) + d);
if (!is_directed::apply<Graph>::type::value && u == v) if (!graph_tool::is_directed(_g) && u == v)
a += d * log(2); a += d * log(2);
} }
...@@ -644,7 +644,7 @@ public: ...@@ -644,7 +644,7 @@ public:
{ {
std::uniform_int_distribution<> sample(0, base_t::_edges.size() - 1); std::uniform_int_distribution<> sample(0, base_t::_edges.size() - 1);
pair<size_t, bool> et = make_pair(sample(base_t::_rng), false); pair<size_t, bool> et = make_pair(sample(base_t::_rng), false);
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(_g))
{ {
std::bernoulli_distribution coin(0.5); std::bernoulli_distribution coin(0.5);
et.second = coin(base_t::_rng); et.second = coin(base_t::_rng);
...@@ -700,7 +700,7 @@ public: ...@@ -700,7 +700,7 @@ public:
deg_t tdeg = get_deg(t, _g);; deg_t tdeg = get_deg(t, _g);;
_edges_by_target[tdeg].push_back(make_pair(ei, false)); _edges_by_target[tdeg].push_back(make_pair(ei, false));
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(_g))
{ {
t = source(e, _g); t = source(e, _g);
deg_t tdeg = get_deg(t, _g); deg_t tdeg = get_deg(t, _g);
...@@ -711,7 +711,7 @@ public: ...@@ -711,7 +711,7 @@ public:
pair<size_t,bool> get_target_edge(pair<size_t, bool>& e, bool) pair<size_t,bool> get_target_edge(pair<size_t, bool>& e, bool)
{ {
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(_g))
{ {
std::bernoulli_distribution coin(0.5); std::bernoulli_distribution coin(0.5);
e.second = coin(base_t::_rng); e.second = coin(base_t::_rng);
...@@ -836,7 +836,7 @@ public: ...@@ -836,7 +836,7 @@ public:
pair<size_t, bool> get_target_edge(pair<size_t, bool>& e, bool) pair<size_t, bool> get_target_edge(pair<size_t, bool>& e, bool)
{ {
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(_g))
{ {
std::bernoulli_distribution coin(0.5); std::bernoulli_distribution coin(0.5);
e.second = coin(base_t::_rng); e.second = coin(base_t::_rng);
...@@ -848,7 +848,7 @@ public: ...@@ -848,7 +848,7 @@ public:
std::uniform_int_distribution<> sample(0, base_t::_edges.size() - 1); std::uniform_int_distribution<> sample(0, base_t::_edges.size() - 1);
size_t epi = sample(base_t::_rng); size_t epi = sample(base_t::_rng);
pair<size_t, bool> ep = make_pair(epi, false); pair<size_t, bool> ep = make_pair(epi, false);
if (!is_directed::apply<Graph>::type::value) if (!graph_tool::is_directed(_g))
{ {
// for undirected graphs we must select a random direction // for undirected graphs we must select a random direction
std::bernoulli_distribution coin(0.5); std::bernoulli_distribution coin(0.5);
...@@ -1000,7 +1000,7 @@ public: ...@@ -1000,7 +1000,7 @@ public:
s = uniform_sample(svs, _rng); s = uniform_sample(svs, _rng);
t = uniform_sample(tvs, _rng); t = uniform_sample(tvs, _rng);
if (!is_directed::apply<Graph>::type::value && if (!graph_tool::is_directed(_g) &&
deg.first == deg.second && s != t && self_loops) deg.first == deg.second && s != t && self_loops)
{ {
// sample self-loops w/ correct probability for undirected // sample self-loops w/ correct probability for undirected
......
...@@ -42,7 +42,7 @@ template <bool micro_deg, class Graph, class VProp, class IVec, class FVec, ...@@ -42,7 +42,7 @@ template <bool micro_deg, class Graph, class VProp, class IVec, class FVec,
void gen_sbm(Graph& g, VProp b, IVec& rs, IVec& ss, FVec probs, VDProp in_deg, void gen_sbm(Graph& g, VProp b, IVec& rs, IVec& ss, FVec probs, VDProp in_deg,
VDProp out_deg, bool micro_ers, RNG& rng) VDProp out_deg, bool micro_ers, RNG& rng)
{ {
constexpr bool is_dir = is_directed::apply<Graph>::type::value; constexpr bool is_dir = graph_tool::is_directed(g);
typedef typename std::conditional_t<micro_deg,size_t,double> dtype; typedef typename std::conditional_t<micro_deg,size_t,double> dtype;
vector<vector<size_t>> rvs; vector<vector<size_t>> rvs;
vector<vector<dtype>> v_in_probs, v_out_probs; vector<vector<dtype>> v_in_probs, v_out_probs;
......
...@@ -61,7 +61,7 @@ struct do_edge_endpoint ...@@ -61,7 +61,7 @@ struct do_edge_endpoint
{ {
auto s = v; auto s = v;
auto t = target(e, g); auto t = target(e, g);
if (!is_directed::apply<Graph>::type::value && s > t) if (!graph_tool::is_directed(g) && s > t)
continue; continue;
if (src) if (src)
eprop[e] = prop[s]; eprop[e] = prop[s];
......
...@@ -233,7 +233,7 @@ struct get_edge_dispatch ...@@ -233,7 +233,7 @@ struct get_edge_dispatch
bool all_edges, boost::python::list& es) const bool all_edges, boost::python::list& es) const
{ {
auto gp = retrieve_graph_view<Graph>(gi, g); auto gp = retrieve_graph_view<Graph>(gi, g);
size_t k_t = is_directed::apply<Graph>::type::value ? size_t k_t = graph_tool::is_directed(g) ?
in_degreeS()(t, g) : out_degree(t, g); in_degreeS()(t, g) : out_degree(t, g);
if (out_degree(s, g) <= k_t) if (out_degree(s, g) <= k_t)
{ {
...@@ -251,11 +251,11 @@ struct get_edge_dispatch ...@@ -251,11 +251,11 @@ struct get_edge_dispatch
{ {
for (auto e : in_or_out_edges_range(vertex(t, g), g)) for (auto e : in_or_out_edges_range(vertex(t, g), g))
{ {
auto w = is_directed::apply<Graph>::type::value ? auto w = graph_tool::is_directed(g) ?
source(e, g) : target(e, g); source(e, g) : target(e, g);
if (w == vertex(s, g)) if (w == vertex(s, g))
{ {
if (!is_directed::apply<Graph>::type::value && e.s != s) if (!graph_tool::is_directed(g) && e.s != s)
std::swap(e.s, e.t); std::swap(e.s, e.t);
es.append(PythonEdge<Graph>(gp, e)); es.append(PythonEdge<Graph>(gp, e));
if (!all_edges) if (!all_edges)
......
...@@ -68,6 +68,11 @@ struct is_directed ...@@ -68,6 +68,11 @@ struct is_directed
}; };
}; };
template <class Graph>
constexpr bool is_directed(const Graph&)
{
return is_directed::apply<std::remove_reference_t<Graph>>::type::value;
}
// This will count "by hand" the number of vertices on a graph. Always O(V). // This will count "by hand" the number of vertices on a graph. Always O(V).
struct HardNumVertices struct HardNumVertices
......
...@@ -34,7 +34,7 @@ template <class Edge, class Graph> ...@@ -34,7 +34,7 @@ template <class Edge, class Graph>
inline typename graph_traits<Graph>::vertex_descriptor inline typename graph_traits<Graph>::vertex_descriptor
get_source(const Edge& e, const Graph &g) get_source(const Edge& e, const Graph &g)
{ {