MultiArray.hpp

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                 // Create subarray from iterator here, no on-demand creator here (last argument 0)
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 //      using typename Base_t::ValueBase_t;
00363         typedef typename Base_t::ValueBase_t ValueBase_t;
00364         typedef typename Base_t::component_t component_t;
00365 //      using Base_t::component_t;
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 //              return MultiArrayBase_t(array_iterator(*this), Size() );
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 //               MSVC                           GCC             G++                   SGI C++
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 } /* namespace Fiber */ 
00540 
00541 #endif /* __Fiber_MULTIARRAY_HPP */
00542