cisst-saw
Loading...
Searching...
No Matches
nmrMultiIndexCounter.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5
6 Author(s): Ofri Sadowsky
7 Created on: 2003
8
9 (C) Copyright 2003-2007 Johns Hopkins University (JHU), All Rights
10 Reserved.
11
12--- begin cisst license - do not edit ---
13
14This software is provided "as is" under an open source license, with
15no warranty. The complete license can be found in license.txt and
16http://www.cisst.org/cisst/license.txt.
17
18--- end cisst license ---
19*/
20
21
22#ifndef _nmrMultiIndexCounter_h
23#define _nmrMultiIndexCounter_h
24
29#ifndef DEFINE_FORMATTED_OUTPUT
30#define DEFINE_FORMATTED_OUTPUT 0
31#endif
32
33#include <vector>
36
37// class nmrMultiIndexCounter
38// Implements a multi-counter iterator type.
39//
40// Usage example:
41//
42// nmrMultiIndexCounter counter(3);
43// nmrMultiIndexCounter::IndexType lowBounds[] = {0, 0, 0};
44// nmrMultiIndexCounter::IndexType highBounds[] = {2, 3, 4};
45// counter.SetBounds(lowBounds, highBounds);
46//
47// // go over all values between lowBounds and highBounds.
48// for(counter.GoToLowBounds(); counter.IsBelowHighBounds(); counter.Increment()) {
49// // use the counter cells, addressing them with operator[]
50// }
51//
52// Note 1: the bounds are "weak", in the sense that the test is for <= or >=
53// rather than the strict < or >. That is, the above program is equivalent to:
54//
55// for (i0 = 0; i0 <= 2; ++i0)
56// for (i1 = 0; i1 <= 3; ++i1)
57// for (i2 = 0; i2 <= 4; ++i2) {
58// // do something
59// }
60// }
61// }
62//
63//
64// Note 2: Increment() and Decrement() are complementary operations, except for overflow
65// and underflow cases. If a counter reaches overflow or underflow after Increment() or
66// Decrement(), the result of the opposite operation is COUNTER_UNDEFINED.
68{
69public:
70 typedef int IndexType;
71
73
75
76 // Initialize the counter by specifying the size (number of cells).
77 // The counter is initialized as all zeros, except for the increments which
78 // are all DefaultIncrement.
80
81 // Set all the increments to the default value (1)
83 {
84 Increments.assign( GetSize(), increment );
85 }
86
87 // return the size (number of cells) of the counter.
88 unsigned int GetSize() const
89 {
90 return Index.size();
91 }
92
93 // Set low and high bounds (inclusive!) for the counter. The low bounds
94 // must be <= the high bounds. In the current implementation, there is
95 // no check for it, and the user must take care of it.
96 // Set the status to COUNTER_UNDEFINED, since we don't check for the relationship
97 // between the actual index and the bounds at this stage.
98 // Note that the bounds are "weak", in the sense that the test is for <= or >=
99 // rather than the strict < or >.
100 void SetBounds(const IndexType lowBounds[], const IndexType highBounds[])
101 {
102 register int i;
103 register const int s = GetSize();
104 for (i = 0; i < s; i++) {
105 LowBounds[i] = lowBounds[i];
106 HighBounds[i] = highBounds[i];
107 }
109 }
110
111 // Set the lower bound of a single counter. 'counter' is the zero-based indicator
112 // of the counter to be set, 'bound' is the bound value for the counter.
113 void SetLowBound(unsigned int counter, IndexType bound)
114 {
115 LowBounds[counter] = bound;
116 }
117
118 // Set the higher bound of a single counter. 'counter' is the zero-based indicator
119 // of the counter to be set, 'bound' is the bound value for the counter.
120 void SetHighBound(unsigned int counter, IndexType bound)
121 {
122 HighBounds[counter] = bound;
123 }
124
125
126 // Set the increments for each of the cells. This does not affect the status.
127 // The increments have to be positive, although there is no assertion for it in
128 // the current implementation.
129 void SetIncrements(const IndexType increments[])
130 {
131 register int i;
132 register const int s = GetSize();
133 for (i = 0; i < s; i++) {
134 Increments[i] = increments[i];
135 }
136 }
137
138 // Set the increment of a single counter. 'counter' is the zero-based indicator
139 // of the counter to be set, 'increment' is the incrementation value for the counter.
140 void SetIncrement(unsigned int counter, IndexType increment)
141 {
142 Increments[counter] = increment;
143 }
144
145 // Return the value in a single cell.
146 IndexType operator[](unsigned int i) const
147 { return Index[i]; }
148
149 // Return a pointer to the cells as an array, if one wants to initialize other
150 // objects with the current values of the cells.
151 const IndexType * GetIndexCells() const
152 {
153 return &(Index[0]);
154 }
155
156 // Return the same pointer as GetIndexCells() but pointing unsigned int.
157 const unsigned int * GetIndexCellsAsUnsigned() const
158 {
159 return reinterpret_cast<const unsigned int *>(GetIndexCells());
160 }
161
162 const IndexType * GetLowBounds() const
163 {
164 return &(LowBounds[0]);
165 }
166
167 IndexType GetLowBound(unsigned int counter) const
168 {
169 return LowBounds[counter];
170 }
171
172 const IndexType * GetHighBounds() const
173 {
174 return &(HighBounds[0]);
175 }
176
177 IndexType GetHighBound(unsigned int counter) const
178 {
179 return HighBounds[counter];
180 }
181
182 const IndexType * GetIncrements() const
183 {
184 return &(Increments[0]);
185 }
186
187 IndexType GetIncrement(unsigned int counter) const
188 {
189 return Increments[counter];
190 }
191
192 // Set the index of a single cell to a given value without checking the status first.
193 // If the new value exceeds the bounds, then the function sets the status to COUNTER_UNDEFINED.
194 void SetIndex(unsigned int cell, IndexType value)
195 {
196 Index[cell] = value;
197 if ( (value < LowBounds[cell]) || (HighBounds[cell] < value) )
199 }
200
201 // Update the status of this object: first set it to COUNTER_UNDEFINED. If all the cells are
202 // in bounds, set it to COUNTER_IN_BOUNDS.
204 {
205 register int i;
206 register const int s = GetSize();
208 for (i = 0; i < s; i++) {
209 if ( (Index[i] < LowBounds[i]) || (HighBounds[i] < Index[i]) )
210 return;
211 }
212
214 }
215
218 bool IndexIsEqualTo(const nmrMultiIndexCounter & other) const;
219
223 {
224 register int i;
225 register const int s = GetSize();
226 for (i = 0; i < s; i++) {
227 Index[i] = LowBounds[i];
228 }
230 }
231
232
233 // Set the counter to the high bounds specified in SetBounds().
234 // Set the status to COUNTER_IN_BOUNDS.
236 {
237 register int i;
238 register const int s = GetSize();
239 for (i = 0; i < s; i++) {
240 Index[i] = HighBounds[i];
241 }
243 }
244
245 void GoTo(const IndexType where[])
246 {
247 register int i;
248 register const int s = GetSize();
249 for (i = 0; i < s; i++) {
250 Index[i] = where[i];
251 }
253 }
254
268 void Increment();
269
283 void Decrement();
284
287 {
288 return Status;
289 }
290
292 bool IsAboveLowBounds() const
293 {
294 return ( (GetStatus() != COUNTER_UNDEFINED) && (GetStatus() != COUNTER_UNDERFLOW) );
295 }
296
298 bool IsBelowHighBounds() const
299 {
300 return ( (GetStatus() != COUNTER_UNDEFINED) && (GetStatus() != COUNTER_OVERFLOW) );
301 }
302
304 bool IsBetweenBounds() const
305 {
306 return ( GetStatus() == COUNTER_IN_BOUNDS );
307 }
308
310 unsigned long GetNumberOfCombinations() const;
311
312protected:
313 typedef std::vector<IndexType> CounterType;
318
320
321};
322
323
324#endif
void SetHighBound(unsigned int counter, IndexType bound)
Definition nmrMultiIndexCounter.h:120
int IndexType
Definition nmrMultiIndexCounter.h:70
CounterStatus Status
Definition nmrMultiIndexCounter.h:319
const IndexType * GetIndexCells() const
Definition nmrMultiIndexCounter.h:151
IndexType GetHighBound(unsigned int counter) const
Definition nmrMultiIndexCounter.h:177
nmrMultiIndexCounter(unsigned int size)
unsigned long GetNumberOfCombinations() const
bool IsBetweenBounds() const
Definition nmrMultiIndexCounter.h:304
CounterType Index
Definition nmrMultiIndexCounter.h:314
IndexType GetLowBound(unsigned int counter) const
Definition nmrMultiIndexCounter.h:167
void SetIndex(unsigned int cell, IndexType value)
Definition nmrMultiIndexCounter.h:194
CounterStatus GetStatus() const
Definition nmrMultiIndexCounter.h:286
std::vector< IndexType > CounterType
Definition nmrMultiIndexCounter.h:313
const unsigned int * GetIndexCellsAsUnsigned() const
Definition nmrMultiIndexCounter.h:157
const IndexType * GetHighBounds() const
Definition nmrMultiIndexCounter.h:172
const IndexType * GetIncrements() const
Definition nmrMultiIndexCounter.h:182
const IndexType * GetLowBounds() const
Definition nmrMultiIndexCounter.h:162
CounterType LowBounds
Definition nmrMultiIndexCounter.h:315
void SetLowBound(unsigned int counter, IndexType bound)
Definition nmrMultiIndexCounter.h:113
void GoTo(const IndexType where[])
Definition nmrMultiIndexCounter.h:245
IndexType GetIncrement(unsigned int counter) const
Definition nmrMultiIndexCounter.h:187
void SetIncrements(const IndexType increments[])
Definition nmrMultiIndexCounter.h:129
static const IndexType DefaultIncrement
Definition nmrMultiIndexCounter.h:72
IndexType operator[](unsigned int i) const
Definition nmrMultiIndexCounter.h:146
bool IsAboveLowBounds() const
Definition nmrMultiIndexCounter.h:292
unsigned int GetSize() const
Definition nmrMultiIndexCounter.h:88
void UpdateStatus()
Definition nmrMultiIndexCounter.h:203
void SetIncrement(unsigned int counter, IndexType increment)
Definition nmrMultiIndexCounter.h:140
CounterType HighBounds
Definition nmrMultiIndexCounter.h:316
CounterStatus
Definition nmrMultiIndexCounter.h:74
@ COUNTER_UNDEFINED
Definition nmrMultiIndexCounter.h:74
@ COUNTER_IN_BOUNDS
Definition nmrMultiIndexCounter.h:74
@ COUNTER_UNDERFLOW
Definition nmrMultiIndexCounter.h:74
@ COUNTER_OVERFLOW
Definition nmrMultiIndexCounter.h:74
void GoToLowBounds()
Definition nmrMultiIndexCounter.h:222
CounterType Increments
Definition nmrMultiIndexCounter.h:317
void SetBounds(const IndexType lowBounds[], const IndexType highBounds[])
Definition nmrMultiIndexCounter.h:100
bool IndexIsEqualTo(const nmrMultiIndexCounter &other) const
void SetAllIncrements(IndexType increment)
Definition nmrMultiIndexCounter.h:82
bool IsBelowHighBounds() const
Definition nmrMultiIndexCounter.h:298
void GoToHighBounds()
Definition nmrMultiIndexCounter.h:235
#define CISST_EXPORT
Definition cmnExportMacros.h:50
Portability across compilers and operating systems tools.
Rules of exporting.
size_type size(void) const
Definition vctDynamicConstMatrixBase.h:228