GetFEM  5.5
gmm_sub_index.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2002-2026 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, see https://www.gnu.org/licenses/.
19 
20  As a special exception, you may use this file as it is a part of a free
21  software library without restriction. Specifically, if other files
22  instantiate templates or use macros or inline functions from this file,
23  or you compile this file and link it with other files to produce an
24  executable, this file does not by itself cause the resulting executable
25  to be covered by the GNU Lesser General Public License. This exception
26  does not however invalidate any other reasons why the executable file
27  might be covered by the GNU Lesser General Public License.
28 
29 ===========================================================================*/
30 
31 /**@file gmm_sub_index.h
32  @author Yves Renard <Yves.Renard@insa-lyon.fr>
33  @date October 13, 2002.
34  @brief sub-indices.
35 */
36 
37 #ifndef GMM_SUB_INDEX_H__
38 #define GMM_SUB_INDEX_H__
39 
40 #include "gmm_def.h"
41 
42 namespace gmm {
43 
44  /* ******************************************************************** */
45  /* sub indices */
46  /* ******************************************************************** */
47 
48  struct basic_index : public std::vector<size_t> {
49 
50  mutable size_type nb_ref;
51  // size_type key1; faire la somme des composantes
52  // const basic_index *rind; rindex s'il existe
53 
54 
55  size_t operator[](size_type i) const {
56  return (i < size()) ? std::vector<size_t>::operator[](i) : size_type(-1);
57  }
58 
59  basic_index() : nb_ref(1) {}
60  basic_index(size_type j) : std::vector<size_t>(j), nb_ref(1) {}
61  template <typename IT> basic_index(IT b, IT e)
62  : std::vector<size_t>(e-b), nb_ref(1) { std::copy(b, e, begin()); }
63  basic_index(const basic_index *pbi) : nb_ref(1) {
64  const_iterator it = pbi->begin(), ite = pbi->end();
65  size_type i = 0;
66  for ( ; it != ite; ++it) i = std::max(i, *it);
67  resize(i+1); std::fill(begin(), end(), size_type(-1));
68  for (it = pbi->begin(), i = 0; it != ite; ++it, ++i)
69  std::vector<size_t>::operator[](*it) = i;
70  }
71  void swap(size_type i, size_type j) {
72  std::swap(std::vector<size_t>::operator[](i),
73  std::vector<size_t>::operator[](j));
74  }
75 
76  };
77 
78  typedef basic_index *pbasic_index;
79 
80  struct index_generator {
81 
82  template <typename IT> static pbasic_index create_index(IT begin, IT end)
83  { return new basic_index(begin, end); }
84  static pbasic_index create_rindex(pbasic_index pbi)
85  { return new basic_index(pbi); }
86  static void attach(pbasic_index pbi) { if (pbi) pbi->nb_ref++; }
87  static void unattach(pbasic_index pbi)
88  { if (pbi && --(pbi->nb_ref) == 0) delete pbi; }
89 
90  };
91 
92  struct sub_index {
93 
94  size_type first_, last_;
95  typedef basic_index base_type;
96  typedef base_type::const_iterator const_iterator;
97 
98  mutable pbasic_index ind;
99  mutable pbasic_index rind;
100 
101  void comp_extr() {
102  std::vector<size_t>::const_iterator it = ind->begin(), ite = ind->end();
103  if (it != ite) { first_=last_= *it; ++it; } else { first_=last_= 0; }
104  for (; it != ite; ++it) {
105  first_ = std::min(first_, *it);
106  last_ = std::max(last_, *it);
107  }
108  }
109 
110  inline void test_rind() const
111  { if (!rind) rind = index_generator::create_rindex(ind); }
112  size_type size() const { return ind->size(); }
113  size_type first() const { return first_; }
114  size_type last() const { return last_; }
115  size_type index(size_type i) const { return (*ind)[i]; }
116  size_type rindex(size_type i) const {
117  test_rind();
118  if (i < rind->size()) return (*rind)[i];
119  else return size_type(-1);
120  }
121 
122  const_iterator begin() const { return ind->begin(); }
123  const_iterator end() const { return ind->end(); }
124  const_iterator rbegin() const { test_rind(); return rind->begin(); }
125  const_iterator rend() const { test_rind(); return rind->end(); }
126 
127  sub_index() : ind(0), rind(0) {}
128  template <typename IT> sub_index(IT it, IT ite)
129  : ind(index_generator::create_index(it, ite)), rind(0)
130  { comp_extr(); }
131  template <typename CONT> sub_index(const CONT &c)
132  : ind(index_generator::create_index(c.begin(), c.end())), rind(0)
133  { comp_extr(); }
134  ~sub_index() {
135  index_generator::unattach(rind);
136  index_generator::unattach(ind);
137  }
138  sub_index(const sub_index &si) : first_(si.first_), last_(si.last_),
139  ind(si.ind), rind(si.rind)
140  { index_generator::attach(rind); index_generator::attach(ind); }
141  sub_index &operator =(const sub_index &si) {
142  index_generator::unattach(rind);
143  index_generator::unattach(ind);
144  ind = si.ind; rind = si.rind;
145  index_generator::attach(rind);
146  index_generator::attach(ind);
147  first_ = si.first_; last_ = si.last_;
148  return *this;
149  }
150  };
151 
152  struct unsorted_sub_index : public sub_index {
153  typedef basic_index base_type;
154  typedef base_type::const_iterator const_iterator;
155 
156  template <typename IT> unsorted_sub_index(IT it, IT ite)
157  : sub_index(it, ite) {}
158  template <typename CONT> unsorted_sub_index(const CONT &c)
159  : sub_index(c) {}
160  unsorted_sub_index() {}
161  unsorted_sub_index(const unsorted_sub_index &si) : sub_index((const sub_index &)(si)) { }
162  unsorted_sub_index &operator =(const unsorted_sub_index &si)
163  { sub_index::operator =(si); return *this; }
164  void swap(size_type i, size_type j) {
165  GMM_ASSERT2(ind->nb_ref <= 1, "Operation not allowed on this index");
166  if (rind) rind->swap((*ind)[i], (*ind)[j]);
167  ind->swap(i, j);
168  }
169  };
170 
171  inline std::ostream &operator << (std::ostream &o, const sub_index &si) {
172  o << "sub_index(";
173  if (si.size() != 0) o << si.index(0);
174  for (size_type i = 1; i < si.size(); ++i) o << ", " << si.index(i);
175  o << ")";
176  return o;
177  }
178 
179  struct sub_interval {
180  size_type min, max;
181 
182  size_type size() const { return max - min; }
183  size_type first() const { return min; }
184  size_type last() const { return max; }
185  size_type index(size_type i) const { return min + i; }
186  size_type step() const { return 1; }
187  size_type rindex(size_type i) const
188  { if (i >= min && i < max) return i - min; return size_type(-1); }
189  sub_interval(size_type mi, size_type l) : min(mi), max(mi+l) {}
190  sub_interval() {}
191  };
192 
193  inline std::ostream &operator << (std::ostream &o, const sub_interval &si)
194  { o << "sub_interval(" << si.min << ", " << si.size() << ")"; return o; }
195 
196  struct sub_slice {
197  size_type min, max, N;
198 
199  size_type size() const { return (max - min) / N; }
200  size_type first() const { return min; }
201  size_type last() const { return (min == max) ? max : max+1-N; }
202  size_type step() const { return N; }
203  size_type index(size_type i) const { return min + N * i; }
204  size_type rindex(size_type i) const {
205  if (i >= min && i < max) {
206  size_type j = (i - min);
207  if (j % N == 0)
208  return j / N;
209  }
210  return size_type(-1);
211  }
212  sub_slice(size_type mi, size_type l, size_type n)
213  : min(mi), max(mi+l*n), N(n) {}
214  sub_slice() {}
215  };
216 
217  inline std::ostream &operator << (std::ostream &o, const sub_slice &si) {
218  o << "sub_slice(" << si.min << ", " << si.size() << ", " << si.step()
219  << ")"; return o;
220  }
221 
222  template<class SUBI> struct index_is_sorted
223  { typedef linalg_true bool_type; };
224  template<> struct index_is_sorted<unsorted_sub_index>
225  { typedef linalg_false bool_type; };
226 
227 }
228 
229 #endif // GMM_SUB_INDEX_H__
void resize(V &v, size_type n)
*‍/
Definition: gmm_blas.h:209
Basic definitions and tools of GMM.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48