MADNESS  0.10.1
indexit.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id$
32 */
33 #ifndef MADNESS_MRA_INDEXIT_H__INCLUDED
34 #define MADNESS_MRA_INDEXIT_H__INCLUDED
35 
36 /// \file indexit.h
37 /// \brief Provides IndexIterator
38 
39 #include <vector>
40 #include <madness/world/print.h>
41 
42 namespace madness {
43 
44  /// Facilitates iteration through a multidimension index space.
45  /// Since there are multiple ways for navigating index space (column- vs.
46  /// row-major, etc.), this class should be abstract, with an abstract ++
47  /// operator. The original IndexIterator assumed the highest dimension
48  /// (NDIM-1) would be iterated quickest (this index changes each time ++
49  /// is called), however, sometimes a different order is desired.
50  ///
51  /// For legacy purposes, operator++ is thus NOT abstract, but has the
52  /// implementation of the HighDimIndexIterator defined below. Eventually,
53  /// the IndexIterator::operator++ should be deprecated, and such
54  /// instances of IndexIterator replaced with HighDimIndexIterator.
55  class IndexIterator {
56  private:
57  /// Bury the default constructor
59 
60  protected:
61  std::vector<long> n; ///< User specified upper limits for each dimension
62  std::vector<long> i; ///< Current index
63  bool finished;
64 
65  public:
66  /// Iterates dimension d from 0 to limts[d]-1 inclusive
67  template<typename V>
68  IndexIterator(const V& limits) :
69  n(limits.size()), i(limits.size(), 0l), finished(false) {
70  for (unsigned int d = 0; d < n.size(); ++d)
71  n[d] = limits[d];
72  }
73 
74  /// Iterates dimension d from 0 to limts[d]-1 inclusive
75  IndexIterator(int ndim, const long limits[]) :
76  n(ndim), i(ndim, 0l), finished(false) {
77  for (unsigned int d = 0; d < n.size(); ++d)
78  n[d] = limits[d];
79  }
80 
81  /// Iterates all dimensions from 0 to top-1 inclusive
82  IndexIterator(int ndim, long top) :
83  n(ndim,top), i(ndim, 0l), finished(false) {
84  }
85 
86  virtual ~IndexIterator() {}
87 
89  reset() {
90  for (unsigned int d = 0; d < n.size(); ++d)
91  i[d] = 0;
92  finished = false;
93  return *this;
94  }
95 
96  long
97  operator[](int d) const {
99  return i[d];
100  }
101 
102  const std::vector<long>&
103  operator*() const {
105  return i;
106  }
107 
108  operator bool() const {
109  return !finished;
110  }
111 
112  /// this function should be abstracted and deprecated
113  virtual IndexIterator&
115  for (int d = n.size() - 1; d >= 0; --d) {
116  ++(i[d]);
117  if (i[d] < n[d])
118  return *this;
119  else
120  i[d] = 0;
121  }
122  finished = true;
123  return *this;
124  }
125 
126  /// this function should also be deprecated
127  static void
128  test() {
129  Vector<int, 4> n(3);
130  for (IndexIterator it(n); it; ++it) {
131  print(*it);
132  }
133  }
134  };
135 
136  /// The inherited IndexIterator for iterating over the high dimensions
137  /// quickly and the low dimensions slowly (all elements of dimension 0
138  /// at index i will be visited before any element of index i+1 in dim. 0).
139  ///
140  /// This is equivalent to the original implementation of IndexIterator.
142  private:
143  /// Bury the default constructor
145 
146  public:
147  /// Iterates dimension d from 0 to limts[d]-1 inclusive
148  template<typename V>
149  HighDimIndexIterator(const V& limits) : IndexIterator(limits) {}
150 
151  /// Iterates dimension d from 0 to limts[d]-1 inclusive
152  HighDimIndexIterator(int ndim, const long limits[]) :
153  IndexIterator(ndim, limits) {}
154 
155  /// Iterates all dimensions from 0 to top-1 inclusive
156  HighDimIndexIterator(int ndim, long top) : IndexIterator(ndim, top) {}
157 
159 
160  /// increment the highest dimension first and check for overflows
161  /// up through dimension 0
162  virtual IndexIterator&
164  for (int d = n.size() - 1; d >= 0; --d) {
165  ++(i[d]);
166  if (i[d] < n[d])
167  return *this;
168  else
169  i[d] = 0;
170  }
171  finished = true;
172  return *this;
173  }
174  };
175 
176  /// The inherited IndexIterator for iterating over the low dimensions
177  /// quickly and the high dimensions slowly (all elements of dimension
178  /// ndim-1 at index i will be visited before any element of index i+1 in
179  /// dim. ndim-1).
181  private:
182  /// Bury the default constructor
184 
185  public:
186  /// Iterates dimension d from 0 to limts[d]-1 inclusive
187  template<typename V>
188  LowDimIndexIterator(const V& limits) : IndexIterator(limits) {}
189 
190  /// Iterates dimension d from 0 to limts[d]-1 inclusive
191  LowDimIndexIterator(int ndim, const long limits[]) :
192  IndexIterator(ndim, limits) {}
193 
194  /// Iterates all dimensions from 0 to top-1 inclusive
195  LowDimIndexIterator(int ndim, long top) : IndexIterator(ndim, top) {}
196 
197  virtual ~LowDimIndexIterator() {}
198 
199  /// increment the lowest dimension first and check for overflows
200  /// up through dimension 0
201  virtual IndexIterator&
203  int ndim = n.size();
204  for (int d = 0; d < ndim; ++d) {
205  ++(i[d]);
206  if (i[d] < n[d])
207  return *this;
208  else
209  i[d] = 0;
210  }
211  finished = true;
212  return *this;
213  }
214  };
215 
216  /// The inherited IndexIterator for iterating over the dimensions in a
217  /// specified order.
218  ///
219  /// NOTE: if iterating quickly over the high dimensions and slowly over
220  /// the low dimensions (in dimensional order), use HighDimIndexIterator.
221  ///
222  /// NOTE: if iterating quickly over the low dimensions and slowly over
223  /// the high dimensions (in dimensional order), use LowDimIndexIterator.
225  private:
226  /// Bury the default constructor
228 
229  protected:
230  /// the array storing the dimensional order for iteration
231  /// dim[0] is the quickest dimension over which to iterate
232  /// dim[ndim-1] is the slowest dimension
233  std::vector<int> dim;
234 
235  public:
236  /// Iterates dimension d from 0 to limts[d]-1 inclusive
237  ///
238  /// order[0] is the dimension to be iterated over quickest
239  /// ...
240  /// order[d-1] is the dimension to be iterated over slowest
241  template<typename V, typename D>
242  NonstandardIndexIterator(const V& limits, const D& order) :
243  IndexIterator(limits), dim(order.size()) {
244  int i, j, ndim = order.size();
245 
246  MADNESS_ASSERT(limits.size() == ndim);
247  for(i = 0; i < ndim; ++i) {
248  MADNESS_ASSERT(order[i] >= 0 && order[i] < ndim);
249 
250  // make sure we haven't seen this dimension before
251  for(j = 0; j < i; ++j)
252  MADNESS_ASSERT(order[i] != order[j]);
253 
254  dim[i] = order[i];
255  }
256  }
257 
258  /// Iterates dimension d from 0 to limts[d]-1 inclusive
259  ///
260  /// order[0] is the dimension to be iterated over quickest
261  /// ...
262  /// order[d-1] is the dimension to be iterated over slowest
263  NonstandardIndexIterator(int ndim, const long limits[],
264  const int order[]) : IndexIterator(ndim, limits) {
265  int i, j;
266 
267  for(i = 0; i < ndim; ++i) {
268  MADNESS_ASSERT(order[i] >= 0 && order[i] < ndim);
269 
270  // make sure we haven't seen this dimension before
271  for(j = 0; j < i; ++j)
272  MADNESS_ASSERT(order[i] != order[j]);
273 
274  dim[i] = order[i];
275  }
276  }
277 
278  /// Iterates all dimensions from 0 to top-1 inclusive
279  ///
280  /// order[0] is the dimension to be iterated over quickest
281  /// ...
282  /// order[d-1] is the dimension to be iterated over slowest
283  template<typename D>
284  NonstandardIndexIterator(int ndim, long top, const D &order) :
285  IndexIterator(ndim, top), dim(order.size()) {
286  int i, j;
287 
288  MADNESS_ASSERT(order.size() == ndim);
289  for(i = 0; i < ndim; ++i) {
290  MADNESS_ASSERT(order[i] >= 0 && order[i] < ndim);
291 
292  // make sure we haven't seen this dimension before
293  for(j = 0; j < i; ++j)
294  MADNESS_ASSERT(order[i] != order[j]);
295 
296  dim[i] = order[i];
297  }
298  }
299 
300  /// Iterates all dimensions from 0 to top-1 inclusive
301  ///
302  /// order[0] is the dimension to be iterated over quickest
303  /// ...
304  /// order[d-1] is the dimension to be iterated over slowest
305  NonstandardIndexIterator(int ndim, long top, const int order[]) :
306  IndexIterator(ndim, top), dim(ndim) {
307  int i, j;
308 
309  for(i = 0; i < ndim; ++i) {
310  MADNESS_ASSERT(order[i] >= 0 && order[i] < ndim);
311 
312  // make sure we haven't seen this dimension before
313  for(j = 0; j < i; ++j)
314  MADNESS_ASSERT(order[i] != order[j]);
315 
316  dim[i] = order[i];
317  }
318  }
319 
321 
322  /// increment the dimensions in the order detailed in dim
323  virtual IndexIterator&
325  int ndim = n.size();
326  for (int d = 0; d < ndim; ++d) {
327  ++(i[dim[d]]);
328  if (i[dim[d]] < n[dim[d]])
329  return *this;
330  else
331  i[dim[d]] = 0;
332  }
333  finished = true;
334  return *this;
335  }
336  };
337 }
338 
339 #endif // MADNESS_MRA_INDEXIT_H__INCLUDED
Definition: indexit.h:141
HighDimIndexIterator()
Bury the default constructor.
Definition: indexit.h:144
virtual ~HighDimIndexIterator()
Definition: indexit.h:158
HighDimIndexIterator(int ndim, const long limits[])
Iterates dimension d from 0 to limts[d]-1 inclusive.
Definition: indexit.h:152
HighDimIndexIterator(int ndim, long top)
Iterates all dimensions from 0 to top-1 inclusive.
Definition: indexit.h:156
virtual IndexIterator & operator++()
Definition: indexit.h:163
HighDimIndexIterator(const V &limits)
Iterates dimension d from 0 to limts[d]-1 inclusive.
Definition: indexit.h:149
Definition: indexit.h:55
virtual IndexIterator & operator++()
this function should be abstracted and deprecated
Definition: indexit.h:114
bool finished
Definition: indexit.h:63
IndexIterator(int ndim, const long limits[])
Iterates dimension d from 0 to limts[d]-1 inclusive.
Definition: indexit.h:75
static void test()
this function should also be deprecated
Definition: indexit.h:128
std::vector< long > i
Current index.
Definition: indexit.h:62
virtual ~IndexIterator()
Definition: indexit.h:86
long operator[](int d) const
Definition: indexit.h:97
const std::vector< long > & operator*() const
Definition: indexit.h:103
std::vector< long > n
User specified upper limits for each dimension.
Definition: indexit.h:61
IndexIterator & reset()
Definition: indexit.h:89
IndexIterator()
Bury the default constructor.
Definition: indexit.h:58
IndexIterator(const V &limits)
Iterates dimension d from 0 to limts[d]-1 inclusive.
Definition: indexit.h:68
IndexIterator(int ndim, long top)
Iterates all dimensions from 0 to top-1 inclusive.
Definition: indexit.h:82
Definition: indexit.h:180
LowDimIndexIterator(int ndim, const long limits[])
Iterates dimension d from 0 to limts[d]-1 inclusive.
Definition: indexit.h:191
virtual IndexIterator & operator++()
Definition: indexit.h:202
virtual ~LowDimIndexIterator()
Definition: indexit.h:197
LowDimIndexIterator()
Bury the default constructor.
Definition: indexit.h:183
LowDimIndexIterator(const V &limits)
Iterates dimension d from 0 to limts[d]-1 inclusive.
Definition: indexit.h:188
LowDimIndexIterator(int ndim, long top)
Iterates all dimensions from 0 to top-1 inclusive.
Definition: indexit.h:195
Definition: indexit.h:224
std::vector< int > dim
Definition: indexit.h:233
NonstandardIndexIterator(const V &limits, const D &order)
Definition: indexit.h:242
NonstandardIndexIterator(int ndim, long top, const D &order)
Definition: indexit.h:284
virtual ~NonstandardIndexIterator()
Definition: indexit.h:320
virtual IndexIterator & operator++()
increment the dimensions in the order detailed in dim
Definition: indexit.h:324
NonstandardIndexIterator(int ndim, long top, const int order[])
Definition: indexit.h:305
NonstandardIndexIterator(int ndim, const long limits[], const int order[])
Definition: indexit.h:263
NonstandardIndexIterator()
Bury the default constructor.
Definition: indexit.h:227
A simple, fixed dimension vector.
Definition: vector.h:64
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition: madness_exception.h:134
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition: print.h:225
Defines simple templates for printing to std::cout "a la Python".
Definition: test_ar.cc:204
static double V(const coordT &r)
Definition: tdse.cc:288
void d()
Definition: test_sig.cc:79