Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
sparsematrix_boost.h
Go to the documentation of this file.
1/* Copyright (c) 2022: G-CSC, Goethe University Frankfurt
2 * Felix Salfelder 2022
3 * This file is part of UG4.
4 *
5 * UG4 is free software: you can redistribute it and/or modify it under the
6 * terms of the GNU Lesser General Public License version 3 (as published by the
7 * Free Software Foundation) with the following additional attribution
8 * requirements (according to LGPL/GPL v3 §7):
9 */
10
11// BGL interface for cpu sparse martrix (dynamic CRS).
12
13#ifndef UG_SPARSEMATRIX_BOOST_H
14#define UG_SPARSEMATRIX_BOOST_H
15
16#include "common/util/trace.h"
18
19#include <boost/graph/properties.hpp> // put_get_helper
20#include <boost/iterator/counting_iterator.hpp>
21
22#include <cstdint> // for std::intmax_t
23
24namespace boost{
25
26using ug::iszero; // for now
27
28// a bit of a pointer dance,
29// because ug::SparseMatrix<T>::const_row_iterator is not default constructible.
30template<class T>
31class SM_adjacency_iterator : public iterator_facade<
32 SM_adjacency_iterator<T>,
33 typename ug::SparseMatrix<T>::const_row_iterator,
34 std::input_iterator_tag,
35 size_t, // <= reference
36 std::intmax_t // difference_type
37 >{ //
39 typedef typename M::const_row_iterator iter_t;
40 typedef iterator_facade<
43 std::input_iterator_tag,
44 size_t, // <= reference
45 std::intmax_t // difference_type
47
48public:
50 typedef intmax_t difference_type;
51 typedef size_t reference;
52
53public:
54 SM_adjacency_iterator() : base_class(), _base(nullptr), _end(nullptr){
55 }
58 : _base(p._base?(new iter_t(*p._base)) : nullptr)
59 , _end(p._end?(new iter_t(*p._end)) : nullptr){
60 }
62 assert(p);
63 _base = new iter_t(*p);
64 _end = new iter_t(*e);
66 }
68 delete _base;
69 delete _end;
70 _base = nullptr;
71 _end = nullptr;
72 }
75 if(other._base){
76 delete _base;
77 _base = new iter_t(*other._base);
78 }else{ untested();
79 _base = nullptr;
80 }
81 if(other._end){
82 delete _end;
83 _end = new iter_t(*other._end);
84 }else{ untested();
85 _end = nullptr;
86 }
87 return *this;
88 }
89
90 T const& value() const {
91 assert(_base);
92 return _base->value();
93 }
94 int row() const {
95 assert(_base);
96 return _base->row();
97 }
98 size_t idx() const { untested();
99 assert(_base);
100 return _base->idx();
101 }
103 assert(_base);
104 return _base->index(); // row?
105 }
106 bool operator==(const SM_adjacency_iterator& other) const {
107 assert(_base);
108 assert(other._base);
109 return *_base == *other._base;
110 }
111 bool operator!=(const SM_adjacency_iterator& other) const {
112 assert(_base);
113 assert(other._base);
114 return *_base != *other._base;
115 }
116
117private:
118 // could use boost::filter_iterator, but does not work yet.
120 while((*_base) != (*_end)){
121 if(iszero(_base->value())){
122 ++(*_base);
123 }else{
124 break;
125 }
126 }
127 }
128 bool equal(SM_adjacency_iterator const& other) const { untested();
129 assert(_base);
130 assert(other._base);
131 return *_base == *other._base;
132 }
133 void increment() {
134 assert(_base);
135 assert(_end);
136 ++(*_base);
137 skip_zeroes();
138 }
139 void decrement() { untested();
140 // incomplete(); // don't use. too complicated.
141 assert(_base);
142 --(*_base);
143 }
144
145private:
149}; // SM_adjacency_iterator
150
151template<class T>
153public:
154// SM_edge(size_t v, size_t w) : _row(v), _idx(w) { untested();
155// }
156 SM_edge(SM_edge const&) = default;
157 SM_edge(SM_edge&&) = default;
158 explicit SM_edge() { untested();
159 }
160 SM_edge(int s, int t, T const& v) : _source(s), _target(t), _value(v) {
161 }
162 SM_edge& operator=(SM_edge const&) = default;
163 SM_edge& operator=(SM_edge&&) = default;
164
165public:
166 int source() const{
167 return _source;
168 }
169 int target() const{
170 return _target;
171 }
172 template<class X>
173 T const& value(X const&) const{
174 return _value;
175 }
176
177public:
178 bool operator==(const SM_edge& other) const { untested();
179 return _source == other._source && _target == other._target;
180 }
181 bool operator!=(const SM_edge& other) const { untested();
182 return !operator==(other);
183 }
184
185private:
189}; // SM_edge
190
191template<class T, class M>
192int source(SM_edge<T> const& e, M const&)
193{ untested();
194 return e.source();
195}
196
197template<class T, class M>
198int target(SM_edge<T> const& e, M const&)
199{ untested();
200 return e.target();
201}
202
203template<class T, bool out=true>
204class SM_out_edge_iterator : public iterator_facade<
205 SM_out_edge_iterator<T, out>,
206 SM_adjacency_iterator<T>,
207 // bidirectional_traversal_tag, // breaks InputIterator (why?)
208 std::input_iterator_tag,
209 SM_edge<T>, // <= reference
210 std::intmax_t // difference_type
211 >{ //
212public: // types
213 typedef iterator_facade<
216 std::input_iterator_tag,
217 SM_edge<T>, // <= reference
218 std::intmax_t // difference_type
222 typedef intmax_t difference_type;
225
226public: // construct
228 }
230 : base_class(), _base(w), _src(src) {
231 if(out){
232 }else{
233 }
234 }
237 if(out){
238 }else{
239 }
240 }
246#if 0
247public: // op
248 SM_out_edge_iterator operator+(int a) const{ untested();
249 SM_out_edge_iterator ret(*this);
250 ret.base.first += a;
251 return ret;
252 }
253 SM_out_edge_iterator operator-(int a) const{ untested();
254 SM_out_edge_iterator ret(*this);
255 ret.base.first -= a;
256 return ret;
257 }
258 difference_type operator-(SM_out_edge_iterator const& other) const{ untested();
259 SM_out_edge_iterator ret(*this);
260 return ret.base.first - other.base.first;
261 }
262#endif
263private:
265 if(out){
266 return edge_type(_src, *_base, _base.value());
267 }else{
268 return edge_type(*_base, _src, _base.value());
269 }
270 }
271 bool equal(SM_out_edge_iterator const& other) const { untested();
272 assert(_base.first == other._base.first);
273 return _base.second == other._base.second;
274 }
275 void increment() { untested();
276 ++_base;
277 }
278 void decrement() { untested();
279 --_base;
280 }
281 // bool operator==(const SM_out_edge_iterator& other) const
282 // { incomplete();
283 // return false;
284 // }
285public:
287 ++_base;
288 return *this;
289 }
291 SM_out_edge_iterator copy(*this);
292 ++*this;
293 return copy;
294 }
295 bool operator==(const SM_out_edge_iterator& other) const {
296 return _base == other._base;
297 }
298 bool operator!=(const SM_out_edge_iterator& other) const {
299 return _base != other._base;
300 }
301
302private:
304 int _src;
306}; // SM_out_edge_iterator
307
309 : adjacency_graph_tag, bidirectional_graph_tag, vertex_list_graph_tag {};
310
311template <class T> struct graph_traits<ug::SparseMatrix<T>>{
312 typedef int vertex_descriptor;
314 typedef directed_tag directed_category;
315 typedef disallow_parallel_edge_tag edge_parallel_category;
317 typedef counting_iterator<size_t> vertex_iterator;
320 typedef int degree_size_type;
322};
323
324template<class T>
325std::pair<typename graph_traits<ug::SparseMatrix<T>>::adjacency_iterator,
326 typename graph_traits<ug::SparseMatrix<T>>::adjacency_iterator>
327inline adjacent_vertices(size_t v, ug::SparseMatrix<T> const& M)
328{
329 assert(v<M.num_rows());
330 typedef typename graph_traits<ug::SparseMatrix<T>>::adjacency_iterator a;
331
334
335 return std::make_pair(a(&b, &e), a(&e, &e));
336}
337
338template<class T>
339inline std::pair<SM_out_edge_iterator<T>, SM_out_edge_iterator<T>>
341{
342 assert(size_t(v)<g.num_rows());
343 typedef SM_out_edge_iterator<T> Iter;
344 auto a = adjacent_vertices(v, g);
345 return std::make_pair(Iter(a.first, v), Iter(a.second, v));
346}
347
348template<class T>
350 : public put_get_helper<size_t, sparse_matrix_index_map<T> > { //
351public:
352 typedef size_t vertex_index_type;
353 typedef size_t vertex_descriptor;
354 typedef readable_property_map_tag category;
358
361 sparse_matrix_index_map(ug::SparseMatrix<T>const&, boost::vertex_index_t) { untested();
362 }
363 template<class X>
365 }
366 template <class T_>
367 value_type operator[](T_ x) const {
368 return x;
369 }
371 return *this;
372 }
373};
374
375template<class T>
376struct property_map<ug::SparseMatrix<T>, vertex_index_t>{
379};
380
381template<class T>
382typename property_map<ug::SparseMatrix<T>, vertex_index_t>::const_type
383get(vertex_index_t, ug::SparseMatrix<T> const& m)
384{
386}
387
388template<class T>
389std::pair<counting_iterator<size_t>, counting_iterator<size_t> > vertices(
390 ug::SparseMatrix<T> const& M)
391{
392 counting_iterator<size_t> b(0);
393 counting_iterator<size_t> e(M.num_rows());
394
395 return std::make_pair(b,e);
396}
397
398template<class T>
400{
401 assert(M.num_rows() == M.num_cols());
402 return M.num_rows();
403}
404
405template<class T>
406int out_degree(int v, ug::SparseMatrix<T> const& M)
407{
408 int c = 0;
409 auto i = out_edges(v, M);
410 for(; i.first != i.second; ++i.first) {
411 ++c;
412 }
413 return c;
414}
415
416// template<class T>
417// T get(edge_weight_t, ug::SparseMatrix<T> const& M, SM_edge<T> e)
418// { untested();
419// return e.value();
420// }
421
422template<class T, class M=ug::SparseMatrix<T>>
424 public put_get_helper< T /*algebraic connection?*/, SM_edge_weight_map<T> > { //
425public:
427 typedef int vertex_descriptor;
428 typedef readable_property_map_tag category;
430 typedef T& reference;
432
435 SM_edge_weight_map(ug::SparseMatrix<T>const & g, boost::edge_weight_t) : _g(g) { untested();
436 }
437 // bug?
438 SM_edge_weight_map(M const& g) : _g(g) {
439 }
440 template <class X>
441 value_type operator[](X const& x) const {
442 // assert(x == _g.position(x));
443 return x.value(_g);
444 }
446 assert(&s._g==&_g); (void)s;
447 return *this;
448 }
449private:
450 M const& _g;
451}; // SM_edge_weight_map
452
453// g++ 'enumeral_type' in template unification not implemented workaround
454template<class T, class Tag>
455struct property_map<ug::SparseMatrix<T>, Tag> {
456// typedef typename gala_graph_property_map<Tag>::template bind_<T> map_gen;
457// typedef typename map_gen::type type;
458// typedef typename map_gen::const_type const_type;
459};
460
461template<class T>
463//inline typename property_map<ug::SparseMatrix<T>, edge_weight_t>::type
464get(edge_weight_t, ug::SparseMatrix<T> const & g) {
465 return SM_edge_weight_map<T>(g);
466}
467
468#if 0
469template<class T>
470inline typename property_map<ug::SparseMatrix<T>, edge_all_t>::type
471get(edge_all_t, ug::SparseMatrix<T> & g) { incomplete();
472 typedef typename property_map<ug::SparseMatrix<T>, edge_all_t>::type
473 pmap_type;
474 return pmap_type(&g);
475}
476#endif
477
478} // boost
479
480namespace ug{
481
482// used from boost::print_graph, graph_utility.hpp.
483// must be in ug, because of ADL. why don't they call boost::{out_edges,vertices}?
484using boost::vertices;
485using boost::out_edges;
486
487}// ug
488
489#endif // guard
parameterString p
parameterString s
Definition sparsematrix_interface.h:37
Definition sparsematrix_boost.h:37
bool operator==(const SM_adjacency_iterator &other) const
Definition sparsematrix_boost.h:106
friend class iterator_core_access
Definition sparsematrix_boost.h:148
~SM_adjacency_iterator()
Definition sparsematrix_boost.h:67
intmax_t difference_type
Definition sparsematrix_boost.h:50
SM_adjacency_iterator(SM_adjacency_iterator &&p)=delete
void skip_zeroes()
Definition sparsematrix_boost.h:119
SM_adjacency_iterator(value_type p, value_type e)
Definition sparsematrix_boost.h:61
void decrement()
Definition sparsematrix_boost.h:139
value_type _end
Definition sparsematrix_boost.h:147
iter_t * value_type
Definition sparsematrix_boost.h:49
value_type _base
Definition sparsematrix_boost.h:146
SM_adjacency_iterator()
Definition sparsematrix_boost.h:54
ug::SparseMatrix< T > M
Definition sparsematrix_boost.h:38
iterator_facade< SM_adjacency_iterator< T >, typename ug::SparseMatrix< T >::const_row_iterator, std::input_iterator_tag, size_t, std::intmax_t > base_class
Definition sparsematrix_boost.h:46
bool equal(SM_adjacency_iterator const &other) const
Definition sparsematrix_boost.h:128
SM_adjacency_iterator & operator=(SM_adjacency_iterator &&other)=delete
int row() const
Definition sparsematrix_boost.h:94
void increment()
Definition sparsematrix_boost.h:133
SM_adjacency_iterator(SM_adjacency_iterator const &p)
Definition sparsematrix_boost.h:57
M::const_row_iterator iter_t
Definition sparsematrix_boost.h:39
T const & value() const
Definition sparsematrix_boost.h:90
bool operator!=(const SM_adjacency_iterator &other) const
Definition sparsematrix_boost.h:111
reference dereference() const
Definition sparsematrix_boost.h:102
size_t idx() const
Definition sparsematrix_boost.h:98
size_t reference
Definition sparsematrix_boost.h:51
SM_adjacency_iterator & operator=(const SM_adjacency_iterator &other)
Definition sparsematrix_boost.h:74
Definition sparsematrix_boost.h:424
int vertex_descriptor
Definition sparsematrix_boost.h:427
SM_edge_weight_map(ug::SparseMatrix< T >const &g, boost::edge_weight_t)
Definition sparsematrix_boost.h:435
T & reference
Definition sparsematrix_boost.h:430
SM_edge_weight_map(M const &g)
Definition sparsematrix_boost.h:438
vertex_descriptor key_type
Definition sparsematrix_boost.h:431
edge_weight_type value_type
Definition sparsematrix_boost.h:429
SM_edge_weight_map(SM_edge_weight_map const &p)
Definition sparsematrix_boost.h:433
value_type operator[](X const &x) const
Definition sparsematrix_boost.h:441
T edge_weight_type
Definition sparsematrix_boost.h:426
M const & _g
Definition sparsematrix_boost.h:450
SM_edge_weight_map & operator=(const SM_edge_weight_map &s)
Definition sparsematrix_boost.h:445
readable_property_map_tag category
Definition sparsematrix_boost.h:428
Definition sparsematrix_boost.h:152
SM_edge & operator=(SM_edge &&)=default
SM_edge(SM_edge &&)=default
bool operator!=(const SM_edge &other) const
Definition sparsematrix_boost.h:181
int target() const
Definition sparsematrix_boost.h:169
SM_edge()
Definition sparsematrix_boost.h:158
T _value
Definition sparsematrix_boost.h:188
int _target
Definition sparsematrix_boost.h:187
SM_edge(SM_edge const &)=default
T const & value(X const &) const
Definition sparsematrix_boost.h:173
int source() const
Definition sparsematrix_boost.h:166
bool operator==(const SM_edge &other) const
Definition sparsematrix_boost.h:178
SM_edge(int s, int t, T const &v)
Definition sparsematrix_boost.h:160
SM_edge & operator=(SM_edge const &)=default
int _source
Definition sparsematrix_boost.h:186
Definition sparsematrix_boost.h:211
friend class iterator_core_access
Definition sparsematrix_boost.h:305
SM_out_edge_iterator & operator=(SM_out_edge_iterator &&other)=default
reference dereference() const
Definition sparsematrix_boost.h:264
void decrement()
Definition sparsematrix_boost.h:278
SM_out_edge_iterator & operator++()
Definition sparsematrix_boost.h:286
SM_adjacency_iterator< T > value_type
Definition sparsematrix_boost.h:221
ug::SparseMatrix< T > M
Definition sparsematrix_boost.h:220
intmax_t difference_type
Definition sparsematrix_boost.h:222
SM_out_edge_iterator(SM_out_edge_iterator const &p)
Definition sparsematrix_boost.h:235
bool equal(SM_out_edge_iterator const &other) const
Definition sparsematrix_boost.h:271
value_type _base
Definition sparsematrix_boost.h:303
bool operator==(const SM_out_edge_iterator &other) const
Definition sparsematrix_boost.h:295
~SM_out_edge_iterator()
Definition sparsematrix_boost.h:242
SM_out_edge_iterator & operator=(SM_out_edge_iterator const &other)=default
iterator_facade< SM_out_edge_iterator< T, out >, SM_adjacency_iterator< T >, std::input_iterator_tag, SM_edge< T >, std::intmax_t > base_class
Definition sparsematrix_boost.h:219
void increment()
Definition sparsematrix_boost.h:275
SM_out_edge_iterator()
Definition sparsematrix_boost.h:227
bool operator!=(const SM_out_edge_iterator &other) const
Definition sparsematrix_boost.h:298
SM_out_edge_iterator operator++(int)
Definition sparsematrix_boost.h:290
SM_edge< T > edge_type
Definition sparsematrix_boost.h:224
SM_edge< T > reference
Definition sparsematrix_boost.h:223
SM_out_edge_iterator(SM_out_edge_iterator &&p)=delete
SM_out_edge_iterator(SM_adjacency_iterator< T > w, int src)
Definition sparsematrix_boost.h:229
int _src
Definition sparsematrix_boost.h:304
Definition sparsematrix_boost.h:350
size_t vertex_index_type
Definition sparsematrix_boost.h:352
sparse_matrix_index_map & operator=(const sparse_matrix_index_map &s)
Definition sparsematrix_boost.h:370
vertex_descriptor key_type
Definition sparsematrix_boost.h:357
vertex_index_type value_type
Definition sparsematrix_boost.h:355
sparse_matrix_index_map(ug::SparseMatrix< T >const &, boost::vertex_index_t)
Definition sparsematrix_boost.h:361
vertex_index_type reference
Definition sparsematrix_boost.h:356
readable_property_map_tag category
Definition sparsematrix_boost.h:354
size_t vertex_descriptor
Definition sparsematrix_boost.h:353
value_type operator[](T_ x) const
Definition sparsematrix_boost.h:367
sparse_matrix_index_map(sparse_matrix_index_map const &p)
Definition sparsematrix_boost.h:359
sparse_matrix_index_map(X const &)
Definition sparsematrix_boost.h:364
Definition sparsematrix.h:421
size_t idx() const
Definition sparsematrix.h:478
const value_type & value() const
Definition sparsematrix.h:470
size_t index() const
Definition sparsematrix.h:471
sparse matrix for big, variable sparse matrices.
Definition sparsematrix.h:99
size_t num_rows() const
returns number of rows
Definition sparsematrix.h:342
row_iterator end_row(size_t r)
Definition sparsematrix.h:485
size_t num_cols() const
returns the number of cols
Definition sparsematrix.h:345
row_iterator begin_row(size_t r)
Definition sparsematrix.h:484
#define untested()
Definition lua_table_handle.cpp:15
Definition boost_serialization_routines.h:49
std::pair< typename graph_traits< T >::adjacency_iterator, typename graph_traits< T >::adjacency_iterator > adjacent_vertices(size_t v, ug::BidirectionalMatrix< T > const &M)
Definition bidirectional_boost.h:108
std::pair< SM_out_edge_iterator< typename T::value_type >, SM_out_edge_iterator< typename T::value_type > > out_edges(size_t v, ug::BidirectionalMatrix< T > const &g)
Definition bidirectional_boost.h:136
int out_degree(int v, ug::BidirectionalMatrix< T > const &M)
Definition bidirectional_boost.h:76
std::pair< counting_iterator< size_t >, counting_iterator< size_t > > vertices(ug::BidirectionalMatrix< T > const &M)
Definition bidirectional_boost.h:60
int num_vertices(ug::BidirectionalMatrix< T > const &M)
Definition bidirectional_boost.h:70
SM_edge_weight_map< typename T::value_type, ug::BidirectionalMatrix< T > > get(edge_weight_t, ug::BidirectionalMatrix< T > const &g)
Definition bidirectional_boost.h:157
size_t target(SM_edge< typename T::value_type > const &e, ug::BidirectionalMatrix< T > const &m)
Definition bidirectional_boost.h:100
size_t source(SM_edge< typename T::value_type > const &e, ug::BidirectionalMatrix< T > const &)
Definition bidirectional_boost.h:94
the ug namespace
bool iszero(__T __val)
Definition sparsematrix_impl.h:53
Definition sparsematrix_boost.h:309
SM_traversal_tag traversal_category
Definition sparsematrix_boost.h:316
int degree_size_type
Definition sparsematrix_boost.h:320
disallow_parallel_edge_tag edge_parallel_category
Definition sparsematrix_boost.h:315
SM_adjacency_iterator< T > adjacency_iterator
Definition sparsematrix_boost.h:319
int vertices_size_type
Definition sparsematrix_boost.h:321
counting_iterator< size_t > vertex_iterator
Definition sparsematrix_boost.h:317
int vertex_descriptor
Definition sparsematrix_boost.h:312
SM_edge< T > edge_descriptor
Definition sparsematrix_boost.h:313
directed_tag directed_category
Definition sparsematrix_boost.h:314
SM_out_edge_iterator< T > out_edge_iterator
Definition sparsematrix_boost.h:318
sparse_matrix_index_map< T > type
Definition sparsematrix_boost.h:377
type const_type
Definition sparsematrix_boost.h:378
#define incomplete()
Definition trace.h:10
function ProblemDisc new(problemDesc, dom)