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
83186f00
Commit
83186f00
authored
Sep 06, 2015
by
Tiago Peixoto
Browse files
Implement support for edge properties in Graph.add_edge_list()
parent
2bc9ddf4
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/graph/graph_properties.hh
View file @
83186f00
...
...
@@ -429,9 +429,9 @@ private:
virtual
void
put
(
const
Key
&
k
,
const
Value
&
val
)
{
return
put_dispatch
(
_pmap
,
k
,
_c_put
(
val
),
is_convertible
<
typename
boost
::
property_traits
<
PropertyMap
>::
category
,
boost
::
writable_property_map_tag
>
());
put_dispatch
(
_pmap
,
k
,
_c_put
(
val
),
is_convertible
<
typename
boost
::
property_traits
<
PropertyMap
>::
category
,
boost
::
writable_property_map_tag
>
());
}
template
<
class
PMap
>
...
...
src/graph/graph_python_interface.cc
View file @
83186f00
...
...
@@ -387,17 +387,21 @@ template <class ValueList>
struct
add_edge_list
{
template
<
class
Graph
>
void
operator
()(
Graph
&
g
,
python
::
object
aedge_list
,
bool
&
found
)
const
void
operator
()(
Graph
&
g
,
python
::
object
aedge_list
,
python
::
object
&
eprops
,
bool
&
found
)
const
{
boost
::
mpl
::
for_each
<
ValueList
>
(
std
::
bind
(
dispatch
(),
std
::
ref
(
g
),
std
::
ref
(
aedge_list
),
std
::
ref
(
found
),
placeholders
::
_1
));
std
::
ref
(
eprops
),
std
::
ref
(
found
),
placeholders
::
_1
));
}
struct
dispatch
{
template
<
class
Graph
,
class
Value
>
void
operator
()(
Graph
&
g
,
python
::
object
&
aedge_list
,
bool
&
found
,
Value
)
const
void
operator
()(
Graph
&
g
,
python
::
object
&
aedge_list
,
python
::
object
&
oeprops
,
bool
&
found
,
Value
)
const
{
if
(
found
)
return
;
...
...
@@ -408,13 +412,31 @@ struct add_edge_list
if
(
edge_list
.
shape
()[
1
]
<
2
)
throw
GraphException
(
"Second dimension in edge list must be of size (at least) two"
);
typedef
typename
graph_traits
<
Graph
>::
edge_descriptor
edge_t
;
vector
<
DynamicPropertyMapWrap
<
Value
,
edge_t
>>
eprops
;
python
::
stl_input_iterator
<
boost
::
any
>
iter
(
oeprops
),
end
;
for
(;
iter
!=
end
;
++
iter
)
eprops
.
emplace_back
(
*
iter
,
writable_edge_properties
());
for
(
const
auto
&
e
:
edge_list
)
{
size_t
s
=
e
[
0
];
size_t
t
=
e
[
1
];
while
(
s
>=
num_vertices
(
g
)
||
t
>=
num_vertices
(
g
))
add_vertex
(
g
);
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
);
auto
ne
=
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
).
first
;
for
(
size_t
i
=
0
;
i
<
e
.
size
()
-
2
;
++
i
)
{
try
{
put
(
eprops
[
i
],
ne
,
e
[
i
+
2
]);
}
catch
(
bad_lexical_cast
&
)
{
throw
ValueException
(
"Invalid edge property value: "
+
lexical_cast
<
string
>
(
e
[
i
+
2
]));
}
}
}
found
=
true
;
}
...
...
@@ -423,13 +445,15 @@ struct add_edge_list
};
};
void
do_add_edge_list
(
GraphInterface
&
gi
,
python
::
object
aedge_list
)
void
do_add_edge_list
(
GraphInterface
&
gi
,
python
::
object
aedge_list
,
python
::
object
eprops
)
{
typedef
mpl
::
vector
<
bool
,
char
,
uint8_t
,
uint16_t
,
uint32_t
,
uint64_t
,
int8_t
,
int16_t
,
int32_t
,
int64_t
,
uint64_t
,
double
,
long
double
>
vals_t
;
bool
found
=
false
;
run_action
<>
()(
gi
,
std
::
bind
(
add_edge_list
<
vals_t
>
(),
placeholders
::
_1
,
aedge_list
,
run_action
<>
()(
gi
,
std
::
bind
(
add_edge_list
<
vals_t
>
(),
placeholders
::
_1
,
aedge_list
,
std
::
ref
(
eprops
),
std
::
ref
(
found
)))();
if
(
!
found
)
throw
GraphException
(
"Invalid type for edge list; must be two-dimensional with a scalar type"
);
...
...
@@ -440,17 +464,18 @@ struct add_edge_list_hash
{
template
<
class
Graph
,
class
VProp
>
void
operator
()(
Graph
&
g
,
python
::
object
aedge_list
,
VProp
vmap
,
bool
&
found
,
bool
use_str
)
const
bool
&
found
,
bool
use_str
,
python
::
object
&
eprops
)
const
{
boost
::
mpl
::
for_each
<
ValueList
>
(
std
::
bind
(
dispatch
(),
std
::
ref
(
g
),
std
::
ref
(
aedge_list
),
std
::
ref
(
vmap
),
std
::
ref
(
found
),
placeholders
::
_1
));
std
::
ref
(
found
),
std
::
ref
(
eprops
),
placeholders
::
_1
));
if
(
!
found
)
{
if
(
use_str
)
dispatch
()(
g
,
aedge_list
,
vmap
,
found
,
std
::
string
());
dispatch
()(
g
,
aedge_list
,
vmap
,
found
,
eprops
,
std
::
string
());
else
dispatch
()(
g
,
aedge_list
,
vmap
,
found
,
python
::
object
());
dispatch
()(
g
,
aedge_list
,
vmap
,
found
,
eprops
,
python
::
object
());
}
}
...
...
@@ -458,7 +483,7 @@ struct add_edge_list_hash
{
template
<
class
Graph
,
class
VProp
,
class
Value
>
void
operator
()(
Graph
&
g
,
python
::
object
&
aedge_list
,
VProp
&
vmap
,
bool
&
found
,
Value
)
const
bool
&
found
,
python
::
object
&
oeprops
,
Value
)
const
{
if
(
found
)
return
;
...
...
@@ -470,6 +495,11 @@ struct add_edge_list_hash
if
(
edge_list
.
shape
()[
1
]
<
2
)
throw
GraphException
(
"Second dimension in edge list must be of size (at least) two"
);
typedef
typename
graph_traits
<
Graph
>::
edge_descriptor
edge_t
;
vector
<
DynamicPropertyMapWrap
<
Value
,
edge_t
>>
eprops
;
python
::
stl_input_iterator
<
boost
::
any
>
iter
(
oeprops
),
end
;
for
(;
iter
!=
end
;
++
iter
)
eprops
.
emplace_back
(
*
iter
,
writable_edge_properties
());
auto
get_vertex
=
[
&
]
(
const
Value
&
r
)
->
size_t
{
...
...
@@ -488,7 +518,19 @@ struct add_edge_list_hash
{
size_t
s
=
get_vertex
(
e
[
0
]);
size_t
t
=
get_vertex
(
e
[
1
]);
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
);
auto
ne
=
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
).
first
;
for
(
size_t
i
=
0
;
i
<
e
.
size
()
-
2
;
++
i
)
{
try
{
put
(
eprops
[
i
],
ne
,
e
[
i
+
2
]);
}
catch
(
bad_lexical_cast
&
)
{
throw
ValueException
(
"Invalid edge property value: "
+
lexical_cast
<
string
>
(
e
[
i
+
2
]));
}
}
}
found
=
true
;
}
...
...
@@ -497,7 +539,7 @@ struct add_edge_list_hash
template
<
class
Graph
,
class
VProp
>
void
operator
()(
Graph
&
g
,
python
::
object
&
edge_list
,
VProp
&
vmap
,
bool
&
found
,
std
::
string
)
const
bool
&
found
,
python
::
object
&
oeprops
,
std
::
string
)
const
{
if
(
found
)
return
;
...
...
@@ -505,6 +547,12 @@ struct add_edge_list_hash
{
unordered_map
<
std
::
string
,
size_t
>
vertices
;
typedef
typename
graph_traits
<
Graph
>::
edge_descriptor
edge_t
;
vector
<
DynamicPropertyMapWrap
<
python
::
object
,
edge_t
>>
eprops
;
python
::
stl_input_iterator
<
boost
::
any
>
piter
(
oeprops
),
pend
;
for
(;
piter
!=
pend
;
++
piter
)
eprops
.
emplace_back
(
*
piter
,
writable_edge_properties
());
auto
get_vertex
=
[
&
]
(
const
std
::
string
&
r
)
->
size_t
{
auto
iter
=
vertices
.
find
(
r
);
...
...
@@ -521,10 +569,46 @@ struct add_edge_list_hash
python
::
stl_input_iterator
<
python
::
object
>
iter
(
edge_list
),
end
;
for
(;
iter
!=
end
;
++
iter
)
{
const
auto
&
e
=
*
iter
;
size_t
s
=
get_vertex
(
python
::
extract
<
std
::
string
>
(
e
[
0
]));
size_t
t
=
get_vertex
(
python
::
extract
<
std
::
string
>
(
e
[
1
]));
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
);
const
auto
&
row
=
*
iter
;
python
::
stl_input_iterator
<
python
::
object
>
eiter
(
row
),
eend
;
size_t
s
=
0
;
size_t
t
=
0
;
typename
graph_traits
<
Graph
>::
edge_descriptor
e
;
size_t
i
=
0
;
for
(;
eiter
!=
eend
;
++
eiter
)
{
if
(
i
>=
eprops
.
size
()
+
2
)
break
;
const
auto
&
val
=
*
eiter
;
switch
(
i
)
{
case
0
:
s
=
get_vertex
(
python
::
extract
<
std
::
string
>
(
val
));
while
(
s
>=
num_vertices
(
g
))
add_vertex
(
g
);
break
;
case
1
:
t
=
get_vertex
(
python
::
extract
<
std
::
string
>
(
val
));
while
(
t
>=
num_vertices
(
g
))
add_vertex
(
g
);
e
=
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
).
first
;
break
;
default:
try
{
put
(
eprops
[
i
-
2
],
e
,
val
);
}
catch
(
bad_lexical_cast
&
)
{
throw
ValueException
(
"Invalid edge property value: "
+
python
::
extract
<
string
>
(
python
::
str
(
val
))());
}
}
i
++
;
}
}
found
=
true
;
}
...
...
@@ -533,7 +617,7 @@ struct add_edge_list_hash
template
<
class
Graph
,
class
VProp
>
void
operator
()(
Graph
&
g
,
python
::
object
&
edge_list
,
VProp
&
vmap
,
bool
&
found
,
python
::
object
)
const
bool
&
found
,
python
::
object
&
oeprops
,
python
::
object
)
const
{
if
(
found
)
return
;
...
...
@@ -541,6 +625,12 @@ struct add_edge_list_hash
{
unordered_map
<
python
::
object
,
size_t
>
vertices
;
typedef
typename
graph_traits
<
Graph
>::
edge_descriptor
edge_t
;
vector
<
DynamicPropertyMapWrap
<
python
::
object
,
edge_t
>>
eprops
;
python
::
stl_input_iterator
<
boost
::
any
>
piter
(
oeprops
),
pend
;
for
(;
piter
!=
pend
;
++
piter
)
eprops
.
emplace_back
(
*
piter
,
writable_edge_properties
());
auto
get_vertex
=
[
&
]
(
const
python
::
object
&
r
)
->
size_t
{
auto
iter
=
vertices
.
find
(
r
);
...
...
@@ -557,10 +647,46 @@ struct add_edge_list_hash
python
::
stl_input_iterator
<
python
::
object
>
iter
(
edge_list
),
end
;
for
(;
iter
!=
end
;
++
iter
)
{
const
auto
&
e
=
*
iter
;
size_t
s
=
get_vertex
(
e
[
0
]);
size_t
t
=
get_vertex
(
e
[
1
]);
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
);
const
auto
&
row
=
*
iter
;
python
::
stl_input_iterator
<
python
::
object
>
eiter
(
row
),
eend
;
size_t
s
=
0
;
size_t
t
=
0
;
typename
graph_traits
<
Graph
>::
edge_descriptor
e
;
size_t
i
=
0
;
for
(;
eiter
!=
eend
;
++
eiter
)
{
if
(
i
>=
eprops
.
size
()
+
2
)
break
;
const
auto
&
val
=
*
eiter
;
switch
(
i
)
{
case
0
:
s
=
get_vertex
(
val
);
while
(
s
>=
num_vertices
(
g
))
add_vertex
(
g
);
break
;
case
1
:
t
=
get_vertex
(
val
);
while
(
t
>=
num_vertices
(
g
))
add_vertex
(
g
);
e
=
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
).
first
;
break
;
default:
try
{
put
(
eprops
[
i
-
2
],
e
,
val
);
}
catch
(
bad_lexical_cast
&
)
{
throw
ValueException
(
"Invalid edge property value: "
+
python
::
extract
<
string
>
(
python
::
str
(
val
))());
}
}
i
++
;
}
}
found
=
true
;
}
...
...
@@ -570,7 +696,8 @@ struct add_edge_list_hash
};
void
do_add_edge_list_hashed
(
GraphInterface
&
gi
,
python
::
object
aedge_list
,
boost
::
any
&
vertex_map
,
bool
is_str
)
boost
::
any
&
vertex_map
,
bool
is_str
,
python
::
object
eprops
)
{
typedef
mpl
::
vector
<
bool
,
char
,
uint8_t
,
uint16_t
,
uint32_t
,
uint64_t
,
int8_t
,
int16_t
,
int32_t
,
int64_t
,
uint64_t
,
double
,
...
...
@@ -579,10 +706,75 @@ void do_add_edge_list_hashed(GraphInterface& gi, python::object aedge_list,
run_action
<
graph_tool
::
detail
::
all_graph_views
,
boost
::
mpl
::
true_
>
()
(
gi
,
std
::
bind
(
add_edge_list_hash
<
vals_t
>
(),
placeholders
::
_1
,
aedge_list
,
placeholders
::
_2
,
std
::
ref
(
found
),
is_str
),
is_str
,
std
::
ref
(
eprops
)
),
writable_vertex_properties
())(
vertex_map
);
if
(
!
found
)
throw
GraphException
(
"Invalid type for edge list; must be two-dimensional with a scalar or string type"
);
}
struct
add_edge_list_iter
{
template
<
class
Graph
>
void
operator
()(
Graph
&
g
,
python
::
object
&
edge_list
,
python
::
object
&
oeprops
)
const
{
typedef
typename
graph_traits
<
Graph
>::
edge_descriptor
edge_t
;
vector
<
DynamicPropertyMapWrap
<
python
::
object
,
edge_t
>>
eprops
;
python
::
stl_input_iterator
<
boost
::
any
>
piter
(
oeprops
),
pend
;
for
(;
piter
!=
pend
;
++
piter
)
eprops
.
emplace_back
(
*
piter
,
writable_edge_properties
());
python
::
stl_input_iterator
<
python
::
object
>
iter
(
edge_list
),
end
;
for
(;
iter
!=
end
;
++
iter
)
{
const
auto
&
row
=
*
iter
;
python
::
stl_input_iterator
<
python
::
object
>
eiter
(
row
),
eend
;
size_t
s
=
0
;
size_t
t
=
0
;
typename
graph_traits
<
Graph
>::
edge_descriptor
e
;
size_t
i
=
0
;
for
(;
eiter
!=
eend
;
++
eiter
)
{
if
(
i
>=
eprops
.
size
()
+
2
)
break
;
const
auto
&
val
=
*
eiter
;
switch
(
i
)
{
case
0
:
s
=
python
::
extract
<
size_t
>
(
val
);
while
(
s
>=
num_vertices
(
g
))
add_vertex
(
g
);
break
;
case
1
:
t
=
python
::
extract
<
size_t
>
(
val
);
while
(
t
>=
num_vertices
(
g
))
add_vertex
(
g
);
e
=
add_edge
(
vertex
(
s
,
g
),
vertex
(
t
,
g
),
g
).
first
;
break
;
default:
try
{
put
(
eprops
[
i
-
2
],
e
,
val
);
}
catch
(
bad_lexical_cast
&
)
{
throw
ValueException
(
"Invalid edge property value: "
+
python
::
extract
<
string
>
(
python
::
str
(
val
))());
}
}
i
++
;
}
}
}
};
void
do_add_edge_list_iter
(
GraphInterface
&
gi
,
python
::
object
edge_list
,
python
::
object
eprops
)
{
run_action
<>
()
(
gi
,
std
::
bind
(
add_edge_list_iter
(),
placeholders
::
_1
,
std
::
ref
(
edge_list
),
std
::
ref
(
eprops
)))();
}
...
...
@@ -640,6 +832,7 @@ void export_python_interface()
def
(
"remove_edge"
,
graph_tool
::
remove_edge
);
def
(
"add_edge_list"
,
graph_tool
::
do_add_edge_list
);
def
(
"add_edge_list_hashed"
,
graph_tool
::
do_add_edge_list_hashed
);
def
(
"add_edge_list_iter"
,
graph_tool
::
do_add_edge_list_iter
);
def
(
"get_edge"
,
get_edge
);
def
(
"get_vertex_index"
,
get_vertex_index
);
...
...
src/graph_tool/__init__.py
View file @
83186f00
...
...
@@ -239,16 +239,20 @@ def _gt_type(obj):
return
"vector<%s>"
%
_gt_type
(
obj
[
0
])
return
"object"
def
_convert
(
prop
,
val
):
def
_converter
(
val_type
):
# attempt to convert to a compatible python type. This is useful,
# for instance, when dealing with numpy types.
vtype
=
_python_type
(
prop
.
val
ue
_type
()
)
vtype
=
_python_type
(
val_type
)
if
type
(
vtype
)
is
tuple
:
return
[
vtype
[
1
](
x
)
for
x
in
val
]
if
vtype
is
object
:
return
val
return
vtype
(
val
)
def
convert
(
val
):
return
[
vtype
[
1
](
x
)
for
x
in
val
]
elif
vtype
is
object
:
def
convert
(
val
):
return
val
else
:
def
convert
(
val
):
return
vtype
(
val
)
return
convert
def
show_config
():
...
...
@@ -421,6 +425,7 @@ class PropertyMap(object):
except
NameError
:
pass
# ignore if GraphView is yet undefined
self
.
__key_type
=
key_type
self
.
__convert
=
_converter
(
self
.
value_type
())
self
.
__register_map
()
def
__key_trans
(
self
,
key
):
...
...
@@ -482,14 +487,14 @@ class PropertyMap(object):
try
:
self
.
__map
[
key
]
=
v
except
TypeError
:
self
.
__map
[
key
]
=
_convert
(
self
,
v
)
self
.
__map
[
key
]
=
self
.
_
_convert
(
v
)
except
ArgumentError
:
try
:
key
=
self
.
__key_convert
(
key
)
try
:
self
.
__map
[
key
]
=
v
except
TypeError
:
self
.
__map
[
key
]
=
_convert
(
self
,
v
)
self
.
__map
[
key
]
=
self
.
_
_convert
(
v
)
except
ArgumentError
:
if
self
.
key_type
()
==
"e"
:
kt
=
"Edge"
...
...
@@ -829,11 +834,11 @@ class PropertyMap(object):
else
:
u
=
GraphView
(
g
,
skip_vfilt
=
True
,
skip_efilt
=
True
)
if
key_type
==
"v"
:
vals
=
[
_convert
(
self
,
self
[
v
])
for
v
in
u
.
vertices
()]
vals
=
[
self
.
_
_convert
(
self
[
v
])
for
v
in
u
.
vertices
()]
elif
key_type
==
"e"
:
vals
=
[
_convert
(
self
,
self
[
e
])
for
e
in
u
.
edges
()]
vals
=
[
self
.
_
_convert
(
self
[
e
])
for
e
in
u
.
edges
()]
else
:
vals
=
_convert
(
self
,
self
[
g
])
vals
=
self
.
_
_convert
(
self
[
g
])
state
=
dict
(
g
=
g
,
value_type
=
value_type
,
key_type
=
key_type
,
vals
=
vals
,
...
...
@@ -1885,9 +1890,10 @@ class Graph(object):
self
.
__check_perms
(
"del_edge"
)
return
libcore
.
remove_edge
(
self
.
__graph
,
edge
)
def
add_edge_list
(
self
,
edge_list
,
hashed
=
False
,
string_vals
=
False
):
def
add_edge_list
(
self
,
edge_list
,
hashed
=
False
,
string_vals
=
False
,
eprops
=
None
):
"""Add a list of edges to the graph, given by ``edge_list``, which can
be a
list
of ``(source, target)`` pairs where both ``source`` and
be a
n iterator
of ``(source, target)`` pairs where both ``source`` and
``target`` are vertex indexes, or a :class:`~numpy.ndarray` of shape
``(E,2)``, where ``E`` is the number of edges, and each line specifies a
``(source, target)`` pair. If the list references vertices which do not
...
...
@@ -1895,17 +1901,33 @@ class Graph(object):
Optionally, if ``hashed == True``, the vertex values in the edge list
are not assumed to correspond to vertex indices directly. In this case
they will be mapped to vertex indices
in
according to the order in which
they will be mapped to vertex indices according to the order in which
they are encountered. In this case, a vertex property map with the
vertex values is returned. If ``string_vals == True``, the algorithm
assumes that the vertex values are strings. Otherwise, they will be
assumed to be numeric if ``edge_list`` is a :class:`~numpy.ndarray`, or
arbitrary python objects if it is not.
If given, `eprops` specifies edge property maps that will be filled with
the remaining values at each row, if there are more than two.
"""
self
.
__check_perms
(
"add_edge"
)
if
eprops
is
None
:
eprops
=
()
else
:
convert
=
[
_converter
(
x
.
value_type
())
for
x
in
eprops
]
eprops
=
[
_prop
(
"e"
,
self
,
x
)
for
x
in
eprops
]
if
not
isinstance
(
edge_list
,
numpy
.
ndarray
):
def
wrap
(
elist
):
for
row
in
elist
:
yield
(
val
if
i
<
2
else
convert
[
i
-
2
](
val
)
for
(
i
,
val
)
in
enumerate
(
row
))
edge_list
=
wrap
(
edge_list
)
if
not
hashed
:
edges
=
numpy
.
asarray
(
edge_list
)
libcore
.
add_edge_list
(
self
.
__graph
,
edges
)
if
isinstance
(
edge_list
,
numpy
.
ndarray
):
libcore
.
add_edge_list
(
self
.
__graph
,
edge_list
,
eprops
)
else
:
libcore
.
add_edge_list_iter
(
self
.
__graph
,
edge_list
,
eprops
)
else
:
if
isinstance
(
edge_list
,
numpy
.
ndarray
):
vprop
=
self
.
new_vertex_property
(
_gt_type
(
edge_list
.
dtype
))
...
...
@@ -1915,7 +1937,7 @@ class Graph(object):
vprop
=
self
.
new_vertex_property
(
"object"
)
libcore
.
add_edge_list_hashed
(
self
.
__graph
,
edge_list
,
_prop
(
"v"
,
self
,
vprop
),
string_vals
)
string_vals
,
eprops
)
return
vprop
def
set_fast_edge_removal
(
self
,
fast
=
True
):
...
...
src/graph_tool/util/__init__.py
View file @
83186f00
...
...
@@ -42,7 +42,7 @@ from __future__ import division, absolute_import, print_function
from
..
dl_import
import
dl_import
dl_import
(
"from . import libgraph_tool_util"
)
from
..
import
_degree
,
_prop
,
_convert
from
..
import
_degree
,
_prop
,
_convert
er
import
weakref
__all__
=
[
"find_vertex"
,
"find_vertex_range"
,
"find_edge"
,
"find_edge_range"
]
...
...
@@ -52,7 +52,7 @@ def find_vertex(g, prop, match):
"""Find all vertices `v` for which `prop[v] = match`. The parameter prop
can be either a :class:`~graph_tool.PropertyMap` or string with value "in",
"out" or "total", representing a degree type."""
val
=
_convert
(
prop
,
match
)
val
=
_convert
er
(
prop
.
value_type
())(
match
)
ret
=
libgraph_tool_util
.
\
find_vertex_range
(
weakref
.
ref
(
g
),
_degree
(
g
,
prop
),
(
val
,
val
))
...
...
@@ -72,7 +72,7 @@ def find_vertex_range(g, prop, range):
def
find_edge
(
g
,
prop
,
match
):
"""Find all edges `e` for which `prop[e] = match`. The parameter prop
must be a :class:`~graph_tool.PropertyMap`."""
val
=
_convert
(
prop
,
match
)
val
=
_convert
er
(
prop
.
value_type
())(
match
)
ret
=
libgraph_tool_util
.
\
find_edge_range
(
weakref
.
ref
(
g
),
_prop
(
"e"
,
g
,
prop
),
(
val
,
val
))
...
...
@@ -82,7 +82,8 @@ def find_edge(g, prop, match):
def
find_edge_range
(
g
,
prop
,
range
):
"""Find all edges `e` for which `range[0] <= prop[e] <= range[1]`. The
parameter prop can be either a :class:`~graph_tool.PropertyMap`."""
convert
=
converter
(
prop
.
value_type
())
ret
=
libgraph_tool_util
.
\
find_edge_range
(
weakref
.
ref
(
g
),
_prop
(
"e"
,
g
,
prop
),
(
_
convert
(
prop
,
range
[
0
]),
_
convert
(
prop
,
range
[
1
])))
(
convert
(
range
[
0
]),
convert
(
range
[
1
])))
return
ret
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