Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Tiago Peixoto
graph-tool
Commits
7067c4fd
Commit
7067c4fd
authored
Jul 23, 2020
by
Tiago Peixoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
global_clustering(): add `ret_counts` parameter
parent
65142f35
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
78 deletions
+73
-78
src/graph/clustering/graph_clustering.cc
src/graph/clustering/graph_clustering.cc
+9
-9
src/graph/clustering/graph_clustering.hh
src/graph/clustering/graph_clustering.hh
+51
-66
src/graph_tool/clustering/__init__.py
src/graph_tool/clustering/__init__.py
+13
-3
No files found.
src/graph/clustering/graph_clustering.cc
View file @
7067c4fd
...
...
@@ -43,17 +43,18 @@ boost::python::tuple global_clustering(GraphInterface& g, boost::any weight)
if
(
weight
.
empty
())
weight
=
weight_map_t
();
double
c
,
c_err
;
boost
::
python
::
tuple
oret
;
run_action
<
graph_tool
::
detail
::
never_directed
>
()
(
g
,
[
&
](
auto
&&
graph
,
auto
&&
a2
)
{
return
get_global_clustering
()
(
std
::
forward
<
decltype
(
graph
)
>
(
graph
),
std
::
forward
<
decltype
(
a2
)
>
(
a2
),
c
,
c_err
);
auto
ret
=
get_global_clustering
(
std
::
forward
<
decltype
(
graph
)
>
(
graph
),
std
::
forward
<
decltype
(
a2
)
>
(
a2
));
oret
=
boost
::
python
::
make_tuple
(
get
<
0
>
(
ret
),
get
<
1
>
(
ret
),
get
<
2
>
(
ret
),
get
<
3
>
(
ret
));
},
weight_props_t
())(
weight
);
return
boost
::
python
::
make_tuple
(
c
,
c_err
)
;
return
oret
;
}
void
local_clustering
(
GraphInterface
&
g
,
boost
::
any
prop
,
boost
::
any
weight
)
...
...
@@ -72,10 +73,9 @@ void local_clustering(GraphInterface& g, boost::any prop, boost::any weight)
(
g
,
[
&
](
auto
&&
graph
,
auto
&&
a2
,
auto
&&
a3
)
{
return
set_clustering_to_property
()
(
std
::
forward
<
decltype
(
graph
)
>
(
graph
),
std
::
forward
<
decltype
(
a2
)
>
(
a2
),
std
::
forward
<
decltype
(
a3
)
>
(
a3
));
set_clustering_to_property
(
std
::
forward
<
decltype
(
graph
)
>
(
graph
),
std
::
forward
<
decltype
(
a2
)
>
(
a2
),
std
::
forward
<
decltype
(
a3
)
>
(
a3
));
},
weight_props_t
(),
writable_vertex_scalar_properties
())(
weight
,
prop
);
}
...
...
src/graph/clustering/graph_clustering.hh
View file @
7067c4fd
...
...
@@ -90,80 +90,65 @@ auto get_triangles(typename graph_traits<Graph>::vertex_descriptor v,
// retrieves the global clustering coefficient
struct
get_global_clustering
template
<
class
Graph
,
class
EWeight
>
auto
get_global_clustering
(
const
Graph
&
g
,
EWeight
eweight
)
{
template
<
class
Graph
,
class
EWeight
>
void
operator
()(
const
Graph
&
g
,
EWeight
eweight
,
double
&
c
,
double
&
c_err
)
const
{
typedef
typename
property_traits
<
EWeight
>::
value_type
val_t
;
val_t
triangles
=
0
,
n
=
0
;
vector
<
val_t
>
mask
(
num_vertices
(
g
),
0
);
vector
<
std
::
pair
<
val_t
,
val_t
>>
ret
(
num_vertices
(
g
));
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask) reduction(+:triangles, n)
parallel_vertex_loop_no_spawn
(
g
,
[
&
](
auto
v
)
{
auto
temp
=
get_triangles
(
v
,
eweight
,
mask
,
g
);
triangles
+=
temp
.
first
;
n
+=
temp
.
second
;
ret
[
v
]
=
temp
;
});
c
=
double
(
triangles
)
/
n
;
// "jackknife" variance
c_err
=
0.0
;
double
cerr
=
0.0
;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:cerr)
parallel_vertex_loop_no_spawn
(
g
,
[
&
](
auto
v
)
{
auto
cl
=
double
(
triangles
-
ret
[
v
].
first
)
/
(
n
-
ret
[
v
].
second
);
cerr
+=
power
(
c
-
cl
,
2
);
});
c_err
=
sqrt
(
cerr
);
}
};
typedef
typename
property_traits
<
EWeight
>::
value_type
val_t
;
val_t
triangles
=
0
,
n
=
0
;
vector
<
val_t
>
mask
(
num_vertices
(
g
),
0
);
vector
<
std
::
pair
<
val_t
,
val_t
>>
ret
(
num_vertices
(
g
));
// sets the local clustering coefficient to a property
struct
set_clustering_to_property
{
template
<
class
Graph
,
class
EWeight
,
class
ClustMap
>
void
operator
()(
const
Graph
&
g
,
EWeight
eweight
,
ClustMap
clust_map
)
const
{
typedef
typename
property_traits
<
EWeight
>::
value_type
val_t
;
vector
<
val_t
>
mask
(
num_vertices
(
g
),
false
);
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask) reduction(+:triangles, n)
parallel_vertex_loop_no_spawn
(
g
,
[
&
](
auto
v
)
{
auto
temp
=
get_triangles
(
v
,
eweight
,
mask
,
g
);
triangles
+=
temp
.
first
;
n
+=
temp
.
second
;
ret
[
v
]
=
temp
;
});
double
c
=
double
(
triangles
)
/
n
;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask)
parallel_vertex_loop_no_spawn
// "jackknife" variance
double
c_err
=
0.0
;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:c_err)
parallel_vertex_loop_no_spawn
(
g
,
[
&
](
auto
v
)
{
auto
triangles
=
get_triangles
(
v
,
eweight
,
mask
,
g
);
double
clustering
=
(
triangles
.
second
>
0
)
?
double
(
triangles
.
first
)
/
triangles
.
second
:
0.0
;
clust_map
[
v
]
=
clustering
;
auto
cl
=
double
(
triangles
-
ret
[
v
].
first
)
/
(
n
-
ret
[
v
].
second
);
c_err
+=
power
(
c
-
cl
,
2
);
});
}
template
<
class
Graph
>
struct
get_undirected_graph
{
typedef
typename
mpl
::
if_
<
std
::
is_convertible
<
typename
graph_traits
<
Graph
>::
directed_category
,
directed_tag
>
,
const
undirected_adaptor
<
Graph
>
,
const
Graph
&
>::
type
type
;
};
};
c_err
=
sqrt
(
c_err
);
return
std
::
make_tuple
(
c
,
c_err
,
triangles
/
3
,
n
);
}
// sets the local clustering coefficient to a property
template
<
class
Graph
,
class
EWeight
,
class
ClustMap
>
void
set_clustering_to_property
(
const
Graph
&
g
,
EWeight
eweight
,
ClustMap
clust_map
)
{
typedef
typename
property_traits
<
EWeight
>::
value_type
val_t
;
vector
<
val_t
>
mask
(
num_vertices
(
g
),
false
);
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask)
parallel_vertex_loop_no_spawn
(
g
,
[
&
](
auto
v
)
{
auto
triangles
=
get_triangles
(
v
,
eweight
,
mask
,
g
);
double
clustering
=
(
triangles
.
second
>
0
)
?
double
(
triangles
.
first
)
/
triangles
.
second
:
0.0
;
clust_map
[
v
]
=
clustering
;
});
}
}
//graph-tool namespace
...
...
src/graph_tool/clustering/__init__.py
View file @
7067c4fd
...
...
@@ -131,7 +131,7 @@ def local_clustering(g, weight=None, prop=None, undirected=True):
return
prop
def
global_clustering
(
g
,
weight
=
None
):
def
global_clustering
(
g
,
weight
=
None
,
ret_counts
=
False
):
r
"""Return the global clustering coefficient.
Parameters
...
...
@@ -140,11 +140,18 @@ def global_clustering(g, weight=None):
Graph to be used.
weight : :class:`~graph_tool.EdgePropertyMap`, optional (default: None)
Edge weights. If omitted, a constant value of 1 will be used.
ret_counts : ``boolean`` (optional, default: ``False``)
If ``True`` the number of triangles and connected triples are also
returned.
Returns
-------
c : tuple of floats
Global clustering coefficient and standard deviation (jacknife method)
Global clustering coefficient and standard deviation (jackknife method)
triangles : `int` (if ``ret_counts is True``)
Number of triangles.
triples : `int` (if ``ret_counts is True``)
Number of connected triples.
See Also
--------
...
...
@@ -192,7 +199,10 @@ def global_clustering(g, weight=None):
if
g
.
is_directed
():
g
=
GraphView
(
g
,
directed
=
False
,
skip_properties
=
True
)
c
=
_gt
.
global_clustering
(
g
.
_Graph__graph
,
_prop
(
"e"
,
g
,
weight
))
return
c
if
ret_counts
:
return
c
[:
2
],
c
[
2
],
c
[
3
]
else
:
return
c
[:
2
]
def
extended_clustering
(
g
,
props
=
None
,
max_depth
=
3
,
undirected
=
False
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment