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