dune-spgrid  2.7
multiindex.hh
Go to the documentation of this file.
1 #ifndef DUNE_SPGRID_MULTIINDEX_HH
2 #define DUNE_SPGRID_MULTIINDEX_HH
3 
4 #include <algorithm>
5 #include <array>
6 
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  SPMultiIndex ( const int (&index)[ dimension ] ) { *this = index; }
46 
54  SPMultiIndex ( const std::array< int, dimension > &index ) { *this = index; }
55 
57  // Note: The default copy constructor generated by gcc will call memmove,
58  // which is less efficient than copying each value by hand.
59  // Interestingly, calling memcpy would yield even faster code than
60  // this, but gcc does not understand its meaning and fails to optimize
61  // out unnecessary copies.
62  SPMultiIndex ( const This &other ) { *this = other; }
63 
65  // Note: The default copy assignment operator generated by gcc will call
66  // memmove, which is less efficient than copying each value by hand.
67  // Interestingly, calling memcpy would yield even faster code than
68  // this, but gcc does not understand its meaning and fails to optimize
69  // out unnecessary copies.
70  This &operator= ( const This &other )
71  {
72  for( int i = 0; i < dimension; ++i )
73  index_[ i ] = other.index_[ i ];
74  return *this;
75  }
76 
78  This &operator= ( const int (&index)[ dimension ] )
79  {
80  for( int i = 0; i < dimension; ++i )
81  index_[ i ] = index[ i ];
82  return *this;
83  }
84 
85  This &operator= ( const std::array< int, dimension > &index )
86  {
87  for( int i = 0; i < dimension; ++i )
88  index_[ i ] = index[ i ];
89  return *this;
90  }
91 
93  This &operator+= ( const This &other )
94  {
95  for( int i = 0; i < dimension; ++i )
96  index_[ i ] += other.index_[ i ];
97  return *this;
98  }
99 
101  This &operator-= ( const This &other )
102  {
103  for( int i = 0; i < dimension; ++i )
104  index_[ i ] -= other.index_[ i ];
105  return *this;
106  }
107 
109  This &operator*= ( int a )
110  {
111  for( int i = 0; i < dimension; ++i )
112  index_[ i ] *= a;
113  return *this;
114  }
115 
117  This &operator/= ( int a )
118  {
119  for( int i = 0; i < dimension; ++i )
120  index_[ i ] /= a;
121  return *this;
122  }
123 
125  const int &operator[] ( int i ) const { return index_[ i ]; }
126 
128  int &operator[] ( int i ) { return index_[ i ]; }
129 
131  bool operator== ( const This &other ) const
132  {
133  bool equals = true;
134  for( int i = 0; i < dimension; ++i )
135  equals &= (index_[ i ] == other.index_[ i ]);
136  return equals;
137  }
138 
140  bool operator!= ( const This &other ) const
141  {
142  bool equals = false;
143  for( int i = 0; i < dimension; ++i )
144  equals |= (index_[ i ] != other.index_[ i ]);
145  return equals;
146  }
147 
149  void axpy( const int a, const This &other )
150  {
151  for( int i = 0; i < dimension; ++i )
152  index_[ i ] += a*other.index_[ i ];
153  }
154 
155  ConstIterator begin () const { return index_.begin(); }
156  Iterator begin () { return index_.begin(); }
157 
158  ConstIterator cbegin () const { return index_.begin(); }
159 
160  ConstIterator end () const { return index_.end(); }
161  Iterator end () { return index_.end(); }
162 
163  ConstIterator cend () const { return index_.end(); }
164 
166  void clear ()
167  {
168  for( int i = 0; i < dimension; ++i )
169  index_[ i ] = 0;
170  }
171 
173  void increment ( const This &bound, const int k = 1 )
174  {
175  for( int i = 0; i < dimension; ++i )
176  {
177  index_[ i ] += k;
178  if( index_[ i ] < bound[ i ] )
179  return;
180  index_[ i ] = 0;
181  }
182  }
183 
185  int codimension () const
186  {
187  int codim = dimension;
188  for( int i = 0; i < dimension; ++i )
189  codim -= (index_[ i ] & 1);
190  return codim;
191  }
192 
194  static This zero ()
195  {
196  This zero;
197  zero.clear();
198  return zero;
199  }
200 
201  private:
202  std::array< int, dimension > index_;
203  };
204 
205 
206 
207  // Auxilliary Functions for SPMultiIndex
208  // -------------------------------------
209 
210  template< class char_type, class traits, int dim >
211  inline std::basic_ostream< char_type, traits > &
212  operator<< ( std::basic_ostream< char_type, traits > &out, const SPMultiIndex< dim > &multiIndex )
213  {
214  out << "( " << multiIndex[ 0 ];
215  for( int i = 1; i < dim; ++i )
216  out << ", " << multiIndex[ i ];
217  return out << " )";
218  }
219 
220 
221  template< class char_type, class traits, int dim >
222  inline std::basic_istream< char_type, traits > &
223  operator>> ( std::basic_istream< char_type, traits > &in, SPMultiIndex< dim > &multiIndex )
224  {
226  in >> match( '(' ) >> m[ 0 ];
227  for( int i = 1; i < dim; ++i )
228  in >> match( ',' ) >> m[ i ];
229  in >> match( ')' );
230  if( !in.fail() )
231  multiIndex = m;
232  return in;
233  }
234 
235 
236  template< int dim >
237  inline SPMultiIndex< dim >
239  {
240  SPMultiIndex< dim > c = a;
241  c += b;
242  return c;
243  }
244 
245 
246  template< int dim >
247  inline SPMultiIndex< dim >
249  {
250  SPMultiIndex< dim > c = a;
251  c -= b;
252  return c;
253  }
254 
255 
256  template< int dim >
257  inline SPMultiIndex< dim >
258  operator* ( const SPMultiIndex< dim > &a, const int &b )
259  {
260  SPMultiIndex< dim > c = a;
261  c *= b;
262  return c;
263  }
264 
265 
266  template< int dim >
267  inline SPMultiIndex< dim >
268  operator* ( const int &a, const SPMultiIndex< dim > &b )
269  {
270  return (b*a);
271  }
272 
273 
274  template< int dim >
275  inline SPMultiIndex< dim >
276  operator/ ( const SPMultiIndex< dim > &a, const int &b )
277  {
278  SPMultiIndex< dim > c = a;
279  c /= b;
280  return c;
281  }
282 
283 } // namespace Dune
284 
285 
286 namespace std
287 {
288 
289  // Auxilliary functions for SPMultiIndex
290  // -------------------------------------
291 
292  template< int dim >
295  {
297  for( int i = 0; i < dim; ++i )
298  c[ i ] = min( a[ i ], b[ i ] );
299  return c;
300  }
301 
302 
303  template< int dim >
306  {
308  for( int i = 0; i < dim; ++i )
309  c[ i ] = max( a[ i ], b[ i ] );
310  return c;
311  }
312 
313 } // namespace std
314 
315 #endif // #ifndef DUNE_SPGRID_MULTIINDEX_HH
miscellaneous helper functions
Dune::SPMultiIndex< dim > min(const Dune::SPMultiIndex< dim > &a, const Dune::SPMultiIndex< dim > &b)
Definition: multiindex.hh:294
Dune::SPMultiIndex< dim > max(const Dune::SPMultiIndex< dim > &a, const Dune::SPMultiIndex< dim > &b)
Definition: multiindex.hh:305
Definition: iostream.hh:7
SPMesh< dim > operator-(const SPMesh< dim > &mesh, const SPMultiIndex< dim > &shift)
Definition: mesh.hh:245
SPMesh< dim > operator+(const SPMesh< dim > &mesh, const SPMultiIndex< dim > &shift)
Definition: mesh.hh:236
SPMultiIndex< dim > operator/(const SPMultiIndex< dim > &a, const int &b)
Definition: multiindex.hh:276
SPMultiIndex< dim > operator*(const SPMultiIndex< dim > &a, const int &b)
Definition: multiindex.hh:258
std::basic_ostream< char_type, traits > & operator<<(std::basic_ostream< char_type, traits > &out, const SPCube< ct, dim > &cube)
Definition: cube.hh:148
std::basic_istream< char_type, traits > & operator>>(std::basic_istream< char_type, traits > &in, SPCube< ct, dim > &cube)
Definition: cube.hh:162
iostream::Match< typename iostream::MatchTraits< T >::Type > match(const T &value)
Definition: iostream.hh:87
multiindex
Definition: multiindex.hh:25
Iterator begin()
Definition: multiindex.hh:156
void increment(const This &bound, const int k=1)
Definition: multiindex.hh:173
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:125
SPMultiIndex(const int(&index)[dimension])
constructor from int array
Definition: multiindex.hh:45
static This zero()
obtain the zero multiindex
Definition: multiindex.hh:194
SPMultiIndex()
default constructor
Definition: multiindex.hh:36
This & operator+=(const This &other)
add another multiindex to this one (vector operation)
Definition: multiindex.hh:93
Iterator end()
Definition: multiindex.hh:161
SPMultiIndex(const std::array< int, dimension > &index)
constructor from int array
Definition: multiindex.hh:54
This & operator/=(int a)
scale this multiindex (vector operation)
Definition: multiindex.hh:117
This & operator*=(int a)
scale this multiindex (vector operation)
Definition: multiindex.hh:109
void clear()
initialize to zero
Definition: multiindex.hh:166
This & operator=(const This &other)
copy assignment
Definition: multiindex.hh:70
std::array< int, dimension >::iterator Iterator
Definition: multiindex.hh:33
std::array< int, dimension >::const_iterator ConstIterator
Definition: multiindex.hh:32
ConstIterator end() const
Definition: multiindex.hh:160
bool operator==(const This &other) const
compare two multiindices for equality
Definition: multiindex.hh:131
ConstIterator cbegin() const
Definition: multiindex.hh:158
ConstIterator cend() const
Definition: multiindex.hh:163
void axpy(const int a, const This &other)
add multiple of a multiindex to this one (vector operation)
Definition: multiindex.hh:149
This & operator-=(const This &other)
subtract another multiindex from this one (vector operation)
Definition: multiindex.hh:101
SPMultiIndex(const This &other)
copy constructor
Definition: multiindex.hh:62
ConstIterator begin() const
Definition: multiindex.hh:155
int codimension() const
Definition: multiindex.hh:185
bool operator!=(const This &other) const
compare two multiindices for inequality
Definition: multiindex.hh:140