00001 #ifndef __FIBER_MULTIARRAY_HPP
00002 #define __FIBER_MULTIARRAY_HPP "Created 3.07.2004 21:42:21 by bzfbenge"
00003
00004 #include "MultiIndex.hpp"
00005 #include "Iterator.hpp"
00006 #include "Expression.hpp"
00007 #include "CreativeIterator.hpp"
00008
00009 #include <vector>
00010
00011 namespace Fiber
00012 {
00013 using Eagle::MetaInfo;
00014
00027 template <int N, class T>
00028 class MultiArrayBase : public CreativeIterator<T>
00029 {
00030 private:
00031 MultiIndex<N> dimensions;
00032
00033 using CreativeIterator<T>::myCreator;
00034
00035 public:
00036 typedef CreativeIterator<T> Base_t;
00037
00039 using CreativeIterator<T>::ptr;
00040
00041 using Base_t::ValueBase_t;
00042 using Base_t::component_t;
00043
00045 enum { Dims = N };
00046
00048 typedef T value_type;
00049
00051 typedef Iterator<T> Storage_t;
00052
00054 typedef Iterator<T> SliceStorge_t;
00055
00058 typedef MultiArrayBase<N-1,T> Slice_t;
00059
00060 typedef typename Iterator<T>::reference_t reference_t;
00061
00063 MultiArrayBase(T*data, const MultiIndex<Dims>&Extension, DataCreator<T>*Crec)
00064 : CreativeIterator<T>( Extension.size(), data, Crec)
00065 , dimensions(Extension)
00066 {}
00067
00069 MultiArrayBase(const Iterator<T>&data, const MultiIndex<Dims>&Extension, DataCreator<T>*TheCreator=0)
00070 : Base_t(data, TheCreator)
00071 , dimensions(Extension)
00072 {
00073 if (Extension.size() < this->count() )
00074 {
00075 this->setCount( dimensions.size() );
00076 }
00077 }
00078
00080 MultiArrayBase(const MultiArrayBase&MAB)
00081 : Base_t(MAB)
00082 , dimensions(MAB.dimensions)
00083 {}
00084
00086 unsigned long memsize() const
00087 {
00088 return dimensions.size() * sizeof(T);
00089 }
00090
00092 const Storage_t&storage() const
00093 {
00094 return (*this);
00095 }
00096
00098 const MultiIndex<Dims>&Size() const
00099 {
00100 return dimensions;
00101 }
00102
00104 void Resize(T*data, const MultiIndex<N>&D)
00105 {
00106 this->dimensions = D;
00107 this->SetNewData(data, dimensions.size() );
00108
00109 }
00110
00111
00113 index_t nElements() const
00114 {
00115 return dimensions.size();
00116 }
00117
00121 reference_t operator[](const MultiIndex<N>&I) const
00122 {
00123 if (!ptr() )
00124 {
00125 assert( myCreator );
00126
00127 index_t i = I.maxidx();
00128 Slice_t mySlice( myCreator->slice(Dims-1, i), dimensions.subidx(), myCreator);
00129 MultiIndex<Dims-1> sI = I.subidx();
00130
00131 return mySlice[ sI ];
00132 }
00133
00134 return Base_t::operator[]( I.linear(dimensions) );
00135 }
00136
00144 Slice_t slice(index_t i) const
00145 {
00146 const MultiIndex<Dims-1>&SubSize = dimensions.subidx();
00147 assert(i>=0 && i < dimensions.maxidx() );
00148
00149 if (!ptr() )
00150 {
00151 assert(myCreator);
00152
00153 return Slice_t( myCreator->slice(Dims-1, i), SubSize, myCreator);
00154 }
00155
00156
00157
00158 return Slice_t( *(Iterator<T>*)this + index_t(i*SubSize.size()), SubSize, 0 );
00159 }
00160
00161 Slice_t operator[](index_t i) const
00162 {
00163 return slice(i);
00164 }
00165
00166 reference_t first() const
00167 {
00168 MultiIndex<N> I;
00169 for(int i=0; i<N; i++)
00170 I[i] = 0;
00171
00172 return (*this)[ I ];
00173 }
00174
00175
00176 reference_t last() const
00177 {
00178 MultiIndex<N> I;
00179 for(int i=0; i<N; i++)
00180 {
00181 if (dimensions[i]<1)
00182 I[i] = 0;
00183 else
00184 I[i] = dimensions[i] - 1;
00185 }
00186
00187 return (*this)[ I ];
00188 }
00189 };
00190
00203 template <class T>
00204 class MultiArrayBase<1,T> : public CreativeIterator<T>
00205 {
00206 using CreativeIterator<T>::myCreator;
00207 public:
00208 using CreativeIterator<T>::ptr;
00209
00210 typedef CreativeIterator<T> Base_t;
00211
00212 using Base_t::ValueBase_t;
00213 using Base_t::component_t;
00214
00215 enum { Dims = 1 };
00216
00217 MultiIndex<Dims> dimensions;
00218
00219 using Iterator<T>::count;
00220
00221 typedef T value_type;
00222
00224 typedef Iterator<T> Storage_t;
00225
00226 typedef typename Iterator<T>::reference_t reference_t;
00227
00229 MultiArrayBase<1,T>(const Iterator<T>&data, const MultiIndex<Dims>&Extension, DataCreator<T>*Crec)
00230 : Base_t(data, Crec)
00231 , dimensions( Extension )
00232 {
00233 if (count() > dimensions.size() )
00234 this->setCount( dimensions.size() );
00235 }
00236
00238 const Storage_t&storage() const
00239 {
00240 return *this;
00241 }
00242
00244 void Resize(T*newData, const MultiIndex<1>&D)
00245 {
00246 this->dimensions = D;
00247 this->SetNewData(newData, D.size() );
00248 }
00249
00251 void Resize(T*newData, const index_t&D)
00252 {
00253 Resize(newData, MIndex(D) );
00254 }
00255
00257 unsigned long memsize() const
00258 {
00259 return dimensions.size() * sizeof(T);
00260 }
00261
00262 Iterator<T> getData(index_t i) const
00263 {
00264 return (*this)+i;
00265 }
00266
00268 const MultiIndex<Dims>&Size() const
00269 {
00270 return dimensions;
00271 }
00272
00275 index_t nElements() const
00276 {
00277 return dimensions.size();
00278 }
00279
00282 const reference_t operator[](index_t i) const
00283 {
00284 if (myCreator)
00285 return myCreator->getElement(i);
00286
00287 return storage()[ i ];
00288 }
00289
00292 reference_t operator[](index_t i)
00293 {
00294 if (myCreator)
00295 return myCreator->getElement(i);
00296
00297 return storage()[ i ];
00298 }
00299
00301 const reference_t operator[](const MultiIndex<1>&I) const
00302 {
00303 index_t i = I.maxidx();
00304 return (*this)[ i ];
00305 }
00306
00308 reference_t operator[](const MultiIndex<1>&I)
00309 {
00310 return (*this)[ I.maxidx() ];
00311 }
00312
00313 const reference_t slice(index_t i) const
00314 {
00315 return (*this)[i];
00316 }
00317
00319 const reference_t first() const
00320 {
00321 return (*this)[ 0 ];
00322 }
00323
00325 const reference_t last() const
00326 {
00327 index_t I = 0;
00328 if (dimensions[0]>1)
00329 I = dimensions[0] - 1;
00330
00331 return (*this)[ I ];
00332 }
00333 };
00334
00335
00336
00347 template <int N, class T>
00348 struct MultiArray : public MultiArrayBase<N,T>
00349 {
00350 public:
00351 typedef MultiArrayBase<N,T> Base_t;
00352
00353 typedef typename Base_t::value_type value_type;
00354
00355 typedef MultiArray MultiArray_t;
00356
00357 using Base_t::Size;
00358 using Base_t::slice;
00359 using Base_t::operator[];
00360 using Base_t::ptr;
00361
00362
00363 typedef typename Base_t::ValueBase_t ValueBase_t;
00364 typedef typename Base_t::component_t component_t;
00365
00366
00367 typedef MultiArray<N, ValueBase_t> MultiArrayBase_t;
00368
00369 typedef MultiArray<N, component_t> MultiArrayComponent_t;
00370
00374 MultiArray(T*data, const MultiIndex<N>&Sz)
00375 : Base_t( Iterator<T>(Sz.size(), data), Sz)
00376 {}
00377
00382 MultiArray(const MultiIndex<N>&Sz, DataCreator<T>*Crec)
00383 : Base_t(0, Sz, Crec)
00384 {}
00385
00390 MultiArray(const Iterator<T>&data, const MultiIndex<N>&Sz)
00391 : Base_t(data, Sz, 0)
00392 {}
00393
00394 MultiArray(const MultiArray&MA)
00395 : Base_t(MA)
00396 {}
00397
00398 MultiArray(const Base_t&MA)
00399 : Base_t(MA)
00400 {}
00401
00402 MultiArrayBase_t arraybase() const
00403 {
00404 return MultiArrayBase_t( this->getArrayIterator(), Size() );
00405
00406 }
00407
00413 operator MultiArrayBase_t() const
00414 {
00415 return arraybase();
00416 }
00417
00418
00419 MultiArrayComponent_t component(int i) const
00420 {
00421 return MultiArrayComponent_t(this->getComponent(i), Size() );
00422 }
00423
00425 typedef Iterator<T> SliceStorage_t;
00426
00427 typedef typename MultiArray<N-1,T>::MultiArray_t Hyperslab_t;
00428
00441 Hyperslab_t operator[](index_t i) const
00442 {
00443 return Hyperslab_t( slice(i) );
00444 }
00445 };
00446
00447
00448 template <class T>
00449 class MultiArray<0, T>
00450 {
00451 public:
00452 typedef T MultiArray_t;
00453
00454 typedef typename MetaInfo<T>::element_t component_t;
00455
00456 typedef FixedArray< component_t, MetaInfo<T>::MULTIPLICITY>
00457 FixedArray_t;
00458
00459 typedef typename META::IF< MetaInfo<T>::MULTIPLICITY == 1,
00460 component_t, FixedArray_t>::result ValueBase_t;
00461
00462 typedef MultiArray<0, ValueBase_t> MultiArrayBase_t;
00463
00464 typedef MultiArray<0, component_t> MultiArrayComponent_t;
00465
00466
00467 void *ptr() const { return 0; }
00468 };
00469
00470
00471 template <int I> struct MultiArrayOutStreamSeparator
00472 {
00473 enum { begin = '{', end = '}' };
00474 };
00475
00476 template <> struct MultiArrayOutStreamSeparator<1>
00477 {
00478 enum { begin = 0, end = ' ' };
00479 };
00480
00481 template <> struct MultiArrayOutStreamSeparator<2>
00482 {
00483 enum { begin ='(', end = ')' };
00484 };
00485
00486 template <> struct MultiArrayOutStreamSeparator<3>
00487 {
00488 enum { begin = 0, end = '\n' };
00489 };
00490
00491
00492 #if defined(_IOSTREAM_) || defined(_GLIBCXX_OSTREAM) || _CPP_IOSTREAM || defined(__SGI_STL_IOSTREAM)
00493
00494 template <int N, class T>
00495 std::ostream&operator<<(std::ostream&out, const MultiArray<N,T>&M)
00496 {
00497 for(index_t k=0; k<M.Size()[N-1]; k++)
00498 {
00499 if (MultiArrayOutStreamSeparator<N>::begin)
00500 out << char(MultiArrayOutStreamSeparator<N>::begin);
00501
00502 out << M[k]
00503 << char(MultiArrayOutStreamSeparator<N>::end);
00504 }
00505 return out;
00506 }
00507
00508 #endif
00509
00510
00511 template <class Operator>
00512 struct MExpression
00513 {
00514
00515 template <int D, class Data, class Data1, class Data2>
00516 static void ternary(const MultiArray<D,Data >&p,
00517 const MultiArray<D,Data1>&q,
00518 const MultiArray<D,Data2>&r)
00519 {
00520 Expression<Operator>::ternary( array_iterator(p),
00521 array_iterator(q),
00522 array_iterator(r) );
00523 }
00524 };
00525
00529 template <int N, class T>
00530 struct MultiArraySTLVector : public std::vector<T>, public MultiArray<N,T>
00531 {
00532 MultiArraySTLVector(const MultiIndex<N>&Sz)
00533 : std::vector<T>( Sz.size() )
00534 , MultiArray<N,T>( &*this->begin(), Sz )
00535 {}
00536 };
00537
00538
00539 }
00540
00541 #endif
00542