Dune Core Modules (2.9.0)

multiindex.hh
1 #ifndef DUNE_SPGRID_MULTIINDEX_HH
2 #define DUNE_SPGRID_MULTIINDEX_HH
3 
4 #include <algorithm>
5 #include <array>
6 
7 #include <dune/common/iostream.hh>
8 
10 
11 namespace Dune
12 {
13 
14  // SPMultiIndex
15  // ------------
16 
23  template< int dim >
25  {
26  typedef SPMultiIndex< dim > This;
27 
28  public:
30  static const int dimension = dim;
31 
32  typedef typename std::array< int, dimension >::const_iterator ConstIterator;
33  typedef typename std::array< int, dimension >::iterator Iterator;
34 
36  SPMultiIndex () : index_( {} ) {}
37 
45  template <int d, std::enable_if_t<(d == dimension && d > 0), int> = 0>
46  SPMultiIndex ( const int (&index)[ d ] ) { *this = index; }
47 
55  SPMultiIndex ( const std::array< int, dimension > &index ) { *this = index; }
56 
58  // Note: The default copy constructor generated by gcc will call memmove,
59  // which is less efficient than copying each value by hand.
60  // Interestingly, calling memcpy would yield even faster code than
61  // this, but gcc does not understand its meaning and fails to optimize
62  // out unnecessary copies.
63  SPMultiIndex ( const This &other ) { *this = other; }
64 
66  // Note: The default copy assignment operator generated by gcc will call
67  // memmove, which is less efficient than copying each value by hand.
68  // Interestingly, calling memcpy would yield even faster code than
69  // this, but gcc does not understand its meaning and fails to optimize
70  // out unnecessary copies.
71  This &operator= ( const This &other )
72  {
73  for( int i = 0; i < dimension; ++i )
74  index_[ i ] = other.index_[ i ];
75  return *this;
76  }
77 
79  template <int d, std::enable_if_t<(d == dimension && d > 0), int> = 0>
80  This &operator= ( const int (&index)[ d ] )
81  {
82  for( int i = 0; i < dimension; ++i )
83  index_[ i ] = index[ i ];
84  return *this;
85  }
86 
87  This &operator= ( const std::array< int, dimension > &index )
88  {
89  for( int i = 0; i < dimension; ++i )
90  index_[ i ] = index[ i ];
91  return *this;
92  }
93 
95  This &operator+= ( const This &other )
96  {
97  for( int i = 0; i < dimension; ++i )
98  index_[ i ] += other.index_[ i ];
99  return *this;
100  }
101 
103  This &operator-= ( const This &other )
104  {
105  for( int i = 0; i < dimension; ++i )
106  index_[ i ] -= other.index_[ i ];
107  return *this;
108  }
109 
111  This &operator*= ( int a )
112  {
113  for( int i = 0; i < dimension; ++i )
114  index_[ i ] *= a;
115  return *this;
116  }
117 
119  This &operator/= ( int a )
120  {
121  for( int i = 0; i < dimension; ++i )
122  index_[ i ] /= a;
123  return *this;
124  }
125 
127  const int &operator[] ( int i ) const { return index_[ i ]; }
128 
130  int &operator[] ( int i ) { return index_[ i ]; }
131 
133  bool operator== ( const This &other ) const
134  {
135  bool equals = true;
136  for( int i = 0; i < dimension; ++i )
137  equals &= (index_[ i ] == other.index_[ i ]);
138  return equals;
139  }
140 
142  bool operator!= ( const This &other ) const
143  {
144  bool equals = false;
145  for( int i = 0; i < dimension; ++i )
146  equals |= (index_[ i ] != other.index_[ i ]);
147  return equals;
148  }
149 
151  void axpy( const int a, const This &other )
152  {
153  for( int i = 0; i < dimension; ++i )
154  index_[ i ] += a*other.index_[ i ];
155  }
156 
157  ConstIterator begin () const { return index_.begin(); }
158  Iterator begin () { return index_.begin(); }
159 
160  ConstIterator cbegin () const { return index_.begin(); }
161 
162  ConstIterator end () const { return index_.end(); }
163  Iterator end () { return index_.end(); }
164 
165  ConstIterator cend () const { return index_.end(); }
166 
168  void clear ()
169  {
170  for( int i = 0; i < dimension; ++i )
171  index_[ i ] = 0;
172  }
173 
175  void increment ( const This &bound, const int k = 1 )
176  {
177  for( int i = 0; i < dimension; ++i )
178  {
179  index_[ i ] += k;
180  if( index_[ i ] < bound[ i ] )
181  return;
182  index_[ i ] = 0;
183  }
184  }
185 
187  int codimension () const
188  {
189  int codim = dimension;
190  for( int i = 0; i < dimension; ++i )
191  codim -= (index_[ i ] & 1);
192  return codim;
193  }
194 
196  static This zero ()
197  {
198  This zero;
199  zero.clear();
200  return zero;
201  }
202 
203  private:
204  std::array< int, dimension > index_;
205  };
206 
207 
208 
209  // Auxilliary Functions for SPMultiIndex
210  // -------------------------------------
211 
212  template< class char_type, class traits, int dim >
213  inline std::basic_ostream< char_type, traits > &
214  operator<< ( std::basic_ostream< char_type, traits > &out, const SPMultiIndex< dim > &multiIndex )
215  {
216  out << "( " << multiIndex[ 0 ];
217  for( int i = 1; i < dim; ++i )
218  out << ", " << multiIndex[ i ];
219  return out << " )";
220  }
221 
222 
223  template< class char_type, class traits, int dim >
224  inline std::basic_istream< char_type, traits > &
225  operator>> ( std::basic_istream< char_type, traits > &in, SPMultiIndex< dim > &multiIndex )
226  {
227  SPMultiIndex< dim > m;
228  in >> match( '(' ) >> m[ 0 ];
229  for( int i = 1; i < dim; ++i )
230  in >> match( ',' ) >> m[ i ];
231  in >> match( ')' );
232  if( !in.fail() )
233  multiIndex = m;
234  return in;
235  }
236 
237 
238  template< int dim >
239  inline SPMultiIndex< dim >
240  operator+ ( const SPMultiIndex< dim > &a, const SPMultiIndex< dim > &b )
241  {
242  SPMultiIndex< dim > c = a;
243  c += b;
244  return c;
245  }
246 
247 
248  template< int dim >
249  inline SPMultiIndex< dim >
250  operator- ( const SPMultiIndex< dim > &a, const SPMultiIndex< dim > &b )
251  {
252  SPMultiIndex< dim > c = a;
253  c -= b;
254  return c;
255  }
256 
257 
258  template< int dim >
259  inline SPMultiIndex< dim >
260  operator* ( const SPMultiIndex< dim > &a, const int &b )
261  {
262  SPMultiIndex< dim > c = a;
263  c *= b;
264  return c;
265  }
266 
267 
268  template< int dim >
269  inline SPMultiIndex< dim >
270  operator* ( const int &a, const SPMultiIndex< dim > &b )
271  {
272  return (b*a);
273  }
274 
275 
276  template< int dim >
277  inline SPMultiIndex< dim >
278  operator/ ( const SPMultiIndex< dim > &a, const int &b )
279  {
280  SPMultiIndex< dim > c = a;
281  c /= b;
282  return c;
283  }
284 
285 } // namespace Dune
286 
287 
288 namespace std
289 {
290 
291  // Auxilliary functions for SPMultiIndex
292  // -------------------------------------
293 
294  template< int dim >
297  {
299  for( int i = 0; i < dim; ++i )
300  c[ i ] = min( a[ i ], b[ i ] );
301  return c;
302  }
303 
304 
305  template< int dim >
308  {
310  for( int i = 0; i < dim; ++i )
311  c[ i ] = max( a[ i ], b[ i ] );
312  return c;
313  }
314 
315 } // namespace std
316 
317 #endif // #ifndef DUNE_SPGRID_MULTIINDEX_HH
multiindex
Definition: multiindex.hh:25
void increment(const This &bound, const int k=1)
Definition: multiindex.hh:175
static const int dimension
dimension of the multiindex
Definition: multiindex.hh:30
const int & operator[](int i) const
access i-th component
Definition: multiindex.hh:127
static This zero()
obtain the zero multiindex
Definition: multiindex.hh:196
SPMultiIndex()
default constructor
Definition: multiindex.hh:36
This & operator+=(const This &other)
add another multiindex to this one (vector operation)
Definition: multiindex.hh:95
SPMultiIndex(const std::array< int, dimension > &index)
constructor from int array
Definition: multiindex.hh:55
This & operator/=(int a)
scale this multiindex (vector operation)
Definition: multiindex.hh:119
This & operator*=(int a)
scale this multiindex (vector operation)
Definition: multiindex.hh:111
void clear()
initialize to zero
Definition: multiindex.hh:168
This & operator=(const This &other)
copy assignment
Definition: multiindex.hh:71
bool operator==(const This &other) const
compare two multiindices for equality
Definition: multiindex.hh:133
void axpy(const int a, const This &other)
add multiple of a multiindex to this one (vector operation)
Definition: multiindex.hh:151
This & operator-=(const This &other)
subtract another multiindex from this one (vector operation)
Definition: multiindex.hh:103
SPMultiIndex(const This &other)
copy constructor
Definition: multiindex.hh:63
SPMultiIndex(const int(&index)[d])
constructor from int array
Definition: multiindex.hh:46
int codimension() const
Definition: multiindex.hh:187
bool operator!=(const This &other) const
compare two multiindices for inequality
Definition: multiindex.hh:142
miscellaneous helper functions
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:43
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:402
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:89
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 3, 22:32, 2024)