Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tiago Peixoto
graph-tool
Commits
7a401052
Commit
7a401052
authored
Jul 02, 2013
by
Tiago Peixoto
Browse files
Implement weighted degree property maps and weighted degree selectors
parent
0c4b511c
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/graph/graph.hh
View file @
7a401052
...
...
@@ -111,7 +111,7 @@ public:
//
// python interface
//
python
::
object
DegreeMap
(
string
deg
)
const
;
python
::
object
DegreeMap
(
string
deg
,
boost
::
any
weight
)
const
;
// used for graph properties
graph_property_tag
GetDescriptor
()
const
{
return
graph_property_tag
();
}
...
...
src/graph/graph_bind.cc
View file @
7a401052
...
...
@@ -366,7 +366,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
mpl
::
for_each
<
mpl
::
push_back
<
scalar_types
,
string
>::
type
>
(
export_vector_types
());
class_
<
GraphInterface
>
(
"GraphInterface"
,
init
<>
())
.
def
(
init
<
GraphInterface
,
bool
,
python
::
object
,
python
::
object
>
())
.
def
(
init
<
GraphInterface
,
bool
,
python
::
object
,
python
::
object
,
python
::
object
>
())
.
def
(
"GetNumberOfVertices"
,
&
GraphInterface
::
GetNumberOfVertices
)
.
def
(
"GetNumberOfEdges"
,
&
GraphInterface
::
GetNumberOfEdges
)
.
def
(
"SetDirected"
,
&
GraphInterface
::
SetDirected
)
...
...
@@ -445,4 +445,3 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def
(
"get_graph_type"
,
&
get_graph_type
);
}
src/graph/graph_copy.cc
View file @
7a401052
...
...
@@ -158,6 +158,7 @@ GraphInterface::GraphInterface(const GraphInterface& gi, bool keep_ref,
ref
(
python
::
extract
<
boost
::
any
&>
(
oeprops
[
i
][
1
])())));
}
boost
::
any
avorder
=
python
::
extract
<
boost
::
any
>
(
vorder
);
run_action
<>
()
(
const_cast
<
GraphInterface
&>
(
gi
),
bind
<
void
>
(
do_graph_copy
(),
_1
,
ref
(
*
_mg
),
...
...
src/graph/graph_python_interface.cc
View file @
7a401052
...
...
@@ -230,9 +230,19 @@ void remove_edge(GraphInterface& gi, const python::object& e)
struct
get_degree_map
{
template
<
class
Graph
,
class
Deg
reeMap
,
class
DegS
>
void
operator
()(
const
Graph
&
g
,
DegreeMap
deg_map
,
DegS
deg
)
const
template
<
class
Graph
,
class
Deg
S
,
class
Weight
>
void
operator
()(
const
Graph
&
g
,
python
::
object
&
o
deg_map
,
DegS
deg
,
Weight
weight
)
const
{
typedef
typename
detail
::
get_weight_type
<
Weight
>::
type
weight_t
;
typedef
typename
mpl
::
if_
<
is_same
<
weight_t
,
size_t
>
,
int32_t
,
weight_t
>::
type
deg_t
;
typedef
typename
property_map_type
::
apply
<
deg_t
,
GraphInterface
::
vertex_index_map_t
>::
type
map_t
;
map_t
cdeg_map
(
get
(
vertex_index
,
g
));
typename
map_t
::
unchecked_t
deg_map
=
cdeg_map
.
get_unchecked
(
num_vertices
(
g
));
int
i
,
N
=
num_vertices
(
g
);
#pragma omp parallel for default(shared) private(i) schedule(dynamic)
for
(
i
=
0
;
i
<
N
;
++
i
)
...
...
@@ -240,33 +250,39 @@ struct get_degree_map
typename
graph_traits
<
Graph
>::
vertex_descriptor
v
=
vertex
(
i
,
g
);
if
(
v
==
graph_traits
<
Graph
>::
null_vertex
())
continue
;
deg_map
[
v
]
=
deg
(
v
,
g
);
deg_map
[
v
]
=
deg
(
v
,
g
,
weight
);
}
odeg_map
=
python
::
object
(
PythonPropertyMap
<
map_t
>
(
cdeg_map
));
}
};
python
::
object
GraphInterface
::
DegreeMap
(
string
deg
)
const
python
::
object
GraphInterface
::
DegreeMap
(
string
deg
,
boost
::
any
weight
)
const
{
typedef
property_map_type
::
apply
<
double
,
GraphInterface
::
vertex_index_map_t
>::
type
map_t
;
map_t
deg_map
(
_vertex_index
);
deg_map
.
reserve
(
num_vertices
(
*
_mg
));
python
::
object
deg_map
;
typedef
typename
mpl
::
push_back
<
edge_scalar_properties
,
detail
::
no_weightS
>::
type
weight_t
;
if
(
weight
.
empty
())
weight
=
detail
::
no_weightS
();
if
(
deg
==
"in"
)
run_action
<>
()(
const_cast
<
GraphInterface
&>
(
*
this
),
bind
<
void
>
(
get_degree_map
(),
_1
,
deg_map
,
in_degreeS
()))();
ref
(
deg_map
),
in_degreeS
(),
_2
),
weight_t
())
(
weight
);
else
if
(
deg
==
"out"
)
run_action
<>
()(
const_cast
<
GraphInterface
&>
(
*
this
),
bind
<
void
>
(
get_degree_map
(),
_1
,
deg_map
,
out_degreeS
()))();
ref
(
deg_map
),
out_degreeS
(),
_2
),
weight_t
())
(
weight
);
else
if
(
deg
==
"total"
)
run_action
<>
()(
const_cast
<
GraphInterface
&>
(
*
this
),
bind
<
void
>
(
get_degree_map
(),
_1
,
deg_map
,
total_degreeS
()))();
return
python
::
object
(
PythonPropertyMap
<
map_t
>
(
deg_map
));
ref
(
deg_map
),
total_degreeS
(),
_2
),
weight_t
())
(
weight
);
return
deg_map
;
}
//
...
...
src/graph/graph_selectors.hh
View file @
7a401052
...
...
@@ -42,78 +42,154 @@ namespace graph_tool
// This file also contains selectors for in_edge iterators of graphs, which
// return an empty range for undirected graphs
struct
total_degreeS
namespace
detail
{
struct
no_weightS
{};
template
<
class
Weight
>
struct
get_weight_type
{
typedef
typename
property_traits
<
Weight
>::
value_type
type
;
};
template
<
>
struct
get_weight_type
<
no_weightS
>
{
typedef
size_t
type
;
};
}
struct
in_degreeS
{
typedef
size_t
value_type
;
total_degreeS
()
{}
in_degreeS
()
{}
template
<
class
Graph
,
class
Vertex
>
size_t
operator
()(
const
Vertex
&
v
,
const
Graph
&
g
)
const
{
return
in_degreeS
::
operator
()(
v
,
g
,
detail
::
no_weightS
());
}
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
operator
()(
const
Vertex
&
v
,
const
Graph
&
g
,
Weight
weight
)
const
{
using
namespace
boost
;
typedef
typename
is_convertible
<
typename
graph_traits
<
Graph
>::
directed_category
,
directed_tag
>::
type
is_directed
;
return
get_
total
_degree
(
v
,
g
,
is_directed
());
return
get_
in
_degree
(
v
,
g
,
is_directed
()
,
weight
);
}
template
<
class
Graph
,
class
Vertex
>
size_t
get_total_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
true_type
)
size_t
get_in_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
true_type
,
detail
::
no_weightS
)
const
{
return
in_degree
(
v
,
g
)
+
out_degree
(
v
,
g
);
return
in_degree
(
v
,
g
);
}
template
<
class
Graph
,
class
Vertex
>
size_t
get_total_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
false_type
)
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
get_in_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
true_type
,
Weight
weight
)
const
{
typename
property_traits
<
Weight
>::
value_type
d
=
0
;
typename
graph_traits
<
Graph
>::
in_edge_iterator
e
,
e_end
;
for
(
tie
(
e
,
e_end
)
=
in_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
d
+=
get
(
weight
,
*
e
);
return
d
;
}
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
size_t
get_in_degree
(
const
Vertex
&
,
const
Graph
&
,
boost
::
false_type
,
Weight
)
const
{
return
out_degree
(
v
,
g
)
;
return
0
;
}
};
struct
in
_degreeS
struct
out
_degreeS
{
typedef
size_t
value_type
;
in_degreeS
()
{}
out_degreeS
()
{}
template
<
class
Graph
,
class
Vertex
>
size_t
operator
()(
const
Vertex
&
v
,
const
Graph
&
g
)
const
{
using
namespace
boost
;
typedef
typename
is_convertible
<
typename
graph_traits
<
Graph
>::
directed_category
,
directed_tag
>::
type
is_directed
;
return
get_in_degree
(
v
,
g
,
is_directed
());
return
out_degreeS
::
operator
()(
v
,
g
,
detail
::
no_weightS
());
}
template
<
class
Graph
,
class
Vertex
>
size_t
get_in_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
true_type
)
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
operator
()(
const
Vertex
&
v
,
const
Graph
&
g
,
Weight
weight
)
const
{
return
get_out_degree
(
v
,
g
,
weight
);
}
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
get_out_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
Weight
weight
)
const
{
return
in_degree
(
v
,
g
);
typename
property_traits
<
Weight
>::
value_type
d
=
0
;
typename
graph_traits
<
Graph
>::
out_edge_iterator
e
,
e_end
;
for
(
tie
(
e
,
e_end
)
=
out_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
d
+=
get
(
weight
,
*
e
);
return
d
;
}
template
<
class
Graph
,
class
Vertex
>
size_t
get_
in
_degree
(
const
Vertex
&
,
const
Graph
&
,
boost
::
false_type
)
size_t
get_
out
_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
detail
::
no_weightS
)
const
{
return
0
;
return
out_degree
(
v
,
g
)
;
}
};
struct
out
_degreeS
struct
total
_degreeS
{
typedef
size_t
value_type
;
out
_degreeS
()
{}
total
_degreeS
()
{}
template
<
class
Graph
,
class
Vertex
>
size_t
operator
()(
const
Vertex
&
v
,
const
Graph
&
g
)
const
{
return
out_degree
(
v
,
g
);
return
total_degreeS
::
operator
()(
v
,
g
,
detail
::
no_weightS
());
}
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
operator
()(
const
Vertex
&
v
,
const
Graph
&
g
,
Weight
weight
)
const
{
using
namespace
boost
;
typedef
typename
is_convertible
<
typename
graph_traits
<
Graph
>::
directed_category
,
directed_tag
>::
type
is_directed
;
return
get_total_degree
(
v
,
g
,
is_directed
(),
weight
);
}
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
get_total_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
true_type
,
Weight
weight
)
const
{
return
in_degreeS
()(
v
,
g
,
weight
)
+
out_degreeS
()(
v
,
g
,
weight
);
}
template
<
class
Graph
,
class
Vertex
,
class
Weight
>
typename
detail
::
get_weight_type
<
Weight
>::
type
get_total_degree
(
const
Vertex
&
v
,
const
Graph
&
g
,
boost
::
false_type
,
Weight
weight
)
const
{
return
out_degreeS
()(
v
,
g
,
weight
);
}
};
template
<
class
PropertyMap
>
struct
scalarS
{
...
...
src/graph_tool/__init__.py
View file @
7a401052
...
...
@@ -1068,7 +1068,8 @@ class Graph(object):
vorder
.
fa
=
numpy
.
arange
(
g
.
num_vertices
())
# The actual copying of the graph and property maps
self
.
__graph
=
libcore
.
GraphInterface
(
g
.
__graph
,
False
,
vprops
,
eprops
)
self
.
__graph
=
libcore
.
GraphInterface
(
g
.
__graph
,
False
,
vprops
,
eprops
,
_prop
(
"v"
,
g
,
vorder
))
# Put the copied properties in the internal dictionary
for
k
,
v
in
g
.
vertex_properties
.
items
():
...
...
@@ -1583,10 +1584,13 @@ class Graph(object):
# degree property map
@
_limit_args
({
"deg"
:
[
"in"
,
"out"
,
"total"
]})
def
degree_property_map
(
self
,
deg
):
def
degree_property_map
(
self
,
deg
,
weight
=
None
):
"""Create and return a vertex property map containing the degree type
given by ``deg``."""
return
PropertyMap
(
self
.
__graph
.
DegreeMap
(
deg
),
self
,
"v"
)
given by ``deg``. If provided, ``weight`` should be an edge
:class:`~graph_tool.PropertyMap` containing the edge weights which
should be summed."""
pmap
=
self
.
__graph
.
DegreeMap
(
deg
,
_prop
(
"e"
,
self
,
weight
))
return
PropertyMap
(
pmap
,
self
,
"v"
)
# I/O operations
# ==============
...
...
@@ -2097,7 +2101,8 @@ class GraphView(Graph):
Graph
.
__init__
(
self
)
# copy graph reference
self
.
_Graph__graph
=
libcore
.
GraphInterface
(
g
.
_Graph__graph
,
True
,
[],
[])
[],
[],
_prop
(
"v"
,
g
,
g
.
vertex_index
))
for
k
,
v
in
g
.
properties
.
items
():
self
.
properties
[
k
]
=
self
.
own_property
(
v
)
...
...
Write
Preview
Supports
Markdown
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