Overture  Version 25
SparseArray.h
Go to the documentation of this file.
1 #ifndef SPARSE_ARRAY
2 #define SPARSE_ARRAY
3 
4 // =====================================================================================
5 // Templated Sparse Array class
6 //
7 // o multi-dimensional array (zero base)
8 // o default value is given to all entries
9 // o only entries with non-default values are stored
10 //
11 // Example:
12 // SparseArray<real> b(5,5);
13 // b.setDefaultValue(7.);
14 // b.set( 24., 2,4 ); // b(2,4)=24.
15 // b.get(1,2)=12.; // b(1,2)=12.
16 // for( int i0=0; i0<5; i0++ )
17 // {
18 // for( int i1=0; i1<5; i1++ )
19 // {
20 // printf("b(%i,%i)=%g ",i0,i1,b(i0,i1));
21 // }
22 // printf("\n");
23 // }
24 // =====================================================================================
25 
26 
27 
28 #define SPARSE_MAP std::map
29 #include <map>
30 
31 // The hash_map has a constant time lookup (modulo initialization costs)
32 // #define SPARSE_MAP hash_map
33 // using namespace std;
34 
35 // #include <ext/hash_map>
36 
37 #define MAX_SPARSE_ARRAY_DIMS 6
38 
39 template<class T>
41 {
42 public:
43 
44 typedef SPARSE_MAP<int, T, std::less<int> > SmapType;
45 
46 SparseArray(int n0=0, int n1=1, int n2=1, int n3=1, int n4=1, int n5=1);
47 ~SparseArray();
48 
49 // access an array entry (no new entry is created)
50 const T & operator()(int i0, int i1=0, int i2=0, int i3=0, int i4=0, int i5=0) const;
51 
52 // delete all sparse entries:
53 void clear();
54 
55 // void compress( vector<int> & indexInfo, vector<T> & sparseData );
56 // void decompress( const vector<int> & indexInfo, const vector<T> & sparseData );
57 
58 // remove all entries and redimension the array to size 0
59 void destroy();
60 
61 // get a reference to an array entry (an new entry will be created if needed)
62 T & get(int i0=0, int i1=0, int i2=0, int i3=0, int i4=0, int i5=0 );
63 
64 // redimension the array.
65 void redim(int n0, int n1=1, int n2=1, int n3=1, int n4=1, int n5=1);
66 
67 // set an array value. Create an entry if needed. Erase the entry if value=defaultValue
68 void set( const T & value, int i0, int i1=0, int i2=0, int i3=0, int i4=0, int i5=0 );
69 
70 void setDefaultValue( const T & value );
71 
72 int size() const; // return the total number of (possible entries)
73 
74 int size(int d ) const; // return the size of dimension d of the array
75 
76 // return the number of sparse entries stored
77 int sparseSize() const;
78 
79 // // ---> We could also have a state that is set to create an entry if needed ---
80 // enum AssignOptionEnum
81 // {
82 // createEntryIfNeeded=0
83 // };
84 //
85 //
86 // // use this operator to create an entry if it is accessed but does not exist
87 // T & operator()( const int i, AssignOptionEnum opt );
88 
89 protected:
90 
91 int boundsCheck(int i0, int i1, int i2, int i3, int i4, int i5 ) const;
92 
93 SPARSE_MAP<int, T, std::less<int> > smap;
94 
97 
98 };
99 
100 #define SPARSE_INDEX(i0,i1,i2,i3,i4,i5) ((i0)+dims[0]*((i1)+dims[1]*((i2)+dims[2]*((i3)+dims[3]*((i4)+dims[4]*((i5)))))))
101 
102 template<class T> SparseArray<T>::
103 SparseArray(int n0 /* =0 */, int n1 /* =1 */, int n2 /* =1 */, int n3 /* =1 */, int n4 /* =1 */, int n5 /* =1 */)
104 // ===============================================================================================
105 // /Description:
106 // Create a sparse array with dimensions (n0,n1,...) ande default value of zero.
107 //
108 // /n0,n1,... (input) : dimensions
109 // ===============================================================================================
110 {
111  dims[0]=n0;
112  dims[1]=n1;
113  dims[2]=n2;
114  dims[3]=n3;
115  dims[4]=n4;
116  dims[5]=n5;
117  defaultValue=0;
118 }
119 
120 template<class T> SparseArray<T>::
122 {
123 }
124 
125 template<class T> int SparseArray<T>::
126 boundsCheck(int i0, int i1, int i2, int i3, int i4, int i5 ) const
127 {
128  int iv[MAX_SPARSE_ARRAY_DIMS]={i0,i1,i2,i3,i4,i5}; //
129  bool ok=true;
130  for( int d=0; d<MAX_SPARSE_ARRAY_DIMS; d++ )
131  {
132  if( iv[d]<0 || iv[d]>=dims[d] )
133  {
134  ok=false;
135  printf("SparseArray::boundsCheck: index i%i=%i is out of bounds : [%i,%i]\n",d,iv[d],0,dims[d]-1);
136  }
137  }
138  if( !ok ) Overture::abort("error");
139  return 0;
140 }
141 
142 
143 template<class T> void SparseArray<T>::
145 // ===============================================================================================
146 // /Description:
147 // Remove all entries from the array.
148 // ===============================================================================================
149 {
150  smap.clear();
151 }
152 
153 template<class T> void SparseArray<T>::
155 // ===============================================================================================
156 // /Description:
157 // Remove all entries from the array.
158 // ===============================================================================================
159 {
160  clear();
161  redim(0,0,0,0,0,0);
162 }
163 
164 
165 template<class T> T & SparseArray<T>::
166 get(int i0/* =0 */, int i1/* =0 */, int i2/* =0 */, int i3/* =0 */, int i4/* =0 */, int i5/* =0 */)
167 // ===============================================================================================
168 // /Description:
169 // Return a reference to value of the array at index (i0,i1,...)
170 // /i0,i1,... (input) : index to evaluate the array at
171 // ===============================================================================================
172 {
173  boundsCheck(i0,i1,i2,i3,i4,i5);
174  const int i = SPARSE_INDEX(i0,i1,i2,i3,i4,i5);
175 
176  typename SmapType::iterator sait = smap.find(i);
177 
178  if( sait != smap.end() )
179  {
180  return (*sait).second;
181  }
182  else
183  {
184  // printf(" SparseArray: insert a new value into the array at [%i]\n",i);
185  smap[i]=defaultValue;
186  return smap[i];
187  }
188 }
189 
190 
191 template<class T> void SparseArray<T>::
192 redim(int n0 , int n1 /* =1 */, int n2 /* =1 */, int n3 /* =1 */, int n4 /* =1 */, int n5 /* =1 */)
193 // ===============================================================================================
194 // /Description:
195 // Redimension the array
196 // /n0,n1,... (input) : dimensions
197 // ===============================================================================================
198 {
199  dims[0]=n0;
200  dims[1]=n1;
201  dims[2]=n2;
202  dims[3]=n3;
203  dims[4]=n4;
204  dims[5]=n5;
205 }
206 
207 
208 template<class T> const T & SparseArray<T>::
209 operator()(int i0, int i1/* =0 */, int i2/* =0 */, int i3/* =0 */, int i4/* =0 */, int i5/* =0 */ ) const
210 // ===============================================================================================
211 // /Description:
212 // Return the value of the array at index (i0,i1,...)
213 // /i0,i1,... (input) : index to evaluate the array at
214 // ===============================================================================================
215 {
216  boundsCheck(i0,i1,i2,i3,i4,i5);
217  const int i = SPARSE_INDEX(i0,i1,i2,i3,i4,i5);
218 
219  typename SmapType::const_iterator sait= smap.find(i);
220 
221  sait = smap.find(i);
222  if( sait != smap.end() )
223  return (*sait).second;
224  else
225  return defaultValue;
226 }
227 
228 template<class T> void SparseArray<T>::
229 set(const T & value, int i0, int i1/* =0 */, int i2/* =0 */, int i3/* =0 */, int i4/* =0 */, int i5/* =0 */ )
230 // ===============================================================================================
231 // /Description:
232 // Assign a value:
233 // array(i0,i1,i2,...)=value
234 // Create a new entry if one is not alread y there.
235 //
236 // /i0,i1,... (input) : index to evaluate the array at
237 // ===============================================================================================
238 {
239  boundsCheck(i0,i1,i2,i3,i4,i5);
240  const int i = SPARSE_INDEX(i0,i1,i2,i3,i4,i5);
241 
242  typename SmapType::iterator sait = smap.find(i);
243 
244  if( sait != smap.end() )
245  {
246  if( value!=defaultValue )
247  (*sait).second=value;
248  else
249  {
250  // Remove the entry if value==defaultValue
251  smap.erase(sait);
252  }
253 
254  }
255  else if( value!=defaultValue )
256  {
257  // printf(" SparseArray: insert a new value into the array at [%i]\n",i);
258  smap[i]=value;
259  }
260 
261 }
262 
263 template<class T> void SparseArray<T>::
264 setDefaultValue( const T & value )
265 // ===============================================================================================
266 // /Description:
267 // Assign a the default value for array entries that have not been set.
268 //
269 // /value (input) : default value for array entries that have not been set.
270 // ===============================================================================================
271 {
272  defaultValue=value;
273 }
274 
275 template<class T> int SparseArray<T>::
276 size() const
277 // ===============================================================================================
278 // /Description:
279 // Return the total number of (possible) entries
280 //
281 // ===============================================================================================
282 {
283  int total=1;
284  for( int d=0; d<MAX_SPARSE_ARRAY_DIMS; d++ )
285  total*=dims[d];
286  return total;
287 }
288 
289 template<class T> int SparseArray<T>::
290 size(int d ) const
291 // ===============================================================================================
292 // /Description:
293 // Return the size of dimension d of the array.
294 //
295 // ===============================================================================================
296 {
297  if( d>=0 && d<MAX_SPARSE_ARRAY_DIMS )
298  return dims[d];
299  else
300  {
301  printf("SparseArray:ERROR:size: invalid array dimension d=%i\n",d);
302  return -1;
303  }
304 
305 }
306 
307 
308 template<class T> int SparseArray<T>::
309 sparseSize() const
310 // ===============================================================================================
311 // /Description:
312 // Return the number of non-default entries in the sparse array
313 //
314 // ===============================================================================================
315 {
316  return smap.size();
317 }
318 
319 
320 
321 // // use this operator to create an entry if it is accessed but does not exist
322 // template<class T> T & SparseArray<T>::
323 // operator()( const int i, AssignOptionEnum opt )
324 // {
325 // typedef map<int, T, less<int> > SmapT;
326 // typename SmapT::const_iterator sait = smap.find(i);
327 //
328 // sait = smap.find(i);
329 // if( sait != smap.end() )
330 // {
331 // return (*sait).second;
332 // }
333 // else
334 // {
335 // printf(" SparseArray: insert a new value into the array at [%i]\n",i);
336 // // return (*this)[i](defaultValue);
337 // return smap[i];
338 // }
339 // }
340 
341 #undef SPARSE_INDEX
342 #undef MAX_SPARSE_ARRAY_DIMS
343 #undef SPARSE_MAP
344 
345 #endif