39 #ifndef GMM_INTERFACE_H__
40 #define GMM_INTERFACE_H__
86 template <
typename PT>
struct simple_vector_ref {
87 typedef simple_vector_ref<PT> this_type;
88 typedef typename std::iterator_traits<PT>::value_type V;
90 typedef typename std::iterator_traits<PT>::reference ref_V;
91 typedef typename linalg_traits<this_type>::iterator iterator;
92 typedef typename linalg_traits<this_type>::reference reference;
93 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
95 iterator begin_, end_;
99 simple_vector_ref(ref_V v) : begin_(vect_begin(const_cast<V&>(v))),
100 end_(vect_end(const_cast<V&>(v))),
101 origin(linalg_origin(const_cast<V&>(v))),
102 size_(vect_size(v)) {}
104 simple_vector_ref(
const simple_vector_ref<CPT> &cr)
105 : begin_(cr.begin_),end_(cr.end_),origin(cr.origin),size_(cr.size_) {}
107 simple_vector_ref(
void) {}
110 {
return linalg_traits<V>::access(origin, begin_, end_, i); }
113 template <
typename IT,
typename ORG,
typename PT>
inline
114 void set_to_begin(IT &it, ORG o, simple_vector_ref<PT> *,linalg_modifiable) {
115 typedef typename linalg_traits<simple_vector_ref<PT> >::V_reference ref_t;
116 set_to_begin(it, o, PT(), ref_t());
119 template <
typename IT,
typename ORG,
typename PT>
inline
120 void set_to_begin(IT &it, ORG o,
const simple_vector_ref<PT> *,
122 typedef typename linalg_traits<simple_vector_ref<PT> >::V_reference ref_t;
123 set_to_begin(it, o, PT(), ref_t());
126 template <
typename IT,
typename ORG,
typename PT>
inline
127 void set_to_end(IT &it, ORG o, simple_vector_ref<PT> *, linalg_modifiable) {
128 typedef typename linalg_traits<simple_vector_ref<PT> >::V_reference ref_t;
129 set_to_end(it, o, PT(), ref_t());
132 template <
typename IT,
typename ORG,
typename PT>
inline
133 void set_to_end(IT &it, ORG o,
const simple_vector_ref<PT> *,
135 typedef typename linalg_traits<simple_vector_ref<PT> >::V_reference ref_t;
136 set_to_end(it, o, PT(), ref_t());
140 template <
typename PT>
struct linalg_traits<simple_vector_ref<PT> > {
141 typedef simple_vector_ref<PT> this_type;
142 typedef this_type *pthis_type;
143 typedef typename std::iterator_traits<PT>::value_type V;
144 typedef typename linalg_traits<V>::origin_type origin_type;
146 typedef typename linalg_traits<V>::is_reference V_reference;
147 typedef typename which_reference<PT>::is_reference is_reference;
148 typedef abstract_vector linalg_type;
149 typedef typename linalg_traits<V>::value_type value_type;
150 typedef typename select_ref<value_type,
typename
151 linalg_traits<V>::reference, PT>::ref_type reference;
152 typedef typename select_ref<
const origin_type *, origin_type *,
153 PT>::ref_type porigin_type;
154 typedef typename select_ref<typename linalg_traits<V>::const_iterator,
155 typename linalg_traits<V>::iterator, PT>::ref_type iterator;
156 typedef typename linalg_traits<V>::const_iterator const_iterator;
157 typedef typename linalg_traits<V>::storage_type storage_type;
158 typedef linalg_true index_sorted;
159 static size_type size(
const this_type &v) {
return v.size_; }
160 static inline iterator begin(this_type &v) {
161 iterator it = v.begin_;
162 set_to_begin(it, v.origin, pthis_type(), is_reference());
165 static inline const_iterator begin(
const this_type &v) {
166 const_iterator it = v.begin_;
167 set_to_begin(it, v.origin, pthis_type(), is_reference());
170 static inline iterator end(this_type &v) {
171 iterator it = v.end_;
172 set_to_end(it, v.origin, pthis_type(), is_reference());
175 static inline const_iterator end(
const this_type &v) {
176 const_iterator it = v.end_;
177 set_to_end(it, v.origin, pthis_type(), is_reference());
180 static origin_type* origin(this_type &v) {
return v.origin; }
181 static const origin_type* origin(
const this_type &v) {
return v.origin; }
182 static void clear(origin_type* o,
const iterator &it,
const iterator &ite)
183 { linalg_traits<V>::clear(o, it, ite); }
184 static void do_clear(this_type &v) {
clear(v.origin, v.begin_, v.end_); }
185 static value_type access(
const origin_type *o,
const const_iterator &it,
187 {
return linalg_traits<V>::access(o, it, ite, i); }
188 static reference access(origin_type *o,
const iterator &it,
190 {
return linalg_traits<V>::access(o, it, ite, i); }
193 template <
typename PT>
194 std::ostream &operator << (std::ostream &o,
const simple_vector_ref<PT>& v)
195 { gmm::write(o,v);
return o; }
197 template <
typename T,
typename alloc>
198 simple_vector_ref<const std::vector<T,alloc> *>
199 vref(
const std::vector<T, alloc> &vv)
200 {
return simple_vector_ref<const std::vector<T,alloc> *>(vv); }
209 template <
typename T,
typename alloc>
210 struct linalg_traits<std::vector<T, alloc> > {
211 typedef std::vector<T, alloc> this_type;
212 typedef this_type origin_type;
213 typedef linalg_false is_reference;
214 typedef abstract_vector linalg_type;
215 typedef T value_type;
216 typedef T& reference;
217 typedef typename this_type::iterator iterator;
218 typedef typename this_type::const_iterator const_iterator;
219 typedef abstract_dense storage_type;
220 typedef linalg_true index_sorted;
221 static size_type size(
const this_type &v) {
return v.size(); }
222 static iterator begin(this_type &v) {
return v.begin(); }
223 static const_iterator begin(
const this_type &v) {
return v.begin(); }
224 static iterator end(this_type &v) {
return v.end(); }
225 static const_iterator end(
const this_type &v) {
return v.end(); }
226 static origin_type* origin(this_type &v) {
return &v; }
227 static const origin_type* origin(
const this_type &v) {
return &v; }
228 static void clear(origin_type*,
const iterator &it,
const iterator &ite)
229 { std::fill(it, ite, value_type(0)); }
230 static void do_clear(this_type &v) { std::fill(v.begin(), v.end(), T(0)); }
231 static value_type access(
const origin_type *,
const const_iterator &it,
234 static reference access(origin_type *,
const iterator &it,
242 template <
typename T>
243 inline size_type nnz(
const std::vector<T>& l) {
return l.size(); }
251 template <
typename IT,
typename V>
252 struct tab_ref_with_origin :
public gmm::tab_ref<IT> {
253 typedef tab_ref_with_origin<IT, V> this_type;
256 typedef typename linalg_traits<V>::origin_type origin_type;
257 typedef typename std::iterator_traits<IT>::pointer PT;
258 typedef typename select_ref<
const origin_type *, origin_type *,
259 PT>::ref_type porigin_type;
264 tab_ref_with_origin(
void) {}
265 template <
class PT> tab_ref_with_origin(
const IT &b,
const IT &e, PT p)
266 : gmm::tab_ref<IT>(b,e), origin(porigin_type(p)) {}
267 tab_ref_with_origin(
const IT &b,
const IT &e, porigin_type p)
268 : gmm::tab_ref<IT>(b,e), origin(p) {}
270 tab_ref_with_origin(
const V &v,
const sub_interval &si)
271 : gmm::tab_ref<IT>(vect_begin(const_cast<V&>(v))+si.min,
272 vect_begin(const_cast<V&>(v))+si.max),
273 origin(linalg_origin(const_cast<V&>(v))) {}
274 tab_ref_with_origin(V &v,
const sub_interval &si)
275 : gmm::tab_ref<IT>(vect_begin(const_cast<V&>(v))+si.min,
276 vect_begin(const_cast<V&>(v))+si.max),
277 origin(linalg_origin(const_cast<V&>(v))) {}
280 template <
typename IT,
typename V>
281 struct linalg_traits<tab_ref_with_origin<IT, V> > {
282 typedef typename std::iterator_traits<IT>::pointer PT;
283 typedef typename linalg_traits<V>::origin_type origin_type;
284 typedef tab_ref_with_origin<IT, V> this_type;
285 typedef typename which_reference<PT>::is_reference is_reference;
286 typedef abstract_vector linalg_type;
287 typedef typename select_ref<
const origin_type *, origin_type *,
288 PT>::ref_type porigin_type;
289 typedef typename std::iterator_traits<IT>::value_type value_type;
290 typedef typename std::iterator_traits<IT>::reference reference;
291 typedef typename this_type::iterator iterator;
292 typedef typename this_type::iterator const_iterator;
293 typedef abstract_dense storage_type;
294 typedef linalg_true index_sorted;
295 static size_type size(
const this_type &v) {
return v.size(); }
296 static iterator begin(this_type &v) {
return v.begin(); }
297 static const_iterator begin(
const this_type &v) {
return v.begin(); }
298 static iterator end(this_type &v) {
return v.end(); }
299 static const_iterator end(
const this_type &v) {
return v.end(); }
300 static origin_type* origin(this_type &v) {
return v.origin; }
301 static const origin_type* origin(
const this_type &v) {
return v.origin; }
302 static void clear(origin_type*,
const iterator &it,
const iterator &ite)
303 { std::fill(it, ite, value_type(0)); }
304 static inline void do_clear(this_type &v)
305 { std::fill(v.begin(), v.end(), value_type(0)); }
306 static value_type access(
const origin_type *,
const const_iterator &it,
309 static reference access(origin_type *,
const iterator &it,
314 template <
typename IT,
typename V> std::ostream &
operator <<
315 (std::ostream &o,
const tab_ref_with_origin<IT, V>& m)
316 { gmm::write(o,m);
return o; }
319 template <
typename IT,
typename V>
321 typedef tab_ref_reg_spaced_with_origin<IT, V> this_type;
322 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
326 tab_ref_reg_spaced_with_origin(
void) {}
328 const porigin_type p)
329 : gmm::tab_ref_reg_spaced<IT>(b,n,s), origin(p) {}
330 tab_ref_reg_spaced_with_origin(
const V &v,
const sub_slice &si)
331 : gmm::tab_ref_reg_spaced<IT>(vect_begin(const_cast<V&>(v)) + si.min,
332 si.N, (si.max - si.min)/si.N),
333 origin(linalg_origin(const_cast<V&>(v))) {}
334 tab_ref_reg_spaced_with_origin(V &v,
const sub_slice &si)
335 : gmm::tab_ref_reg_spaced<IT>(vect_begin(const_cast<V&>(v)) + si.min,
336 si.N, (si.max - si.min)/si.N),
337 origin(linalg_origin(const_cast<V&>(v))) {}
340 template <
typename IT,
typename V>
341 struct linalg_traits<tab_ref_reg_spaced_with_origin<IT, V> > {
342 typedef typename std::iterator_traits<IT>::pointer PT;
343 typedef tab_ref_reg_spaced_with_origin<IT, V> this_type;
344 typedef typename linalg_traits<V>::origin_type origin_type;
345 typedef typename select_ref<
const origin_type *, origin_type *,
346 PT>::ref_type porigin_type;
347 typedef typename which_reference<PT>::is_reference is_reference;
348 typedef abstract_vector linalg_type;
349 typedef typename std::iterator_traits<IT>::value_type value_type;
350 typedef typename std::iterator_traits<IT>::reference reference;
351 typedef typename this_type::iterator iterator;
352 typedef typename this_type::iterator const_iterator;
353 typedef abstract_dense storage_type;
354 typedef linalg_true index_sorted;
355 static size_type size(
const this_type &v) {
return v.size(); }
356 static iterator begin(this_type &v) {
return v.begin(); }
357 static const_iterator begin(
const this_type &v) {
return v.begin(); }
358 static iterator end(this_type &v) {
return v.end(); }
359 static const_iterator end(
const this_type &v) {
return v.end(); }
360 static origin_type* origin(this_type &v) {
return v.origin; }
361 static const origin_type* origin(
const this_type &v) {
return v.origin; }
362 static void clear(origin_type*,
const iterator &it,
const iterator &ite)
363 { std::fill(it, ite, value_type(0)); }
364 static void do_clear(this_type &v)
365 { std::fill(v.begin(), v.end(), value_type(0)); }
366 static value_type access(
const origin_type *,
const const_iterator &it,
369 static reference access(origin_type *,
const iterator &it,
374 template <
typename IT,
typename V> std::ostream &
operator <<
375 (std::ostream &o,
const tab_ref_reg_spaced_with_origin<IT, V>& m)
376 { gmm::write(o,m);
return o; }
379 template <
typename IT,
typename ITINDEX,
typename V>
380 struct tab_ref_index_ref_with_origin
382 typedef tab_ref_index_ref_with_origin<IT, ITINDEX, V> this_type;
383 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
387 tab_ref_index_ref_with_origin(
void) {}
388 tab_ref_index_ref_with_origin(
const IT &b,
const ITINDEX &bi,
389 const ITINDEX &ei, porigin_type p)
390 : gmm::tab_ref_index_ref<IT, ITINDEX>(b, bi, ei), origin(p) {}
392 tab_ref_index_ref_with_origin(
const V &v,
const sub_index &si)
393 : gmm::tab_ref_index_ref<IT, ITINDEX>(vect_begin(const_cast<V&>(v)),
394 si.begin(), si.end()),
395 origin(linalg_origin(const_cast<V&>(v))) {}
396 tab_ref_index_ref_with_origin(V &v,
const sub_index &si)
397 : gmm::tab_ref_index_ref<IT, ITINDEX>(vect_begin(const_cast<V&>(v)),
398 si.begin(), si.end()),
399 origin(linalg_origin(const_cast<V&>(v))) {}
402 template <
typename IT,
typename ITINDEX,
typename V>
403 struct linalg_traits<tab_ref_index_ref_with_origin<IT, ITINDEX, V> > {
404 typedef typename std::iterator_traits<IT>::pointer PT;
405 typedef tab_ref_index_ref_with_origin<IT, ITINDEX, V> this_type;
406 typedef typename linalg_traits<V>::origin_type origin_type;
407 typedef typename select_ref<
const origin_type *, origin_type *,
408 PT>::ref_type porigin_type;
409 typedef typename which_reference<PT>::is_reference is_reference;
410 typedef abstract_vector linalg_type;
411 typedef typename std::iterator_traits<IT>::value_type value_type;
412 typedef typename std::iterator_traits<IT>::reference reference;
413 typedef typename this_type::iterator iterator;
414 typedef typename this_type::iterator const_iterator;
415 typedef abstract_dense storage_type;
416 typedef linalg_true index_sorted;
417 static size_type size(
const this_type &v) {
return v.size(); }
418 static iterator begin(this_type &v) {
return v.begin(); }
419 static const_iterator begin(
const this_type &v) {
return v.begin(); }
420 static iterator end(this_type &v) {
return v.end(); }
421 static const_iterator end(
const this_type &v) {
return v.end(); }
422 static origin_type* origin(this_type &v) {
return v.origin; }
423 static const origin_type* origin(
const this_type &v) {
return v.origin; }
424 static void clear(origin_type*,
const iterator &it,
const iterator &ite)
425 { std::fill(it, ite, value_type(0)); }
426 static void do_clear(this_type &v)
427 { std::fill(v.begin(), v.end(), value_type(0)); }
428 static value_type access(
const origin_type *,
const const_iterator &it,
431 static reference access(origin_type *,
const iterator &it,
436 template <
typename IT,
typename ITINDEX,
typename V>
437 std::ostream &
operator <<
438 (std::ostream &o,
const tab_ref_index_ref_with_origin<IT, ITINDEX, V>& m)
439 { gmm::write(o,m);
return o; }
442 template<
typename ITER,
typename MIT,
typename PT>
443 struct dense_compressed_iterator {
444 typedef ITER value_type;
445 typedef ITER *pointer;
446 typedef ITER &reference;
447 typedef ptrdiff_t difference_type;
448 typedef std::random_access_iterator_tag iterator_category;
450 typedef dense_compressed_iterator<ITER, MIT, PT> iterator;
451 typedef typename std::iterator_traits<PT>::value_type *MPT;
457 iterator operator ++(
int) { iterator tmp = *
this; i++;
return tmp; }
458 iterator operator --(
int) { iterator tmp = *
this; i--;
return tmp; }
459 iterator &operator ++() { ++i;
return *
this; }
460 iterator &operator --() { --i;
return *
this; }
461 iterator &operator +=(difference_type ii) { i += ii;
return *
this; }
462 iterator &operator -=(difference_type ii) { i -= ii;
return *
this; }
464 { iterator itt = *
this;
return (itt += ii); }
466 { iterator itt = *
this;
return (itt -= ii); }
467 difference_type
operator -(
const iterator &ii)
const
468 {
return (N ? (it - ii.it) / N : 0) + i - ii.i; }
470 ITER operator *()
const {
return it+i*N; }
471 ITER operator [](
int ii)
const {
return it + (i+ii) * N; }
473 bool operator ==(
const iterator &ii)
const
474 {
return (*
this - ii) == difference_type(0); }
475 bool operator !=(
const iterator &ii)
const {
return !(ii == *
this); }
476 bool operator < (
const iterator &ii)
const
477 {
return (*
this - ii) < difference_type(0); }
479 dense_compressed_iterator(
void) {}
480 dense_compressed_iterator(
const dense_compressed_iterator<MIT,MIT,MPT> &ii)
481 : it(ii.it), N(ii.N), nrows(ii.nrows), ncols(ii.ncols), i(ii.i),
485 : it(iter), N(n), nrows(r), ncols(c), i(ii), origin(o) { }
493 template <
typename PT1,
typename PT2,
int shift = 0>
494 struct cs_vector_ref_iterator {
498 typedef typename std::iterator_traits<PT1>::value_type value_type;
500 typedef typename std::iterator_traits<PT1>::reference reference;
502 typedef ptrdiff_t difference_type;
503 typedef std::bidirectional_iterator_tag iterator_category;
504 typedef cs_vector_ref_iterator<PT1, PT2, shift> iterator;
506 cs_vector_ref_iterator(
void) {}
507 cs_vector_ref_iterator(PT1 p1, PT2 p2) : pr(p1), ir(p2) {}
509 inline size_type index(
void)
const {
return (*ir) - shift; }
510 iterator &operator ++() { ++pr; ++ir;
return *
this; }
511 iterator operator ++(
int) { iterator tmp = *
this; ++(*this);
return tmp; }
512 iterator &operator --() { --pr; --ir;
return *
this; }
513 iterator operator --(
int) { iterator tmp = *
this; --(*this);
return tmp; }
515 reference operator *()
const {
return *pr; }
516 pointer operator ->()
const {
return pr; }
518 bool operator ==(
const iterator &i)
const {
return (i.pr==pr);}
519 bool operator !=(
const iterator &i)
const {
return (i.pr!=pr);}
522 template <
typename PT1,
typename PT2,
int shift = 0>
struct cs_vector_ref {
527 typedef cs_vector_ref<PT1, PT2, shift> this_type;
528 typedef typename std::iterator_traits<PT1>::value_type value_type;
529 typedef typename linalg_traits<this_type>::const_iterator const_iterator;
532 : pr(pt1), ir(pt2), n(
nnz), size_(ns) {}
533 cs_vector_ref(
void) {}
535 size_type size(
void)
const {
return size_; }
537 const_iterator begin(
void)
const {
return const_iterator(pr, ir); }
538 const_iterator end(
void)
const {
return const_iterator(pr+n, ir+n); }
541 {
return linalg_traits<this_type>::access(pr, begin(), end(),i); }
544 template <
typename PT1,
typename PT2,
int shift>
545 struct linalg_traits<cs_vector_ref<PT1, PT2, shift> > {
546 typedef cs_vector_ref<PT1, PT2, shift> this_type;
547 typedef linalg_const is_reference;
548 typedef abstract_vector linalg_type;
549 typedef typename std::iterator_traits<PT1>::value_type value_type;
550 typedef value_type origin_type;
551 typedef typename std::iterator_traits<PT1>::value_type reference;
552 typedef cs_vector_ref_iterator<typename const_pointer<PT1>::pointer,
553 typename const_pointer<PT2>::pointer, shift> const_iterator;
554 typedef abstract_null_type iterator;
555 typedef abstract_sparse storage_type;
556 typedef linalg_true index_sorted;
557 static size_type size(
const this_type &v) {
return v.size(); }
558 static iterator begin(this_type &v) {
return v.begin(); }
559 static const_iterator begin(
const this_type &v) {
return v.begin(); }
560 static iterator end(this_type &v) {
return v.end(); }
561 static const_iterator end(
const this_type &v) {
return v.end(); }
562 static const origin_type* origin(
const this_type &v) {
return v.pr; }
563 static value_type access(
const origin_type *,
const const_iterator &b,
565 if (b.ir == e.ir)
return value_type(0);
566 PT2 p = std::lower_bound(b.ir, e.ir, i+shift);
567 return (*p == i+shift && p != e.ir) ? b.pr[p-b.ir] : value_type(0);
571 template <
typename PT1,
typename PT2,
int shift>
572 std::ostream &
operator <<
573 (std::ostream &o,
const cs_vector_ref<PT1, PT2, shift>& m)
574 { gmm::write(o,m);
return o; }
576 template <
typename PT1,
typename PT2,
int shift>
577 inline size_type nnz(
const cs_vector_ref<PT1, PT2, shift>& l) {
return l.n; }
583 template <
typename PT1,
typename PT2,
typename PT3,
int shift = 0>
584 struct sparse_compressed_iterator {
585 typedef typename std::iterator_traits<PT1>::value_type value_type;
586 typedef const value_type *pointer;
587 typedef const value_type &reference;
588 typedef ptrdiff_t difference_type;
590 typedef std::random_access_iterator_tag iterator_category;
591 typedef sparse_compressed_iterator<PT1, PT2, PT3, shift> iterator;
597 const value_type *origin;
599 iterator operator ++(
int) { iterator tmp = *
this; jc++;
return tmp; }
600 iterator operator --(
int) { iterator tmp = *
this; jc--;
return tmp; }
601 iterator &operator ++() { jc++;
return *
this; }
602 iterator &operator --() { jc--;
return *
this; }
603 iterator &operator +=(difference_type i) { jc += i;
return *
this; }
604 iterator &operator -=(difference_type i) { jc -= i;
return *
this; }
606 { iterator itt = *
this;
return (itt += i); }
608 { iterator itt = *
this;
return (itt -= i); }
609 difference_type
operator -(
const iterator &i)
const {
return jc - i.jc; }
611 reference operator *()
const {
return pr + *jc - shift; }
612 reference operator [](
int ii) {
return pr + *(jc+ii) - shift; }
614 bool operator ==(
const iterator &i)
const {
return (jc == i.jc); }
615 bool operator !=(
const iterator &i)
const {
return !(i == *
this); }
616 bool operator < (
const iterator &i)
const {
return (jc < i.jc); }
618 sparse_compressed_iterator(
void) {}
619 sparse_compressed_iterator(PT1 p1, PT2 p2, PT3 p3,
size_type nn,
621 : pr(p1), ir(p2), jc(p3), n(nn), origin(o) { }
625 template <
typename PT1,
typename PT2,
typename PT3,
int shift = 0>
626 struct csc_matrix_ref {
632 typedef typename std::iterator_traits<PT1>::value_type value_type;
634 : pr(pt1), ir(pt2), jc(pt3), nc(ncc), nr(nrr) {}
635 csc_matrix_ref(
void) {}
637 size_type nrows(
void)
const {
return nr; }
638 size_type ncols(
void)
const {
return nc; }
641 {
return mat_col(*
this, j)[i]; }
644 template <
typename PT1,
typename PT2,
typename PT3,
int shift>
645 struct linalg_traits<csc_matrix_ref<PT1, PT2, PT3, shift> > {
646 typedef csc_matrix_ref<PT1, PT2, PT3, shift> this_type;
647 typedef linalg_const is_reference;
648 typedef abstract_matrix linalg_type;
649 typedef typename std::iterator_traits<PT1>::value_type value_type;
650 typedef typename std::iterator_traits<PT1>::value_type reference;
651 typedef value_type origin_type;
652 typedef abstract_sparse storage_type;
653 typedef abstract_null_type sub_row_type;
654 typedef abstract_null_type const_sub_row_type;
655 typedef abstract_null_type row_iterator;
656 typedef abstract_null_type const_row_iterator;
657 typedef abstract_null_type sub_col_type;
658 typedef cs_vector_ref<typename const_pointer<PT1>::pointer,
659 typename const_pointer<PT2>::pointer, shift> const_sub_col_type;
660 typedef sparse_compressed_iterator<typename const_pointer<PT1>::pointer,
661 typename const_pointer<PT2>::pointer,
662 typename const_pointer<PT3>::pointer,
663 shift> const_col_iterator;
664 typedef abstract_null_type col_iterator;
665 typedef col_major sub_orientation;
666 typedef linalg_true index_sorted;
667 static size_type nrows(
const this_type &m) {
return m.nrows(); }
668 static size_type ncols(
const this_type &m) {
return m.ncols(); }
669 static const_col_iterator col_begin(
const this_type &m)
670 {
return const_col_iterator(m.pr, m.ir, m.jc, m.nr, m.pr); }
671 static const_col_iterator col_end(
const this_type &m)
672 {
return const_col_iterator(m.pr, m.ir, m.jc + m.nc, m.nr, m.pr); }
673 static const_sub_col_type col(
const const_col_iterator &it) {
674 return const_sub_col_type(it.pr + *(it.jc) - shift,
675 it.ir + *(it.jc) - shift, *(it.jc + 1) - *(it.jc), it.n);
677 static const origin_type* origin(
const this_type &m) {
return m.pr; }
678 static value_type access(
const const_col_iterator &itcol,
size_type j)
679 {
return col(itcol)[j]; }
683 template <
typename PT1,
typename PT2,
typename PT3,
int shift>
684 std::ostream &
operator <<
685 (std::ostream &o,
const csc_matrix_ref<PT1, PT2, PT3, shift>& m)
686 { gmm::write(o,m);
return o; }
692 template <
typename PT1,
typename PT2,
typename PT3,
int shift = 0>
693 struct csr_matrix_ref {
699 typedef typename std::iterator_traits<PT1>::value_type value_type;
701 : pr(pt1), ir(pt2), jc(pt3), nc(ncc), nr(nrr) {}
702 csr_matrix_ref(
void) {}
704 size_type nrows(
void)
const {
return nr; }
705 size_type ncols(
void)
const {
return nc; }
708 {
return mat_row(*
this, i)[j]; }
711 template <
typename PT1,
typename PT2,
typename PT3,
int shift>
712 struct linalg_traits<csr_matrix_ref<PT1, PT2, PT3, shift> > {
713 typedef csr_matrix_ref<PT1, PT2, PT3, shift> this_type;
714 typedef linalg_const is_reference;
715 typedef abstract_matrix linalg_type;
716 typedef typename std::iterator_traits<PT1>::value_type value_type;
717 typedef typename std::iterator_traits<PT1>::value_type reference;
718 typedef value_type origin_type;
719 typedef abstract_sparse storage_type;
720 typedef abstract_null_type sub_col_type;
721 typedef abstract_null_type const_sub_col_type;
722 typedef abstract_null_type col_iterator;
723 typedef abstract_null_type const_col_iterator;
724 typedef abstract_null_type sub_row_type;
725 typedef cs_vector_ref<typename const_pointer<PT1>::pointer,
726 typename const_pointer<PT2>::pointer, shift>
728 typedef sparse_compressed_iterator<typename const_pointer<PT1>::pointer,
729 typename const_pointer<PT2>::pointer,
730 typename const_pointer<PT3>::pointer,
731 shift> const_row_iterator;
732 typedef abstract_null_type row_iterator;
733 typedef row_major sub_orientation;
734 typedef linalg_true index_sorted;
735 static size_type nrows(
const this_type &m) {
return m.nrows(); }
736 static size_type ncols(
const this_type &m) {
return m.ncols(); }
737 static const_row_iterator row_begin(
const this_type &m)
738 {
return const_row_iterator(m.pr, m.ir, m.jc, m.nc, m.pr); }
739 static const_row_iterator row_end(
const this_type &m)
740 {
return const_row_iterator(m.pr, m.ir, m.jc + m.nr, m.nc, m.pr); }
741 static const_sub_row_type row(
const const_row_iterator &it) {
742 return const_sub_row_type(it.pr + *(it.jc) - shift,
743 it.ir + *(it.jc) - shift, *(it.jc + 1) - *(it.jc), it.n);
745 static const origin_type* origin(
const this_type &m) {
return m.pr; }
746 static value_type access(
const const_row_iterator &itrow,
size_type j)
747 {
return row(itrow)[j]; }
750 template <
typename PT1,
typename PT2,
typename PT3,
int shift>
751 std::ostream &
operator <<
752 (std::ostream &o,
const csr_matrix_ref<PT1, PT2, PT3, shift>& m)
753 { gmm::write(o,m);
return o; }
761 template <
class PT>
struct array1D_reference {
763 typedef typename std::iterator_traits<PT>::value_type value_type;
767 const value_type &operator[](
size_type i)
const {
return *(begin+i); }
768 value_type &operator[](
size_type i) {
return *(begin+i); }
770 array1D_reference(PT begin_,
size_type s) : begin(begin_), end(begin_+s) {}
773 template <
typename PT>
774 struct linalg_traits<array1D_reference<PT> > {
775 typedef array1D_reference<PT> this_type;
776 typedef this_type origin_type;
777 typedef typename which_reference<PT>::is_reference is_reference;
778 typedef abstract_vector linalg_type;
779 typedef typename std::iterator_traits<PT>::value_type value_type;
780 typedef typename std::iterator_traits<PT>::reference reference;
782 typedef PT const_iterator;
783 typedef abstract_dense storage_type;
784 typedef linalg_true index_sorted;
785 static size_type size(
const this_type &v) {
return v.end - v.begin; }
786 static iterator begin(this_type &v) {
return v.begin; }
787 static const_iterator begin(
const this_type &v) {
return v.begin; }
788 static iterator end(this_type &v) {
return v.end; }
789 static const_iterator end(
const this_type &v) {
return v.end; }
790 static origin_type* origin(this_type &v) {
return &v; }
791 static const origin_type* origin(
const this_type &v) {
return &v; }
792 static void clear(origin_type*,
const iterator &it,
const iterator &ite)
793 { std::fill(it, ite, value_type(0)); }
794 static void do_clear(this_type &v)
795 { std::fill(v.begin, v.end, value_type(0)); }
796 static value_type access(
const origin_type *,
const const_iterator &it,
799 static reference access(origin_type *,
const iterator &it,
803 { GMM_ASSERT1(
false,
"Not resizable vector"); }
806 template<
typename PT> std::ostream &
operator <<
807 (std::ostream &o,
const array1D_reference<PT>& v)
808 { gmm::write(o,v);
return o; }
810 template <
class PT>
struct array2D_col_reference {
812 typedef typename std::iterator_traits<PT>::value_type T;
813 typedef typename std::iterator_traits<PT>::reference reference;
814 typedef typename const_reference<reference>::reference const_reference;
816 typedef typename const_pointer<PT>::pointer const_iterator;
822 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
823 return *(begin_ + c*nbl+l);
826 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
827 return *(begin_ + c*nbl+l);
832 GMM_ASSERT2(n*m == nbl*nbc,
"dimensions mismatch");
836 void fill(T a, T b = T(0)) {
837 std::fill(begin_, begin_+nbc*nbl, b);
838 iterator p = begin_, e = begin_+nbc*nbl;
839 while (p < e) { *p = a; p += nbl+1; }
841 inline size_type nrows(
void)
const {
return nbl; }
842 inline size_type ncols(
void)
const {
return nbc; }
844 iterator begin(
void) {
return begin_; }
845 const_iterator begin(
void)
const {
return begin_; }
846 iterator end(
void) {
return begin_+nbl*nbc; }
847 const_iterator end(
void)
const {
return begin_+nbl*nbc; }
850 : begin_(begin__), nbl(nrows_), nbc(ncols_) {}
853 template <
typename PT>
struct linalg_traits<array2D_col_reference<PT> > {
854 typedef array2D_col_reference<PT> this_type;
855 typedef this_type origin_type;
856 typedef typename which_reference<PT>::is_reference is_reference;
857 typedef abstract_matrix linalg_type;
858 typedef typename std::iterator_traits<PT>::value_type value_type;
859 typedef typename std::iterator_traits<PT>::reference reference;
860 typedef abstract_dense storage_type;
861 typedef tab_ref_reg_spaced_with_origin<
typename this_type::iterator,
862 this_type> sub_row_type;
863 typedef tab_ref_reg_spaced_with_origin<
typename this_type::const_iterator,
864 this_type> const_sub_row_type;
865 typedef dense_compressed_iterator<
typename this_type::iterator,
866 typename this_type::iterator,
867 this_type *> row_iterator;
868 typedef dense_compressed_iterator<
typename this_type::const_iterator,
869 typename this_type::iterator,
870 const this_type *> const_row_iterator;
871 typedef tab_ref_with_origin<
typename this_type::iterator,
872 this_type> sub_col_type;
873 typedef tab_ref_with_origin<
typename this_type::const_iterator,
874 this_type> const_sub_col_type;
875 typedef dense_compressed_iterator<
typename this_type::iterator,
876 typename this_type::iterator,
877 this_type *> col_iterator;
878 typedef dense_compressed_iterator<
typename this_type::const_iterator,
879 typename this_type::iterator,
880 const this_type *> const_col_iterator;
881 typedef col_and_row sub_orientation;
882 typedef linalg_true index_sorted;
883 static size_type nrows(
const this_type &m) {
return m.nrows(); }
884 static size_type ncols(
const this_type &m) {
return m.ncols(); }
885 static const_sub_row_type row(
const const_row_iterator &it)
886 {
return const_sub_row_type(*it, it.nrows, it.ncols, it.origin); }
887 static const_sub_col_type col(
const const_col_iterator &it)
888 {
return const_sub_col_type(*it, *it + it.nrows, it.origin); }
889 static sub_row_type row(
const row_iterator &it)
890 {
return sub_row_type(*it, it.nrows, it.ncols, it.origin); }
891 static sub_col_type col(
const col_iterator &it)
892 {
return sub_col_type(*it, *it + it.nrows, it.origin); }
893 static row_iterator row_begin(this_type &m)
894 {
return row_iterator(m.begin(), 1, m.nrows(), m.ncols(), 0, &m); }
895 static row_iterator row_end(this_type &m)
896 {
return row_iterator(m.begin(), 1, m.nrows(), m.ncols(), m.nrows(), &m); }
897 static const_row_iterator row_begin(
const this_type &m)
898 {
return const_row_iterator(m.begin(), 1, m.nrows(), m.ncols(), 0, &m); }
899 static const_row_iterator row_end(
const this_type &m) {
900 return const_row_iterator(m.begin(), 1, m.nrows(),
901 m.ncols(), m.nrows(), &m);
903 static col_iterator col_begin(this_type &m)
904 {
return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); }
905 static col_iterator col_end(this_type &m) {
906 return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(),
909 static const_col_iterator col_begin(
const this_type &m) {
910 return const_col_iterator(m.begin(), m.nrows(), m.nrows(),
913 static const_col_iterator col_end(
const this_type &m) {
914 return const_col_iterator(m.begin(), m.nrows(),m.nrows(),m.ncols(),
917 static origin_type* origin(this_type &m) {
return &m; }
918 static const origin_type* origin(
const this_type &m) {
return &m; }
919 static void do_clear(this_type &m) { m.fill(value_type(0)); }
920 static value_type access(
const const_col_iterator &itcol,
size_type j)
921 {
return (*itcol)[j]; }
922 static reference access(
const col_iterator &itcol,
size_type j)
923 {
return (*itcol)[j]; }
930 template<
typename PT> std::ostream &
operator <<
931 (std::ostream &o,
const array2D_col_reference<PT>& m)
932 { gmm::write(o,m);
return o; }
936 template <
class PT>
struct array2D_row_reference {
938 typedef typename std::iterator_traits<PT>::value_type T;
939 typedef typename std::iterator_traits<PT>::reference reference;
940 typedef typename const_reference<reference>::reference const_reference;
942 typedef typename const_pointer<PT>::pointer const_iterator;
948 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
949 return *(begin_ + l*nbc+c);
952 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
953 return *(begin_ + l*nbc+c);
958 GMM_ASSERT2(n*m == nbl*nbc,
"dimensions mismatch");
962 void fill(T a, T b = T(0)) {
963 std::fill(begin_, begin_+nbc*nbl, b);
964 iterator p = begin_, e = begin_+nbc*nbl;
965 while (p < e) { *p = a; p += nbc+1; }
967 inline size_type nrows(
void)
const {
return nbl; }
968 inline size_type ncols(
void)
const {
return nbc; }
970 iterator begin(
void) {
return begin_; }
971 const_iterator begin(
void)
const {
return begin_; }
972 iterator end(
void) {
return begin_+nbl*nbc; }
973 const_iterator end(
void)
const {
return begin_+nbl*nbc; }
976 : begin_(begin__), nbl(nrows_), nbc(ncols_) {}
979 template <
typename PT>
struct linalg_traits<array2D_row_reference<PT> > {
980 typedef array2D_row_reference<PT> this_type;
981 typedef this_type origin_type;
982 typedef typename which_reference<PT>::is_reference is_reference;
983 typedef abstract_matrix linalg_type;
984 typedef typename std::iterator_traits<PT>::value_type value_type;
985 typedef typename std::iterator_traits<PT>::reference reference;
986 typedef abstract_dense storage_type;
987 typedef tab_ref_reg_spaced_with_origin<
typename this_type::iterator,
988 this_type> sub_col_type;
989 typedef tab_ref_reg_spaced_with_origin<
typename this_type::const_iterator,
990 this_type> const_sub_col_type;
991 typedef dense_compressed_iterator<
typename this_type::iterator,
992 typename this_type::iterator,
993 this_type *> col_iterator;
994 typedef dense_compressed_iterator<
typename this_type::const_iterator,
995 typename this_type::iterator,
996 const this_type *> const_col_iterator;
997 typedef tab_ref_with_origin<
typename this_type::iterator,
998 this_type> sub_row_type;
999 typedef tab_ref_with_origin<
typename this_type::const_iterator,
1000 this_type> const_sub_row_type;
1001 typedef dense_compressed_iterator<
typename this_type::iterator,
1002 typename this_type::iterator,
1003 this_type *> row_iterator;
1004 typedef dense_compressed_iterator<
typename this_type::const_iterator,
1005 typename this_type::iterator,
1006 const this_type *> const_row_iterator;
1007 typedef col_and_row sub_orientation;
1008 typedef linalg_true index_sorted;
1009 static size_type ncols(
const this_type &m) {
return m.ncols(); }
1010 static size_type nrows(
const this_type &m) {
return m.nrows(); }
1011 static const_sub_col_type col(
const const_col_iterator &it)
1012 {
return const_sub_col_type(*it, it.ncols, it.nrows, it.origin); }
1013 static const_sub_row_type row(
const const_row_iterator &it)
1014 {
return const_sub_row_type(*it, *it + it.ncols, it.origin); }
1015 static sub_col_type col(
const col_iterator &it)
1016 {
return sub_col_type(*it, *it, it.ncols, it.nrows, it.origin); }
1017 static sub_row_type row(
const row_iterator &it)
1018 {
return sub_row_type(*it, *it + it.ncols, it.origin); }
1019 static col_iterator col_begin(this_type &m)
1020 {
return col_iterator(m.begin(), 1, m.ncols(), m.nrows(), 0, &m); }
1021 static col_iterator col_end(this_type &m)
1022 {
return col_iterator(m.begin(), 1, m.ncols(), m.nrows(), m.ncols(), &m); }
1023 static const_col_iterator col_begin(
const this_type &m)
1024 {
return const_col_iterator(m.begin(), 1, m.ncols(), m.nrows(), 0, &m); }
1025 static const_col_iterator col_end(
const this_type &m) {
1026 return const_col_iterator(m.begin(), 1, m.ncols(),
1027 m.nrows(), m.ncols(), &m);
1029 static row_iterator row_begin(this_type &m)
1030 {
return row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(), 0, &m); }
1031 static row_iterator row_end(this_type &m) {
1032 return row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(),
1035 static const_row_iterator row_begin(
const this_type &m) {
1036 return const_row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(),
1039 static const_row_iterator row_end(
const this_type &m) {
1040 return const_row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(),
1043 static origin_type* origin(this_type &m) {
return &m; }
1044 static const origin_type* origin(
const this_type &m) {
return &m; }
1045 static void do_clear(this_type &m) { m.fill(value_type(0)); }
1046 static value_type access(
const const_row_iterator &itrow,
size_type j)
1047 {
return (*itrow)[j]; }
1048 static reference access(
const row_iterator &itrow,
size_type j)
1049 {
return (*itrow)[j]; }
1053 { v.reshape(m, n); }
1056 template<
typename PT> std::ostream &
operator <<
1057 (std::ostream &o,
const array2D_row_reference<PT>& m)
1058 { gmm::write(o,m);
return o; }
1068 #endif // GMM_INTERFACE_H__