GetFEM++  5.3
gmm_sub_matrix.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2002-2017 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 /**@file gmm_sub_matrix.h
33  @author Yves Renard <Yves.Renard@insa-lyon.fr>
34  @date October 13, 2002.
35  @brief Generic sub-matrices.
36 */
37 
38 #ifndef GMM_SUB_MATRIX_H__
39 #define GMM_SUB_MATRIX_H__
40 
41 #include "gmm_sub_vector.h"
42 
43 namespace gmm {
44 
45  /* ********************************************************************* */
46  /* sub row matrices type */
47  /* ********************************************************************* */
48 
49  template <typename PT, typename SUBI1, typename SUBI2>
50  struct gen_sub_row_matrix {
51  typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
52  typedef typename std::iterator_traits<PT>::value_type M;
53  typedef M * CPT;
54  typedef typename std::iterator_traits<PT>::reference ref_M;
55  typedef typename select_ref<typename linalg_traits<M>
56  ::const_row_iterator, typename linalg_traits<M>::row_iterator,
57  PT>::ref_type iterator;
58  typedef typename linalg_traits<this_type>::reference reference;
59  typedef typename linalg_traits<this_type>::porigin_type porigin_type;
60 
61  SUBI1 si1;
62  SUBI2 si2;
63  iterator begin_;
64  porigin_type origin;
65 
66  reference operator()(size_type i, size_type j) const
67  { return linalg_traits<M>::access(begin_ + si1.index(i), si2.index(j)); }
68 
69  size_type nrows(void) const { return si1.size(); }
70  size_type ncols(void) const { return si2.size(); }
71 
72  gen_sub_row_matrix(ref_M m, const SUBI1 &s1, const SUBI2 &s2)
73  : si1(s1), si2(s2), begin_(mat_row_begin(m)),
74  origin(linalg_origin(m)) {}
75  gen_sub_row_matrix() {}
76  gen_sub_row_matrix(const gen_sub_row_matrix<CPT, SUBI1, SUBI2> &cr) :
77  si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
78  };
79 
80  template <typename PT, typename SUBI1, typename SUBI2>
81  struct gen_sub_row_matrix_iterator {
82  typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
83  typedef typename modifiable_pointer<PT>::pointer MPT;
84  typedef typename std::iterator_traits<PT>::value_type M;
85  typedef typename select_ref<typename linalg_traits<M>
86  ::const_row_iterator, typename linalg_traits<M>::row_iterator,
87  PT>::ref_type ITER;
88  typedef ITER value_type;
89  typedef ITER *pointer;
90  typedef ITER &reference;
91  typedef ptrdiff_t difference_type;
92  typedef size_t size_type;
93  typedef std::random_access_iterator_tag iterator_category;
94  typedef gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2> iterator;
95 
96  ITER it;
97  SUBI1 si1;
98  SUBI2 si2;
99  size_type ii;
100 
101  iterator operator ++(int) { iterator tmp = *this; ii++; return tmp; }
102  iterator operator --(int) { iterator tmp = *this; ii--; return tmp; }
103  iterator &operator ++() { ii++; return *this; }
104  iterator &operator --() { ii--; return *this; }
105  iterator &operator +=(difference_type i) { ii += i; return *this; }
106  iterator &operator -=(difference_type i) { ii -= i; return *this; }
107  iterator operator +(difference_type i) const
108  { iterator itt = *this; return (itt += i); }
109  iterator operator -(difference_type i) const
110  { iterator itt = *this; return (itt -= i); }
111  difference_type operator -(const iterator &i) const { return ii - i.ii; }
112 
113  ITER operator *() const { return it + si1.index(ii); }
114  ITER operator [](int i) { return it + si1.index(ii+i); }
115 
116  bool operator ==(const iterator &i) const { return (ii == i.ii); }
117  bool operator !=(const iterator &i) const { return !(i == *this); }
118  bool operator < (const iterator &i) const { return (ii < i.ii); }
119 
120  gen_sub_row_matrix_iterator(void) {}
121  gen_sub_row_matrix_iterator(const
122  gen_sub_row_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
123  : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
124  gen_sub_row_matrix_iterator(const ITER &iter, const SUBI1 &s1,
125  const SUBI2 &s2, size_type i)
126  : it(iter), si1(s1), si2(s2), ii(i) { }
127 
128  };
129 
130  template <typename PT, typename SUBI1, typename SUBI2>
131  struct linalg_traits<gen_sub_row_matrix<PT, SUBI1, SUBI2> > {
132  typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
133  typedef typename std::iterator_traits<PT>::value_type M;
134  typedef typename which_reference<PT>::is_reference is_reference;
135  typedef abstract_matrix linalg_type;
136  typedef typename linalg_traits<M>::origin_type origin_type;
137  typedef typename select_ref<const origin_type *, origin_type *,
138  PT>::ref_type porigin_type;
139  typedef typename linalg_traits<M>::value_type value_type;
140  typedef typename select_ref<value_type,
141  typename linalg_traits<M>::reference, PT>::ref_type reference;
142  typedef abstract_null_type sub_col_type;
143  typedef abstract_null_type col_iterator;
144  typedef abstract_null_type const_sub_col_type;
145  typedef abstract_null_type const_col_iterator;
146  typedef typename sub_vector_type<const typename org_type<typename
147  linalg_traits<M>::const_sub_row_type>::t *, SUBI2>::vector_type
148  const_sub_row_type;
149  typedef typename select_ref<abstract_null_type,
150  typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_row_type>::t *,
151  SUBI2>::vector_type, PT>::ref_type sub_row_type;
152  typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
153  SUBI1, SUBI2> const_row_iterator;
154  typedef typename select_ref<abstract_null_type,
155  gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
156  row_iterator;
157  typedef typename linalg_traits<const_sub_row_type>::storage_type
158  storage_type;
159  typedef row_major sub_orientation;
160  typedef linalg_true index_sorted;
161  static size_type nrows(const this_type &m) { return m.nrows(); }
162  static size_type ncols(const this_type &m) { return m.ncols(); }
163  static const_sub_row_type row(const const_row_iterator &it)
164  { return const_sub_row_type(linalg_traits<M>::row(*it), it.si2); }
165  static sub_row_type row(const row_iterator &it)
166  { return sub_row_type(linalg_traits<M>::row(*it), it.si2); }
167  static const_row_iterator row_begin(const this_type &m)
168  { return const_row_iterator(m.begin_, m.si1, m.si2, 0); }
169  static row_iterator row_begin(this_type &m)
170  { return row_iterator(m.begin_, m.si1, m.si2, 0); }
171  static const_row_iterator row_end(const this_type &m)
172  { return const_row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
173  static row_iterator row_end(this_type &m)
174  { return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
175  static origin_type* origin(this_type &v) { return v.origin; }
176  static const origin_type* origin(const this_type &v) { return v.origin; }
177  static void do_clear(this_type &m) {
178  row_iterator it = mat_row_begin(m), ite = mat_row_end(m);
179  for (; it != ite; ++it) clear(row(it));
180  }
181  static value_type access(const const_row_iterator &itrow, size_type i)
182  { return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
183  static reference access(const row_iterator &itrow, size_type i)
184  { return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
185  };
186 
187  template <typename PT, typename SUBI1, typename SUBI2>
188  std::ostream &operator <<(std::ostream &o,
189  const gen_sub_row_matrix<PT, SUBI1, SUBI2>& m)
190  { gmm::write(o,m); return o; }
191 
192 
193  /* ********************************************************************* */
194  /* sub column matrices type */
195  /* ********************************************************************* */
196 
197  template <typename PT, typename SUBI1, typename SUBI2>
198  struct gen_sub_col_matrix {
199  typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
200  typedef typename std::iterator_traits<PT>::value_type M;
201  typedef M * CPT;
202  typedef typename std::iterator_traits<PT>::reference ref_M;
203  typedef typename select_ref<typename linalg_traits<M>
204  ::const_col_iterator, typename linalg_traits<M>::col_iterator,
205  PT>::ref_type iterator;
206  typedef typename linalg_traits<this_type>::reference reference;
207  typedef typename linalg_traits<this_type>::porigin_type porigin_type;
208 
209  SUBI1 si1;
210  SUBI2 si2;
211  iterator begin_;
212  porigin_type origin;
213 
214  reference operator()(size_type i, size_type j) const
215  { return linalg_traits<M>::access(begin_ + si2.index(j), si1.index(i)); }
216 
217  size_type nrows(void) const { return si1.size(); }
218  size_type ncols(void) const { return si2.size(); }
219 
220  gen_sub_col_matrix(ref_M m, const SUBI1 &s1, const SUBI2 &s2)
221  : si1(s1), si2(s2), begin_(mat_col_begin(m)),
222  origin(linalg_origin(m)) {}
223  gen_sub_col_matrix() {}
224  gen_sub_col_matrix(const gen_sub_col_matrix<CPT, SUBI1, SUBI2> &cr) :
225  si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
226  };
227 
228  template <typename PT, typename SUBI1, typename SUBI2>
229  struct gen_sub_col_matrix_iterator {
230  typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
231  typedef typename modifiable_pointer<PT>::pointer MPT;
232  typedef typename std::iterator_traits<PT>::value_type M;
233  typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
234  typename linalg_traits<M>::col_iterator,
235  PT>::ref_type ITER;
236  typedef ITER value_type;
237  typedef ITER *pointer;
238  typedef ITER &reference;
239  typedef ptrdiff_t difference_type;
240  typedef size_t size_type;
241  typedef std::random_access_iterator_tag iterator_category;
242  typedef gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2> iterator;
243 
244  ITER it;
245  SUBI1 si1;
246  SUBI2 si2;
247  size_type ii;
248 
249  iterator operator ++(int) { iterator tmp = *this; ii++; return tmp; }
250  iterator operator --(int) { iterator tmp = *this; ii--; return tmp; }
251  iterator &operator ++() { ii++; return *this; }
252  iterator &operator --() { ii--; return *this; }
253  iterator &operator +=(difference_type i) { ii += i; return *this; }
254  iterator &operator -=(difference_type i) { ii -= i; return *this; }
255  iterator operator +(difference_type i) const
256  { iterator itt = *this; return (itt += i); }
257  iterator operator -(difference_type i) const
258  { iterator itt = *this; return (itt -= i); }
259  difference_type operator -(const iterator &i) const { return ii - i.ii; }
260 
261  ITER operator *() const { return it + si2.index(ii); }
262  ITER operator [](int i) { return it + si2.index(ii+i); }
263 
264  bool operator ==(const iterator &i) const { return (ii == i.ii); }
265  bool operator !=(const iterator &i) const { return !(i == *this); }
266  bool operator < (const iterator &i) const { return (ii < i.ii); }
267 
268  gen_sub_col_matrix_iterator(void) {}
269  gen_sub_col_matrix_iterator(const
270  gen_sub_col_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
271  : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
272  gen_sub_col_matrix_iterator(const ITER &iter, const SUBI1 &s1,
273  const SUBI2 &s2, size_type i)
274  : it(iter), si1(s1), si2(s2), ii(i) { }
275  };
276 
277  template <typename PT, typename SUBI1, typename SUBI2>
278  struct linalg_traits<gen_sub_col_matrix<PT, SUBI1, SUBI2> > {
279  typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
280  typedef typename std::iterator_traits<PT>::value_type M;
281  typedef typename linalg_traits<M>::origin_type origin_type;
282  typedef typename select_ref<const origin_type *, origin_type *,
283  PT>::ref_type porigin_type;
284  typedef typename which_reference<PT>::is_reference is_reference;
285  typedef abstract_matrix linalg_type;
286  typedef typename linalg_traits<M>::value_type value_type;
287  typedef typename select_ref<value_type,
288  typename linalg_traits<M>::reference, PT>::ref_type reference;
289  typedef abstract_null_type sub_row_type;
290  typedef abstract_null_type row_iterator;
291  typedef abstract_null_type const_sub_row_type;
292  typedef abstract_null_type const_row_iterator;
293  typedef typename sub_vector_type<const typename org_type<typename linalg_traits<M>::const_sub_col_type>::t *, SUBI1>::vector_type const_sub_col_type;
294  typedef typename select_ref<abstract_null_type, typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_col_type>::t *, SUBI1>::vector_type, PT>::ref_type sub_col_type;
295  typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
296  SUBI1, SUBI2> const_col_iterator;
297  typedef typename select_ref<abstract_null_type,
298  gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
299  col_iterator;
300  typedef col_major sub_orientation;
301  typedef linalg_true index_sorted;
302  typedef typename linalg_traits<const_sub_col_type>::storage_type
303  storage_type;
304  static size_type nrows(const this_type &m) { return m.nrows(); }
305  static size_type ncols(const this_type &m) { return m.ncols(); }
306  static const_sub_col_type col(const const_col_iterator &it)
307  { return const_sub_col_type(linalg_traits<M>::col(*it), it.si1); }
308  static sub_col_type col(const col_iterator &it)
309  { return sub_col_type(linalg_traits<M>::col(*it), it.si1); }
310  static const_col_iterator col_begin(const this_type &m)
311  { return const_col_iterator(m.begin_, m.si1, m.si2, 0); }
312  static col_iterator col_begin(this_type &m)
313  { return col_iterator(m.begin_, m.si1, m.si2, 0); }
314  static const_col_iterator col_end(const this_type &m)
315  { return const_col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
316  static col_iterator col_end(this_type &m)
317  { return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
318  static origin_type* origin(this_type &v) { return v.origin; }
319  static const origin_type* origin(const this_type &v) { return v.origin; }
320  static void do_clear(this_type &m) {
321  col_iterator it = mat_col_begin(m), ite = mat_col_end(m);
322  for (; it != ite; ++it) clear(col(it));
323  }
324  static value_type access(const const_col_iterator &itcol, size_type i)
325  { return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
326  static reference access(const col_iterator &itcol, size_type i)
327  { return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
328  };
329 
330  template <typename PT, typename SUBI1, typename SUBI2> std::ostream &operator <<
331  (std::ostream &o, const gen_sub_col_matrix<PT, SUBI1, SUBI2>& m)
332  { gmm::write(o,m); return o; }
333 
334  /* ******************************************************************** */
335  /* sub matrices */
336  /* ******************************************************************** */
337 
338  template <typename PT, typename SUBI1, typename SUBI2, typename ST>
339  struct sub_matrix_type_ {
340  typedef abstract_null_type return_type;
341  };
342  template <typename PT, typename SUBI1, typename SUBI2>
343  struct sub_matrix_type_<PT, SUBI1, SUBI2, col_major>
344  { typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> matrix_type; };
345  template <typename PT, typename SUBI1, typename SUBI2>
346  struct sub_matrix_type_<PT, SUBI1, SUBI2, row_major>
347  { typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> matrix_type; };
348  template <typename PT, typename SUBI1, typename SUBI2>
349  struct sub_matrix_type {
350  typedef typename std::iterator_traits<PT>::value_type M;
351  typedef typename sub_matrix_type_<PT, SUBI1, SUBI2,
352  typename principal_orientation_type<typename
353  linalg_traits<M>::sub_orientation>::potype>::matrix_type matrix_type;
354  };
355 
356  template <typename M, typename SUBI1, typename SUBI2> inline
357  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
358  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
359  M *>::return_type
360  sub_matrix(M &m, const SUBI1 &si1, const SUBI2 &si2) {
361  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
362  "sub matrix too large");
363  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
364  SUBI2>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>
365  ::matrix_type, M *>::return_type(linalg_cast(m), si1, si2);
366  }
367 
368  template <typename M, typename SUBI1, typename SUBI2> inline
369  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
370  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
371  const M *>::return_type
372  sub_matrix(const M &m, const SUBI1 &si1, const SUBI2 &si2) {
373  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
374  "sub matrix too large");
375  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
376  SUBI2>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>
377  ::matrix_type, const M *>::return_type(linalg_cast(m), si1, si2);
378  }
379 
380  template <typename M, typename SUBI1> inline
381  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
382  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
383  M *>::return_type
384  sub_matrix(M &m, const SUBI1 &si1) {
385  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
386  "sub matrix too large");
387  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
388  SUBI1>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>
389  ::matrix_type, M *>::return_type(linalg_cast(m), si1, si1);
390  }
391 
392  template <typename M, typename SUBI1> inline
393  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
394  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
395  const M *>::return_type
396  sub_matrix(const M &m, const SUBI1 &si1) {
397  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
398  "sub matrix too large");
399  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
400  SUBI1>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>
401  ::matrix_type, const M *>::return_type(linalg_cast(m), si1, si1);
402  }
403 
404 }
405 
406 #endif // GMM_SUB_MATRIX_H__
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:750
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:757
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
Generic sub-vectors.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
Definition: gmm_blas.h:59