1
#ifndef YASMIC_UNDIR_SIMPLE_CSR_MATRIX_AS_GRAPH_HPP
2
#define YASMIC_UNDIR_SIMPLE_CSR_MATRIX_AS_GRAPH_HPP
4
/** @file undir_simple_csr_matrix.hpp
5
* @author David F. Gleich
6
* @copyright Stanford University, 2008
7
* An almost exact copy of simple_csr_matrix_as_graph.hpp but with
11
* 2008-09-26: Initial coding
14
#include <yasmic/simple_csr_matrix_as_graph.hpp>
15
#include <yasmic/undir_simple_csr_matrix.hpp>
16
#include <boost/graph/graph_traits.hpp>
17
#include <boost/graph/properties.hpp>
18
#include <boost/integer.hpp>
19
#include <boost/iterator/iterator_facade.hpp>
20
#include <boost/mpl/if.hpp>
21
#include <boost/type_traits/is_unsigned.hpp>
22
#include <boost/integer.hpp>
23
#include <yasmic/boost_mod/integer_extra.hpp>
24
#include <boost/iterator/counting_iterator.hpp>
26
#define YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS \
27
typename Index,typename Value,typename EdgeIndex
28
#define YASMIC_SIMPLE_CSR_GRAPH_TYPE \
29
typename yasmic::undir_simple_csr_matrix<Index,Value,EdgeIndex>
33
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
34
class undir_simple_csr_edge_iterator;
35
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
36
class undir_simple_csr_out_edge_iterator;
37
} // end namspase yasmic::impl
38
} // end namespace yasmic
40
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
41
class yasmic::impl::undir_simple_csr_edge_iterator
44
typedef std::forward_iterator_tag iterator_category;
45
typedef yasmic::impl::simple_csr_edge<Index,EdgeIndex> value_type;
47
typedef const value_type* pointer;
49
typedef value_type reference;
50
// required due to "bug" in InputIterator concept, it is unused
51
typedef typename boost::int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type;
53
undir_simple_csr_edge_iterator() : ai(NULL), current_edge(), end_of_this_vertex(0) {}
55
undir_simple_csr_edge_iterator(
56
const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g,
57
value_type current_edge,
58
EdgeIndex end_of_this_vertex)
59
: ai(g.ai), current_edge(current_edge),
60
end_of_this_vertex(end_of_this_vertex) {}
63
reference operator*() const { return current_edge; }
64
pointer operator->() const { return ¤t_edge; }
66
bool operator==(const undir_simple_csr_edge_iterator<Index,Value,EdgeIndex>& o) const {
67
return current_edge == o.current_edge;
69
bool operator!=(const undir_simple_csr_edge_iterator<Index,Value,EdgeIndex>& o) const {
70
return current_edge != o.current_edge;
73
undir_simple_csr_edge_iterator& operator++() {
75
while (current_edge.i == end_of_this_vertex) {
77
end_of_this_vertex = ai[current_edge.r + 1];
82
undir_simple_csr_edge_iterator operator++(int) {
83
undir_simple_csr_edge_iterator temp = *this;
89
value_type current_edge;
90
EdgeIndex end_of_this_vertex;
93
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
94
class yasmic::impl::undir_simple_csr_out_edge_iterator
95
: public boost::iterator_facade<
96
typename yasmic::impl::undir_simple_csr_out_edge_iterator<Index,Value,EdgeIndex>,
97
yasmic::impl::simple_csr_edge<Index,EdgeIndex>,
98
std::random_access_iterator_tag,
99
const typename yasmic::impl::simple_csr_edge<Index,EdgeIndex>&,
100
typename boost::int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast>
103
typedef yasmic::impl::simple_csr_edge<Index,EdgeIndex> edge_descriptor;
106
typedef typename boost::int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast
109
undir_simple_csr_out_edge_iterator() {}
111
// Implicit copy constructor OK
112
explicit undir_simple_csr_out_edge_iterator(edge_descriptor e) : _e(e) { }
115
// iterator_facade requirements
116
const edge_descriptor& dereference() const { return _e; }
118
bool equal(const simple_csr_out_edge_iterator<Index,Value,EdgeIndex>& other) const
119
{ return _e == other._e; }
121
void increment() { ++_e.i; }
122
void decrement() { ++_e.i; }
123
void advance(difference_type n) { _e.i += n; }
125
difference_type distance_to(const yasmic::impl::undir_simple_csr_out_edge_iterator<Index,Value,EdgeIndex>& other) const
126
{ return other._e.i - _e.idx; }
130
friend class boost::iterator_core_access;
135
// implement the graph traits
137
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
138
struct graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE> {
139
// requirements for Graph
140
typedef Index vertex_descriptor;
141
typedef yasmic::impl::simple_csr_edge<Index,EdgeIndex> edge_descriptor;
142
typedef undirected_tag directed_category;
143
typedef allow_parallel_edge_tag edge_parallel_category;
144
typedef yasmic::impl::simple_csr_graph_traversal traversal_category;
145
static vertex_descriptor null_vertex()
147
return std::numeric_limits<vertex_descriptor>::max BOOST_PREVENT_MACRO_SUBSTITUTION ();
149
// requirements for VertexListGraph
150
typedef typename yasmic::impl::remove_signedness<Index>::type vertices_size_type;
151
typedef counting_iterator<Index> vertex_iterator;
152
// requirements for EdgeListGraph
153
typedef typename yasmic::impl::remove_signedness<EdgeIndex>::type edges_size_type;
154
typedef yasmic::impl::undir_simple_csr_edge_iterator<Index,Value,EdgeIndex>
156
// requirements for IncidenceGraph
157
typedef edges_size_type degree_size_type;
158
typedef yasmic::impl::undir_simple_csr_out_edge_iterator<Index,Value,EdgeIndex>
160
// requirements for AdjacencyGraph
161
typedef Index* adjacency_iterator;
162
// requirements for various bugs
163
typedef void in_edge_iterator;
166
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
167
struct graph_traits<const YASMIC_SIMPLE_CSR_GRAPH_TYPE>
168
: graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE> {};
171
// implement the requirements for VertexListGraph
173
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
174
inline typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::vertices_size_type
175
num_vertices(const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
178
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
179
inline std::pair<counting_iterator<Index>,counting_iterator<Index> >
180
vertices(const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
181
return std::make_pair(counting_iterator<Index>(0),
182
counting_iterator<Index>(num_vertices(g)));
185
// implement the requirements for EdgeListGraph
187
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
189
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor e,
190
const YASMIC_SIMPLE_CSR_GRAPH_TYPE&)
194
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
196
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor e,
197
const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g)
201
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
202
inline typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edges_size_type
203
num_edges(const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
207
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
208
inline std::pair< typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_iterator,
209
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_iterator >
210
edges(const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
211
typedef typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_iterator ei;
212
typedef typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor e;
214
return std::make_pair(ei(),ei());
218
while (g.ai[r] == g.ai[r+1]) { ++r; }
219
return std::make_pair(ei(g,e(r,0),g.ai[r+1]),
220
ei(g,e(g.nrows,g.nnz),0));
224
// implement the requirements for IncidenceGraph
226
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
227
inline typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::degree_size_type
228
out_degree(Index u, const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
229
return g.ai[u+1] - g.ai[u];
231
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
232
inline std::pair< typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::out_edge_iterator,
233
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::out_edge_iterator >
234
out_edges(Index v, const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
235
typedef typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::out_edge_iterator ei;
236
typedef typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor e;
238
return std::make_pair(ei(e(v,g.ai[v])),ei(e(v+1,g.ai[v+1])));
241
// implement the requirements for adjacency_iterator
243
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
244
inline std::pair< typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::adjacency_iterator,
245
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::adjacency_iterator >
246
adjacent_vertices(Index v, const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g) {
247
return std::make_pair(&g.aj[v],&g.aj[v+1]);
250
template <YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS, typename Tag>
251
struct property_map<YASMIC_SIMPLE_CSR_GRAPH_TYPE, Tag> {
253
typedef identity_property_map vertex_index_type;
254
typedef typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor
256
typedef detail::simple_csr_edge_index_map<EdgeIndex,edge_descriptor> edge_index_type;
257
typedef iterator_property_map<Value*,edge_index_type> edge_weight_type;
259
typedef typename mpl::if_<is_same<Tag, edge_weight_t>,
261
detail::error_property_not_found>::type
264
typedef typename mpl::if_<is_same<Tag, edge_index_t>,
266
edge_weight_or_none>::type
269
typedef typename mpl::if_<is_same<Tag, vertex_index_t>,
271
edge_prop_or_none>::type type;
272
typedef type const_type;
273
}; // end property_map
275
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
276
inline identity_property_map
277
get(vertex_index_t, const YASMIC_SIMPLE_CSR_GRAPH_TYPE&)
279
return identity_property_map();
282
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
285
const YASMIC_SIMPLE_CSR_GRAPH_TYPE&, Index v)
290
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
291
inline typename property_map<YASMIC_SIMPLE_CSR_GRAPH_TYPE, edge_index_t>::const_type
292
get(edge_index_t, const YASMIC_SIMPLE_CSR_GRAPH_TYPE&)
294
typedef typename property_map<YASMIC_SIMPLE_CSR_GRAPH_TYPE, edge_index_t>::const_type
296
return result_type();
299
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
301
get(edge_index_t, const YASMIC_SIMPLE_CSR_GRAPH_TYPE&,
302
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor e)
307
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
308
inline typename property_map<YASMIC_SIMPLE_CSR_GRAPH_TYPE, edge_weight_t>::const_type
309
get(edge_weight_t, const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g)
311
return make_iterator_property_map(g.a,get(edge_index,g));
314
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
316
get(edge_weight_t, const YASMIC_SIMPLE_CSR_GRAPH_TYPE& g,
317
typename graph_traits<YASMIC_SIMPLE_CSR_GRAPH_TYPE>::edge_descriptor e)
322
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
323
struct edge_property_type< YASMIC_SIMPLE_CSR_GRAPH_TYPE > {
327
template<YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS>
328
struct vertex_property_type< YASMIC_SIMPLE_CSR_GRAPH_TYPE > {
332
} // end namespace boost
334
#undef YASMIC_SIMPLE_CSR_GRAPH_TYPE
335
#undef YASMIC_SIMPLE_CSR_TEMPLATE_PARAMS
337
#endif /* YASMIC_UNDIR_SIMPLE_CSR_MATRIX_AS_GRAPH_HPP */