GetFEM  5.4.3
gmm_sub_matrix.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 /**@file gmm_sub_matrix.h
33  @author Yves Renard <[email protected]>
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  bool operator > (const iterator &i) const { return (ii > i.ii); }
120  bool operator >=(const iterator &i) const { return (ii >= i.ii); }
121 
122  gen_sub_row_matrix_iterator(void) {}
123  gen_sub_row_matrix_iterator(const
124  gen_sub_row_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
125  : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
126  gen_sub_row_matrix_iterator(const ITER &iter, const SUBI1 &s1,
127  const SUBI2 &s2, size_type i)
128  : it(iter), si1(s1), si2(s2), ii(i) { }
129 
130  };
131 
132  template <typename PT, typename SUBI1, typename SUBI2>
133  struct linalg_traits<gen_sub_row_matrix<PT, SUBI1, SUBI2> > {
134  typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
135  typedef typename std::iterator_traits<PT>::value_type M;
136  typedef typename which_reference<PT>::is_reference is_reference;
137  typedef abstract_matrix linalg_type;
138  typedef typename linalg_traits<M>::origin_type origin_type;
139  typedef typename select_ref<const origin_type *, origin_type *,
140  PT>::ref_type porigin_type;
141  typedef typename linalg_traits<M>::value_type value_type;
142  typedef typename select_ref<value_type,
143  typename linalg_traits<M>::reference, PT>::ref_type reference;
144  typedef abstract_null_type sub_col_type;
145  typedef abstract_null_type col_iterator;
146  typedef abstract_null_type const_sub_col_type;
147  typedef abstract_null_type const_col_iterator;
148  typedef typename sub_vector_type<const typename org_type<typename
149  linalg_traits<M>::const_sub_row_type>::t *, SUBI2>::vector_type
150  const_sub_row_type;
151  typedef typename select_ref<abstract_null_type,
152  typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_row_type>::t *,
153  SUBI2>::vector_type, PT>::ref_type sub_row_type;
154  typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
155  SUBI1, SUBI2> const_row_iterator;
156  typedef typename select_ref<abstract_null_type,
157  gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
158  row_iterator;
159  typedef typename linalg_traits<const_sub_row_type>::storage_type
160  storage_type;
161  typedef row_major sub_orientation;
162  typedef linalg_true index_sorted;
163  static size_type nrows(const this_type &m) { return m.nrows(); }
164  static size_type ncols(const this_type &m) { return m.ncols(); }
165  static const_sub_row_type row(const const_row_iterator &it)
166  { return const_sub_row_type(linalg_traits<M>::row(*it), it.si2); }
167  static sub_row_type row(const row_iterator &it)
168  { return sub_row_type(linalg_traits<M>::row(*it), it.si2); }
169  static const_row_iterator row_begin(const this_type &m)
170  { return const_row_iterator(m.begin_, m.si1, m.si2, 0); }
171  static row_iterator row_begin(this_type &m)
172  { return row_iterator(m.begin_, m.si1, m.si2, 0); }
173  static const_row_iterator row_end(const this_type &m)
174  { return const_row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
175  static row_iterator row_end(this_type &m)
176  { return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
177  static origin_type* origin(this_type &v) { return v.origin; }
178  static const origin_type* origin(const this_type &v) { return v.origin; }
179  static void do_clear(this_type &m) {
180  row_iterator it = mat_row_begin(m), ite = mat_row_end(m);
181  for (; it != ite; ++it) clear(row(it));
182  }
183  static value_type access(const const_row_iterator &itrow, size_type i)
184  { return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
185  static reference access(const row_iterator &itrow, size_type i)
186  { return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
187  };
188 
189  template <typename PT, typename SUBI1, typename SUBI2>
190  std::ostream &operator <<(std::ostream &o,
191  const gen_sub_row_matrix<PT, SUBI1, SUBI2>& m)
192  { gmm::write(o,m); return o; }
193 
194 
195  /* ********************************************************************* */
196  /* sub column matrices type */
197  /* ********************************************************************* */
198 
199  template <typename PT, typename SUBI1, typename SUBI2>
200  struct gen_sub_col_matrix {
201  typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
202  typedef typename std::iterator_traits<PT>::value_type M;
203  typedef M * CPT;
204  typedef typename std::iterator_traits<PT>::reference ref_M;
205  typedef typename select_ref<typename linalg_traits<M>
206  ::const_col_iterator, typename linalg_traits<M>::col_iterator,
207  PT>::ref_type iterator;
208  typedef typename linalg_traits<this_type>::reference reference;
209  typedef typename linalg_traits<this_type>::porigin_type porigin_type;
210 
211  SUBI1 si1;
212  SUBI2 si2;
213  iterator begin_;
214  porigin_type origin;
215 
216  reference operator()(size_type i, size_type j) const
217  { return linalg_traits<M>::access(begin_ + si2.index(j), si1.index(i)); }
218 
219  size_type nrows(void) const { return si1.size(); }
220  size_type ncols(void) const { return si2.size(); }
221 
222  gen_sub_col_matrix(ref_M m, const SUBI1 &s1, const SUBI2 &s2)
223  : si1(s1), si2(s2), begin_(mat_col_begin(m)),
224  origin(linalg_origin(m)) {}
225  gen_sub_col_matrix() {}
226  gen_sub_col_matrix(const gen_sub_col_matrix<CPT, SUBI1, SUBI2> &cr) :
227  si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
228  };
229 
230  template <typename PT, typename SUBI1, typename SUBI2>
231  struct gen_sub_col_matrix_iterator {
232  typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
233  typedef typename modifiable_pointer<PT>::pointer MPT;
234  typedef typename std::iterator_traits<PT>::value_type M;
235  typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
236  typename linalg_traits<M>::col_iterator,
237  PT>::ref_type ITER;
238  typedef ITER value_type;
239  typedef ITER *pointer;
240  typedef ITER &reference;
241  typedef ptrdiff_t difference_type;
242  typedef size_t size_type;
243  typedef std::random_access_iterator_tag iterator_category;
244  typedef gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2> iterator;
245 
246  ITER it;
247  SUBI1 si1;
248  SUBI2 si2;
249  size_type ii;
250 
251  iterator operator ++(int) { iterator tmp = *this; ii++; return tmp; }
252  iterator operator --(int) { iterator tmp = *this; ii--; return tmp; }
253  iterator &operator ++() { ii++; return *this; }
254  iterator &operator --() { ii--; return *this; }
255  iterator &operator +=(difference_type i) { ii += i; return *this; }
256  iterator &operator -=(difference_type i) { ii -= i; return *this; }
257  iterator operator +(difference_type i) const
258  { iterator itt = *this; return (itt += i); }
259  iterator operator -(difference_type i) const
260  { iterator itt = *this; return (itt -= i); }
261  difference_type operator -(const iterator &i) const { return ii - i.ii; }
262 
263  ITER operator *() const { return it + si2.index(ii); }
264  ITER operator [](int i) { return it + si2.index(ii+i); }
265 
266  bool operator ==(const iterator &i) const { return (ii == i.ii); }
267  bool operator !=(const iterator &i) const { return !(i == *this); }
268  bool operator < (const iterator &i) const { return (ii < i.ii); }
269  bool operator > (const iterator &i) const { return (ii > i.ii); }
270  bool operator >=(const iterator &i) const { return (ii >= i.ii); }
271 
272  gen_sub_col_matrix_iterator(void) {}
273  gen_sub_col_matrix_iterator(const
274  gen_sub_col_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
275  : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
276  gen_sub_col_matrix_iterator(const ITER &iter, const SUBI1 &s1,
277  const SUBI2 &s2, size_type i)
278  : it(iter), si1(s1), si2(s2), ii(i) { }
279  };
280 
281  template <typename PT, typename SUBI1, typename SUBI2>
282  struct linalg_traits<gen_sub_col_matrix<PT, SUBI1, SUBI2> > {
283  typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
284  typedef typename std::iterator_traits<PT>::value_type M;
285  typedef typename linalg_traits<M>::origin_type origin_type;
286  typedef typename select_ref<const origin_type *, origin_type *,
287  PT>::ref_type porigin_type;
288  typedef typename which_reference<PT>::is_reference is_reference;
289  typedef abstract_matrix linalg_type;
290  typedef typename linalg_traits<M>::value_type value_type;
291  typedef typename select_ref<value_type,
292  typename linalg_traits<M>::reference, PT>::ref_type reference;
293  typedef abstract_null_type sub_row_type;
294  typedef abstract_null_type row_iterator;
295  typedef abstract_null_type const_sub_row_type;
296  typedef abstract_null_type const_row_iterator;
297  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;
298  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;
299  typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
300  SUBI1, SUBI2> const_col_iterator;
301  typedef typename select_ref<abstract_null_type,
302  gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
303  col_iterator;
304  typedef col_major sub_orientation;
305  typedef linalg_true index_sorted;
306  typedef typename linalg_traits<const_sub_col_type>::storage_type
307  storage_type;
308  static size_type nrows(const this_type &m) { return m.nrows(); }
309  static size_type ncols(const this_type &m) { return m.ncols(); }
310  static const_sub_col_type col(const const_col_iterator &it)
311  { return const_sub_col_type(linalg_traits<M>::col(*it), it.si1); }
312  static sub_col_type col(const col_iterator &it)
313  { return sub_col_type(linalg_traits<M>::col(*it), it.si1); }
314  static const_col_iterator col_begin(const this_type &m)
315  { return const_col_iterator(m.begin_, m.si1, m.si2, 0); }
316  static col_iterator col_begin(this_type &m)
317  { return col_iterator(m.begin_, m.si1, m.si2, 0); }
318  static const_col_iterator col_end(const this_type &m)
319  { return const_col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
320  static col_iterator col_end(this_type &m)
321  { return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
322  static origin_type* origin(this_type &v) { return v.origin; }
323  static const origin_type* origin(const this_type &v) { return v.origin; }
324  static void do_clear(this_type &m) {
325  col_iterator it = mat_col_begin(m), ite = mat_col_end(m);
326  for (; it != ite; ++it) clear(col(it));
327  }
328  static value_type access(const const_col_iterator &itcol, size_type i)
329  { return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
330  static reference access(const col_iterator &itcol, size_type i)
331  { return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
332  };
333 
334  template <typename PT, typename SUBI1, typename SUBI2> std::ostream &operator <<
335  (std::ostream &o, const gen_sub_col_matrix<PT, SUBI1, SUBI2>& m)
336  { gmm::write(o,m); return o; }
337 
338  /* ******************************************************************** */
339  /* sub matrices */
340  /* ******************************************************************** */
341 
342  template <typename PT, typename SUBI1, typename SUBI2, typename ST>
343  struct sub_matrix_type_ {
344  typedef abstract_null_type return_type;
345  };
346  template <typename PT, typename SUBI1, typename SUBI2>
347  struct sub_matrix_type_<PT, SUBI1, SUBI2, col_major>
348  { typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> matrix_type; };
349  template <typename PT, typename SUBI1, typename SUBI2>
350  struct sub_matrix_type_<PT, SUBI1, SUBI2, row_major>
351  { typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> matrix_type; };
352  template <typename PT, typename SUBI1, typename SUBI2>
353  struct sub_matrix_type {
354  typedef typename std::iterator_traits<PT>::value_type M;
355  typedef typename sub_matrix_type_<PT, SUBI1, SUBI2,
356  typename principal_orientation_type<typename
357  linalg_traits<M>::sub_orientation>::potype>::matrix_type matrix_type;
358  };
359 
360  template <typename M, typename SUBI1, typename SUBI2> inline
361  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
362  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
363  M *>::return_type
364  sub_matrix(M &m, const SUBI1 &si1, const SUBI2 &si2) {
365  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
366  "sub matrix too large");
367  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
368  SUBI2>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>
369  ::matrix_type, M *>::return_type(linalg_cast(m), si1, si2);
370  }
371 
372  template <typename M, typename SUBI1, typename SUBI2> inline
373  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
374  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
375  const M *>::return_type
376  sub_matrix(const M &m, const SUBI1 &si1, const SUBI2 &si2) {
377  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
378  "sub matrix too large");
379  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
380  SUBI2>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI2>
381  ::matrix_type, const M *>::return_type(linalg_cast(m), si1, si2);
382  }
383 
384  template <typename M, typename SUBI1> inline
385  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
386  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
387  M *>::return_type
388  sub_matrix(M &m, const SUBI1 &si1) {
389  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
390  "sub matrix too large");
391  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
392  SUBI1>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>
393  ::matrix_type, M *>::return_type(linalg_cast(m), si1, si1);
394  }
395 
396  template <typename M, typename SUBI1> inline
397  typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
398  ::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
399  const M *>::return_type
400  sub_matrix(const M &m, const SUBI1 &si1) {
401  GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
402  "sub matrix too large");
403  return typename select_return<typename sub_matrix_type<const M *, SUBI1,
404  SUBI1>::matrix_type, typename sub_matrix_type<M *, SUBI1, SUBI1>
405  ::matrix_type, const M *>::return_type(linalg_cast(m), si1, si1);
406  }
407 
408 }
409 
410 #endif // GMM_SUB_MATRIX_H__
void clear(L &l)
clear (fill with zeros) a vector or matrix.
Definition: gmm_blas.h:59
Generic sub-vectors.
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:756
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:749
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49