GetFEM  5.4.2
gmm_interface.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2002-2020 Yves Renard
5 
6  This file is a part of GetFEM
7 
8  GetFEM is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program; if not, write to the Free Software Foundation,
19  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, you may use this file as it is a part of a free
22  software library without restriction. Specifically, if other files
23  instantiate templates or use macros or inline functions from this file,
24  or you compile this file and link it with other files to produce an
25  executable, this file does not by itself cause the resulting executable
26  to be covered by the GNU Lesser General Public License. This exception
27  does not however invalidate any other reasons why the executable file
28  might be covered by the GNU Lesser General Public License.
29 
30 ===========================================================================*/
31 
32 
33 /**@file gmm_interface.h
34  @author Yves Renard <Yves.Renard@insa-lyon.fr>
35  @date October 13, 2002.
36  @brief gmm interface for STL vectors.
37 */
38 
39 #ifndef GMM_INTERFACE_H__
40 #define GMM_INTERFACE_H__
41 
42 #include "gmm_blas.h"
43 #include "gmm_sub_index.h"
44 
45 namespace gmm {
46 
47  /* ********************************************************************* */
48  /* */
49  /* What is needed for a Vector type : */
50  /* Vector v(n) defines a vector with n components. */
51  /* v[i] allows to access to the ith component of v. */
52  /* linalg_traits<Vector> should be filled with appropriate definitions */
53  /* */
54  /* for a dense vector : the minimum is two random iterators (begin and */
55  /* end) and a pointer to a valid origin. */
56  /* for a sparse vector : the minimum is two forward iterators, with */
57  /* a method it.index() which gives the index of */
58  /* a non zero element, an interface object */
59  /* should describe the method to add new non */
60  /* zero element, and a pointer to a valid */
61  /* origin. */
62  /* */
63  /* What is needed for a Matrix type : */
64  /* Matrix m(n, m) defines a matrix with n rows and m columns. */
65  /* m(i, j) allows to access to the element at row i and column j. */
66  /* linalg_traits<Matrix> should be filled with appropriate definitions */
67  /* */
68  /* What is needed for an iterator on dense vector */
69  /* to be standard random access iterator */
70  /* */
71  /* What is needed for an iterator on a sparse vector */
72  /* to be a standard bidirectional iterator */
73  /* elt should be sorted with increasing indices. */
74  /* it.index() gives the index of the non-zero element. */
75  /* */
76  /* Remark : If original iterators are not convenient, they could be */
77  /* redefined and interfaced in linalg_traits<Vector> without changing */
78  /* the original Vector type. */
79  /* */
80  /* ********************************************************************* */
81 
82  /* ********************************************************************* */
83  /* Simple references on vectors */
84  /* ********************************************************************* */
85 
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;
89  typedef V * CPT;
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;
94 
95  iterator begin_, end_;
96  porigin_type origin;
97  size_type size_;
98 
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)) {}
103 
104  simple_vector_ref(const simple_vector_ref<CPT> &cr)
105  : begin_(cr.begin_),end_(cr.end_),origin(cr.origin),size_(cr.size_) {}
106 
107  simple_vector_ref(void) {}
108 
109  reference operator[](size_type i) const
110  { return linalg_traits<V>::access(origin, begin_, end_, i); }
111  };
112 
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());
117  }
118 
119  template <typename IT, typename ORG, typename PT> inline
120  void set_to_begin(IT &it, ORG o, const simple_vector_ref<PT> *,
121  linalg_modifiable) {
122  typedef typename linalg_traits<simple_vector_ref<PT> >::V_reference ref_t;
123  set_to_begin(it, o, PT(), ref_t());
124  }
125 
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());
130  }
131 
132  template <typename IT, typename ORG, typename PT> inline
133  void set_to_end(IT &it, ORG o, const simple_vector_ref<PT> *,
134  linalg_modifiable) {
135  typedef typename linalg_traits<simple_vector_ref<PT> >::V_reference ref_t;
136  set_to_end(it, o, PT(), ref_t());
137  }
138 
139 
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;
145  typedef V *pV;
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());
163  return it;
164  }
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());
168  return it;
169  }
170  static inline iterator end(this_type &v) {
171  iterator it = v.end_;
172  set_to_end(it, v.origin, pthis_type(), is_reference());
173  return it;
174  }
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());
178  return it;
179  }
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,
186  const const_iterator &ite, size_type i)
187  { return linalg_traits<V>::access(o, it, ite, i); }
188  static reference access(origin_type *o, const iterator &it,
189  const iterator &ite, size_type i)
190  { return linalg_traits<V>::access(o, it, ite, i); }
191  };
192 
193  template <typename PT>
194  std::ostream &operator << (std::ostream &o, const simple_vector_ref<PT>& v)
195  { gmm::write(o,v); return o; }
196 
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); }
201 
202 
203  /* ********************************************************************* */
204  /* */
205  /* Traits for S.T.L. object */
206  /* */
207  /* ********************************************************************* */
208 
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,
232  const const_iterator &, size_type i)
233  { return it[i]; }
234  static reference access(origin_type *, const iterator &it,
235  const iterator &, size_type i)
236  { return it[i]; }
237  static void resize(this_type &v, size_type n) { v.resize(n); }
238  };
239 
240 
241 
242  template <typename T>
243  inline size_type nnz(const std::vector<T>& l) { return l.size(); }
244 
245  /* ********************************************************************* */
246  /* */
247  /* Traits for ref objects */
248  /* */
249  /* ********************************************************************* */
250 
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;
254  // next line replaced by the 4 following lines in order to please aCC
255  //typedef typename linalg_traits<this_type>::porigin_type porigin_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;
260 
261 
262  porigin_type origin;
263 
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) {}
269 
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))) {}
278  };
279 
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,
307  const const_iterator &, size_type i)
308  { return it[i]; }
309  static reference access(origin_type *, const iterator &it,
310  const iterator &, size_type i)
311  { return it[i]; }
312  };
313 
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; }
317 
318 
319  template <typename IT, typename V>
320  struct tab_ref_reg_spaced_with_origin : public gmm::tab_ref_reg_spaced<IT> {
321  typedef tab_ref_reg_spaced_with_origin<IT, V> this_type;
322  typedef typename linalg_traits<this_type>::porigin_type porigin_type;
323 
324  porigin_type origin;
325 
326  tab_ref_reg_spaced_with_origin(void) {}
327  tab_ref_reg_spaced_with_origin(const IT &b, size_type n, size_type s,
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))) {}
338  };
339 
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,
367  const const_iterator &, size_type i)
368  { return it[i]; }
369  static reference access(origin_type *, const iterator &it,
370  const iterator &, size_type i)
371  { return it[i]; }
372  };
373 
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; }
377 
378 
379  template <typename IT, typename ITINDEX, typename V>
380  struct tab_ref_index_ref_with_origin
381  : public gmm::tab_ref_index_ref<IT, ITINDEX> {
382  typedef tab_ref_index_ref_with_origin<IT, ITINDEX, V> this_type;
383  typedef typename linalg_traits<this_type>::porigin_type porigin_type;
384 
385  porigin_type origin;
386 
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) {}
391 
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))) {}
400  };
401 
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,
429  const const_iterator &, size_type i)
430  { return it[i]; }
431  static reference access(origin_type *, const iterator &it,
432  const iterator &, size_type i)
433  { return it[i]; }
434  };
435 
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; }
440 
441 
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;
449  typedef size_t size_type;
450  typedef dense_compressed_iterator<ITER, MIT, PT> iterator;
451  typedef typename std::iterator_traits<PT>::value_type *MPT;
452 
453  ITER it;
454  size_type N, nrows, ncols, i;
455  PT origin;
456 
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; }
463  iterator operator +(difference_type ii) const
464  { iterator itt = *this; return (itt += ii); }
465  iterator operator -(difference_type ii) const
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; }
469 
470  ITER operator *() const { return it+i*N; }
471  ITER operator [](int ii) const { return it + (i+ii) * N; }
472 
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); }
478 
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),
482  origin(ii.origin) {}
483  dense_compressed_iterator(const ITER &iter, size_type n, size_type r,
484  size_type c, size_type ii, PT o)
485  : it(iter), N(n), nrows(r), ncols(c), i(ii), origin(o) { }
486 
487  };
488 
489  /* ******************************************************************** */
490  /* Read only reference on a compressed sparse vector */
491  /* ******************************************************************** */
492 
493  template <typename PT1, typename PT2, int shift = 0>
494  struct cs_vector_ref_iterator {
495  PT1 pr;
496  PT2 ir;
497 
498  typedef typename std::iterator_traits<PT1>::value_type value_type;
499  typedef PT1 pointer;
500  typedef typename std::iterator_traits<PT1>::reference reference;
501  typedef size_t size_type;
502  typedef ptrdiff_t difference_type;
503  typedef std::bidirectional_iterator_tag iterator_category;
504  typedef cs_vector_ref_iterator<PT1, PT2, shift> iterator;
505 
506  cs_vector_ref_iterator(void) {}
507  cs_vector_ref_iterator(PT1 p1, PT2 p2) : pr(p1), ir(p2) {}
508 
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; }
514 
515  reference operator *() const { return *pr; }
516  pointer operator ->() const { return pr; }
517 
518  bool operator ==(const iterator &i) const { return (i.pr==pr);}
519  bool operator !=(const iterator &i) const { return (i.pr!=pr);}
520  };
521 
522  template <typename PT1, typename PT2, int shift = 0> struct cs_vector_ref {
523  PT1 pr;
524  PT2 ir;
525  size_type n, size_;
526 
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;
530 
531  cs_vector_ref(PT1 pt1, PT2 pt2, size_type nnz, size_type ns)
532  : pr(pt1), ir(pt2), n(nnz), size_(ns) {}
533  cs_vector_ref(void) {}
534 
535  size_type size(void) const { return size_; }
536 
537  const_iterator begin(void) const { return const_iterator(pr, ir); }
538  const_iterator end(void) const { return const_iterator(pr+n, ir+n); }
539 
540  value_type operator[](size_type i) const
541  { return linalg_traits<this_type>::access(pr, begin(), end(),i); }
542  };
543 
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,
564  const const_iterator &e, size_type i) {
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);
568  }
569  };
570 
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; }
575 
576  template <typename PT1, typename PT2, int shift>
577  inline size_type nnz(const cs_vector_ref<PT1, PT2, shift>& l) { return l.n; }
578 
579  /* ******************************************************************** */
580  /* Read only reference on a compressed sparse column matrix */
581  /* ******************************************************************** */
582 
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;
589  typedef size_t size_type;
590  typedef std::random_access_iterator_tag iterator_category;
591  typedef sparse_compressed_iterator<PT1, PT2, PT3, shift> iterator;
592 
593  PT1 pr;
594  PT2 ir;
595  PT3 jc;
596  size_type n;
597  const value_type *origin;
598 
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; }
605  iterator operator +(difference_type i) const
606  { iterator itt = *this; return (itt += i); }
607  iterator operator -(difference_type i) const
608  { iterator itt = *this; return (itt -= i); }
609  difference_type operator -(const iterator &i) const { return jc - i.jc; }
610 
611  reference operator *() const { return pr + *jc - shift; }
612  reference operator [](int ii) { return pr + *(jc+ii) - shift; }
613 
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); }
617 
618  sparse_compressed_iterator(void) {}
619  sparse_compressed_iterator(PT1 p1, PT2 p2, PT3 p3, size_type nn,
620  const value_type *o)
621  : pr(p1), ir(p2), jc(p3), n(nn), origin(o) { }
622 
623  };
624 
625  template <typename PT1, typename PT2, typename PT3, int shift = 0>
626  struct csc_matrix_ref {
627  PT1 pr; // values.
628  PT2 ir; // row indexes.
629  PT3 jc; // column repartition on pr and ir.
630  size_type nc, nr;
631 
632  typedef typename std::iterator_traits<PT1>::value_type value_type;
633  csc_matrix_ref(PT1 pt1, PT2 pt2, PT3 pt3, size_type nrr, size_type ncc)
634  : pr(pt1), ir(pt2), jc(pt3), nc(ncc), nr(nrr) {}
635  csc_matrix_ref(void) {}
636 
637  size_type nrows(void) const { return nr; }
638  size_type ncols(void) const { return nc; }
639 
640  value_type operator()(size_type i, size_type j) const
641  { return mat_col(*this, j)[i]; }
642  };
643 
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);
676  }
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]; }
680  };
681 
682 
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; }
687 
688  /* ******************************************************************** */
689  /* Read only reference on a compressed sparse row matrix */
690  /* ******************************************************************** */
691 
692  template <typename PT1, typename PT2, typename PT3, int shift = 0>
693  struct csr_matrix_ref {
694  PT1 pr; // values.
695  PT2 ir; // column indexes.
696  PT3 jc; // row repartition on pr and ir.
697  size_type nc, nr;
698 
699  typedef typename std::iterator_traits<PT1>::value_type value_type;
700  csr_matrix_ref(PT1 pt1, PT2 pt2, PT3 pt3, size_type nrr, size_type ncc)
701  : pr(pt1), ir(pt2), jc(pt3), nc(ncc), nr(nrr) {}
702  csr_matrix_ref(void) {}
703 
704  size_type nrows(void) const { return nr; }
705  size_type ncols(void) const { return nc; }
706 
707  value_type operator()(size_type i, size_type j) const
708  { return mat_row(*this, i)[j]; }
709  };
710 
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>
727  const_sub_row_type;
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);
744  }
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]; }
748  };
749 
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; }
754 
755  /* ********************************************************************* */
756  /* */
757  /* Simple interface for C arrays */
758  /* */
759  /* ********************************************************************* */
760 
761  template <class PT> struct array1D_reference {
762 
763  typedef typename std::iterator_traits<PT>::value_type value_type;
764 
765  PT begin, end;
766 
767  const value_type &operator[](size_type i) const { return *(begin+i); }
768  value_type &operator[](size_type i) { return *(begin+i); }
769 
770  array1D_reference(PT begin_, size_type s) : begin(begin_), end(begin_+s) {}
771  };
772 
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;
781  typedef PT iterator;
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,
797  const const_iterator &, size_type i)
798  { return it[i]; }
799  static reference access(origin_type *, const iterator &it,
800  const iterator &, size_type i)
801  { return it[i]; }
802  static void resize(this_type &, size_type )
803  { GMM_ASSERT1(false, "Not resizable vector"); }
804  };
805 
806  template<typename PT> std::ostream &operator <<
807  (std::ostream &o, const array1D_reference<PT>& v)
808  { gmm::write(o,v); return o; }
809 
810  template <class PT> struct array2D_col_reference {
811 
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;
815  typedef PT iterator;
816  typedef typename const_pointer<PT>::pointer const_iterator;
817 
818  PT begin_;
819  size_type nbl, nbc;
820 
821  inline const_reference operator ()(size_type l, size_type c) const {
822  GMM_ASSERT2(l < nbl && c < nbc, "out of range");
823  return *(begin_ + c*nbl+l);
824  }
825  inline reference operator ()(size_type l, size_type c) {
826  GMM_ASSERT2(l < nbl && c < nbc, "out of range");
827  return *(begin_ + c*nbl+l);
828  }
829 
830  void resize(size_type, size_type);
831  void reshape(size_type m, size_type n) {
832  GMM_ASSERT2(n*m == nbl*nbc, "dimensions mismatch");
833  nbl = m; nbc = n;
834  }
835 
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; }
840  }
841  inline size_type nrows(void) const { return nbl; }
842  inline size_type ncols(void) const { return nbc; }
843 
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; }
848 
849  array2D_col_reference(PT begin__, size_type nrows_, size_type ncols_)
850  : begin_(begin__), nbl(nrows_), nbc(ncols_) {}
851  };
852 
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);
902  }
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(),
907  m.ncols(), &m);
908  }
909  static const_col_iterator col_begin(const this_type &m) {
910  return const_col_iterator(m.begin(), m.nrows(), m.nrows(),
911  m.ncols(), 0, &m);
912  }
913  static const_col_iterator col_end(const this_type &m) {
914  return const_col_iterator(m.begin(), m.nrows(),m.nrows(),m.ncols(),
915  m.ncols(), &m);
916  }
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]; }
924  static void resize(this_type &v, size_type m, size_type n)
925  { v.resize(m,n); }
926  static void reshape(this_type &v, size_type m, size_type n)
927  { v.reshape(m, n); }
928  };
929 
930  template<typename PT> std::ostream &operator <<
931  (std::ostream &o, const array2D_col_reference<PT>& m)
932  { gmm::write(o,m); return o; }
933 
934 
935 
936  template <class PT> struct array2D_row_reference {
937 
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;
941  typedef PT iterator;
942  typedef typename const_pointer<PT>::pointer const_iterator;
943 
944  PT begin_;
945  size_type nbl, nbc;
946 
947  inline const_reference operator ()(size_type l, size_type c) const {
948  GMM_ASSERT2(l < nbl && c < nbc, "out of range");
949  return *(begin_ + l*nbc+c);
950  }
951  inline reference operator ()(size_type l, size_type c) {
952  GMM_ASSERT2(l < nbl && c < nbc, "out of range");
953  return *(begin_ + l*nbc+c);
954  }
955 
956  void resize(size_type, size_type);
957  void reshape(size_type m, size_type n) {
958  GMM_ASSERT2(n*m == nbl*nbc, "dimensions mismatch");
959  nbl = m; nbc = n;
960  }
961 
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; }
966  }
967  inline size_type nrows(void) const { return nbl; }
968  inline size_type ncols(void) const { return nbc; }
969 
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; }
974 
975  array2D_row_reference(PT begin__, size_type nrows_, size_type ncols_)
976  : begin_(begin__), nbl(nrows_), nbc(ncols_) {}
977  };
978 
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);
1028  }
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(),
1033  m.nrows(), &m);
1034  }
1035  static const_row_iterator row_begin(const this_type &m) {
1036  return const_row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(),
1037  0, &m);
1038  }
1039  static const_row_iterator row_end(const this_type &m) {
1040  return const_row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(),
1041  m.nrows(), &m);
1042  }
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]; }
1050  static void resize(this_type &v, size_type m, size_type n)
1051  { v.resize(m,n); }
1052  static void reshape(this_type &v, size_type m, size_type n)
1053  { v.reshape(m, n); }
1054  };
1055 
1056  template<typename PT> std::ostream &operator <<
1057  (std::ostream &o, const array2D_row_reference<PT>& m)
1058  { gmm::write(o,m); return o; }
1059 
1060 
1061 
1062 
1063 
1064 
1065 }
1066 
1067 
1068 #endif // GMM_INTERFACE_H__
gmm::tab_ref_reg_spaced
provide a "strided" view a of container
Definition: gmm_ref.h:407
gmm::fill
void fill(L &l, typename gmm::linalg_traits< L >::value_type x)
*‍/
Definition: gmm_blas.h:103
bgeot::size_type
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
gmm::clear
void clear(L &l)
clear (fill with zeros) a vector or matrix.
Definition: gmm_blas.h:59
gmm_sub_index.h
sub-indices.
gmm::resize
void resize(V &v, size_type n)
*‍/
Definition: gmm_blas.h:209
bgeot::operator+
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:749
gmm::reshape
void reshape(M &v, size_type m, size_type n)
*‍/
Definition: gmm_blas.h:250
gmm::nnz
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
Definition: gmm_blas.h:68
gmm_blas.h
Basic linear algebra functions.
bgeot::operator-
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:756
gmm::tab_ref_index_ref
indexed array reference (given a container X, and a set of indexes I, this class provides a pseudo-co...
Definition: gmm_ref.h:289