DirectProductArray.hpp

00001 #ifndef __FIBER_DIRECTPRODUCT_HPP
00002 #define __FIBER_DIRECTPRODUCT_HPP
00003 
00004 #include "MemArray.hpp"
00005 
00006 namespace Fiber
00007 {
00008 using std::type_info;
00009 
00024 template <class T>
00025 class PolynomialArray : public MemArray<1, T>
00026 {
00027 public:
00028         typedef MemArray<1, T> Base_t;
00029         typedef typename Base_t::MultiArray_t MultiArray_t;
00030         MultiIndex<1>   max_index;
00031 
00032         using MultiArray_t::Size;
00033         using MultiArray_t::operator[];
00034 
00038         PolynomialArray(const MultiIndex<1>&M, index_t max_idx, const MemBase::Creator_t&C)
00039         : MemBase(C)
00040         , MemArray<1,T>(M,C)
00041         , max_index(max_idx)
00042         {}
00043 
00046         T operator()(index_t i) const
00047         {
00048         MultiIndex<1> Sz = Size();
00049 
00050         index_t p = Sz.size()-1;
00051         T       t = (*this)[p]; 
00052                 while(p>0)
00053                 {
00054                         t *= i;
00055                         p--;
00056                         t += (*this)[p];
00057                 }
00058                 return t;
00059         }
00060 
00061         index_t Length() const
00062         {
00063                 return max_index.size();
00064         }
00065 
00066         void resize(index_t newSize)
00067         {
00068                 max_index[0] = newSize;
00069         }
00070 
00080         bool locate(T&value) const
00081         {
00082                 if (Length()==2)
00083                 {
00084                         value = (value - (*this)[0] ) / (*this)[1]; 
00085                         return true;
00086                 }
00087 
00088                 return false;
00089         }
00090 };
00091 
00092 
00097 template <class T>
00098 class LinearArray : public PolynomialArray<T>
00099 {
00100 public:
00101         typedef PolynomialArray<T> Base_t;
00102         using Base_t::operator[];
00103 
00104         LinearArray(index_t max_idx, const MemBase::Creator_t&C)
00105         : MemBase(C)
00106         , Base_t(MIndex(2), max_idx, C)
00107         {}
00108 
00117         LinearArray(const T&C0, const T&C1, index_t max_idx, const MemBase::Creator_t&C)
00118         : MemBase(C)
00119         , Base_t(MIndex(2), max_idx, C)
00120         {
00121                 (*this)[0] = C0;
00122                 (*this)[1] = C1;
00123         }
00124 
00125         override MemCore::memsize_t memsize() const
00126         {
00127                 return 0;
00128         }
00129 
00130         T reverse(const T&value) const
00131         {
00132                 return (value - (*this)[0] ) / (*this)[1];
00133         }
00134 };
00135 
00136 
00157 template <class T, int MDIMS>
00158 class   DirectProductMemArrayBase : public MemArrayBase<MDIMS>
00159 {
00160 public:
00162         typedef typename T::value_type component_type;
00163 
00164         typedef PolynomialArray<component_type> PolynomialArray_t;
00165 
00166         enum
00167         {
00169                 COMPONENTS = T::SIZE,
00171                 Dims = MDIMS
00172         };
00173 
00175         RefPtr<PolynomialArray_t>       Components[ COMPONENTS ];
00176 
00182         Eagle::Vector<int, Dims>        ComponentMap;
00183 
00189         DirectProductMemArrayBase(const MemBase::Creator_t&C = MemCore::NullPtr() )
00190         : MemBase(C)
00191         , MemArrayBase<MDIMS>( C )
00192         {
00193                 for(int i=0; i<Dims; i++)
00194                 {
00195                         if (i<COMPONENTS)
00196                                 ComponentMap[ i ] = i; 
00197                         else
00198                                 ComponentMap[ i ] = -1; 
00199                 }
00200         }
00201 
00202         DirectProductMemArrayBase(const RefPtr<PolynomialArray_t> C[ COMPONENTS ],
00203                                   const Eagle::Vector<int, Dims> &CMap,
00204                                   const MemBase::Creator_t&theCreator = MemCore::NullPtr() )
00205         : MemArrayBase<MDIMS>(theCreator)
00206         {
00207                 for(int i=0; i<COMPONENTS; i++)
00208                 {
00209                         Components[i] = C[i];
00210                 }
00211 
00212                 for(int i=0; i<Dims; i++)
00213                 {
00214                         ComponentMap[ i ] = CMap[i];
00215                 }
00216         }
00217 
00218         override void DeferredConstructor()
00219         {
00220                 MemCore::SaveRegistry<DirectProductMemArrayBase>::addInterfaces(this); 
00221         }
00222 
00223         override MemCore::memsize_t memsize() const
00224         {
00225                 return 0;
00226         }
00227 
00228         override RefPtr<MemBase> newMemArray() const
00229         {
00230                 return new MemArray<MDIMS, T>( this->Size() );
00231         }
00232 
00238         RefPtr<MemArray<MDIMS,T> > createMemArray(const RefPtr<MemCore::ChunkBase>&Data, const MemBase::Creator_t&C) const
00239         {
00240                 if (!Data) return MemCore::NullPtr(); 
00241                 if (Data->elements() != Size().size() )
00242                         return MemCore::NullPtr(); 
00243 
00244                 return new MemArray<MDIMS,T>(Data, Size(), C );
00245         }
00246 
00253         override RefPtr<MemBase> createEquallySizedMemArray(const RefPtr<MemCore::ChunkBase>&Storage, const MemBase::Creator_t&C) const
00254         {
00255                 return createMemArray(Storage, C);
00256         }
00257 
00258         override RefPtr<MemBase> getComponentArray(int member, const MemBase::Creator_t&C)
00259         {
00260                 return MemCore::NullPtr();
00261         }
00262 
00263         void retrieve(T&retval, const MultiIndex<Dims>&I) const
00264         {
00265                 for(int i=0; i<Dims; i++)
00266                 {
00267                 int     component = ComponentMap[ i ]; 
00268                         if (component<0 || component>=COMPONENTS)
00269                                 continue;
00270 
00271                 const RefPtr<PolynomialArray_t>&that = Components[ component ];
00272 
00273                         if (that)
00274                                 retval[ component ] = (*that)( I[i] );
00275                 }
00276         }
00277 
00278         bool locate(T&pos) const
00279         {
00280                 for(int i=0; i<Dims; i++)
00281                 {
00282                 int     component = ComponentMap[ i ]; 
00283                         if (component<0 || component>=COMPONENTS)
00284                         {
00285                                 continue;
00286                         }
00287 
00288                 const RefPtr<PolynomialArray_t>&that = Components[ component ];
00289 
00290                         if (!that)
00291                                 return false; 
00292 
00293                         if (!that->locate( pos[ component ] ) )
00294                                 return false;
00295                 }
00296 
00297                 return true;
00298         }
00299 
00300         override MultiIndex<Dims> Size() const
00301         {
00302         MultiIndex<Dims> Sz;
00303                 for(int i=0; i<Dims; i++)
00304                 {
00305                 int     component = ComponentMap[ i ]; 
00306                         if (component<0 || component>=COMPONENTS)
00307                         {
00308                                 Sz[ i ] = 1; 
00309                                 continue;
00310                         }
00311                 const RefPtr<PolynomialArray_t>&that = Components[ component ]; 
00312                         Sz[i] = that->Length();
00313                 }
00314                 return Sz;
00315         }
00316 
00319         MultiIndex<Dims> firstIndex() const
00320         {
00321         MultiIndex<Dims> I;
00322                 for(int i=0; i<Dims; i++)
00323                         I[i] = 0;
00324 
00325                 return I;       
00326         }
00327 
00331         MultiIndex<Dims> lastIndex() const
00332         {
00333         MultiIndex<Dims> I; 
00334                 for(int i=0; i<Dims; i++)
00335                 {
00336                 index_t sz = this->Size()[i]; 
00337                         if (sz>1)
00338                                 I[i] = sz - 1; 
00339                         else
00340                                 I[i] = 0;
00341                 }
00342 
00343                 return Size() - MIndex(1,1,1);
00344         }
00345 
00346 //      override CreativeIterator<T>* creativeIterator()
00347 //      {
00348 //              return 0;
00349 //      }
00350 
00352         override const type_info&getType() const
00353         {
00354                 return typeid(T);
00355         }
00356 
00357         override RefPtr<MemBase> getSlice(index_t i, const MemBase::Creator_t&C) const
00358         {
00359                 return MemCore::NullPtr(); // not yet implemented...
00360         }
00361 
00363         override const FiberTypeBase&getFiberType() const
00364         {
00365                 return FiberType<T>::getFiberType();
00366         }
00367 
00369         override void*getPtr()
00370         {
00371                 return 0;
00372         }
00373 
00374         override HyperslabParameters& getHyperslabParameters()
00375         {
00376         static  HyperslabParameters nix(0,0,0);
00377                 return nix;
00378         }
00379 /*
00380         override RefPtr<UntypedCreativeIterator> getIterator() const
00381         {
00382                 return MemCore::NullPtr();
00383         }
00384 */
00385 };
00386 
00387 struct DirectProductMemArrayCreateBaseArray {};
00388 
00389 
00390 template <class T, int MDIMS = T::SIZE>
00391 class   DirectProductMemArray : public DirectProductMemArrayBase<typename T::FixedArray_t, MDIMS>, public TypedArray<T>
00392 {
00393 public:
00394         typedef MemArray<MDIMS, T> MemArray_t;
00395 
00397         typedef T value_type;
00398 
00400         typedef typename T::value_type component_type;
00401 
00402         typedef DirectProductMemArrayBase<typename T::FixedArray_t, MDIMS> DirectProductMemArrayBase_t;
00403         using DirectProductMemArrayBase_t::Size;
00404 
00405         enum
00406         {
00407                 COMPONENTS = DirectProductMemArrayBase_t::COMPONENTS,
00408                 Dims       = DirectProductMemArrayBase_t::Dims
00409         };
00410 
00416         T       origin;
00417 
00418         template <class TBase>
00419         DirectProductMemArray(const DirectProductMemArrayCreateBaseArray&,const DirectProductMemArray<TBase>&D, const MemBase::Creator_t&C = MemCore::NullPtr() )
00420         : DirectProductMemArrayBase_t(D.Components, D.ComponentMap, C)
00421         , TypedArray<T>( C )
00422         , origin(D.origin)
00423         {}
00424 
00425         DirectProductMemArray(const MemBase::Creator_t&C = MemCore::NullPtr() )
00426         : MemBase(C) // don't use creators here, these arrays don't take significant memory
00427         , TypedArray<T>( C )
00428         {
00429                 for(int c=0; c<COMPONENTS; c++)
00430                         origin[ c ] = 0;
00431         }
00432 
00433         virtual override const T&Origin() const = 0;
00434         virtual override const T&Delta()  const = 0;
00435 
00436         override const void*OriginPtr() const { return &Origin(); }
00437         override const void*DeltaPtr()  const { return &Delta();  }
00438 
00439         T operator[](const MultiIndex<Dims>&I) const
00440         {
00441         T       retval = origin; 
00442                 retrieve( retval, I ); 
00443                 return retval;
00444         }
00445 
00449         override RefPtr<MemBase> makeMemArray(const MemBase::Creator_t&C) const
00450         {
00451         MultiIndex<Dims> Sz = this->Size(); 
00452 
00453         RefPtr<MemArray_t> M = new MemArray_t( Sz, C );
00454         typename MemArray_t::MultiArray_t&dst = *M;
00455 
00456         MultiIndex<Dims> idx;
00457 
00458         T       val = origin;
00459                 do
00460                 {
00461                         retrieve( val, idx);
00462                         dst[idx] = val;
00463 
00464 /*
00465   cannot use retrieve(dst[idx]) here, because dst[idx] might be an ElementProxy type,
00466   and passing such as non-const reference doesnt work.
00467   would be interesting how to fix that. if it is possible at all.
00468  */
00469 //                      retrieve( dst[idx], idx);
00470                 }
00471                 while( idx.inc( Sz ) );
00472 
00473                 return M;
00474         }
00475 
00476 
00477         override RefPtr<MemBase> getFixedArray() const
00478         {
00479                 return MemCore::NullPtr(); 
00480 //              return new DirectProductMemArray<FixedArray<component_type, MDIMS>, MDIMS>(DirectProductMemArrayCreateBaseArray(), *this);
00481         }
00482 
00483         override RefPtr<MemBase> getVectorArray() const
00484         {
00485                 return MemCore::NullPtr();
00486 //              return new DirectProductMemArray<Eagle::Vector<component_type, MDIMS>, MDIMS>(DirectProductMemArrayCreateBaseArray(), *this);
00487         }
00488 
00489 
00490         override RefPtr<MemBase> createMemArray(const MultiIndex<Dims>&, const MemBase::Creator_t&C) const
00491         {
00492                 return MemCore::NullPtr();
00493         }
00494 
00495         override RefPtr<MemBase> createSubMemArray(const MultiIndex<Dims>&, const MultiIndex<Dims>&, const MemBase::Creator_t&C) const
00496         {
00497                 return MemCore::NullPtr();
00498         }
00499 
00501         override const FiberTypeBase&getFiberType() const
00502         {
00503                 return FiberType<T>::getFiberType();
00504         }
00505 
00507         override const type_info&getType() const
00508         {
00509                 return typeid(T);
00510         }
00511 
00513         override CreativeIterator<T>* creativeIterator()
00514         {
00515                 return 0;
00516         }
00517 
00519         override const CreativeIterator<T>* creativeIterator() const
00520         {
00521                 return 0;
00522         }
00523 
00525         override RefPtr<MemCore::TypedChunk<T> > myChunk() const
00526         {
00527                 return MemCore::NullPtr();
00528         }
00529 
00530         override T first() const
00531         {
00532                 return (*this)[ this->firstIndex() ];   
00533         }
00534 
00535         override T last() const
00536         {
00537                 return (*this)[ this->lastIndex() ];
00538         }
00539 };
00540 
00541 
00554 template <class T, class DeltaT = T, int MDIMS = T::SIZE>
00555 class   LinearDirectProductMemArray : public DirectProductMemArray<T, MDIMS>
00556 {
00557 public:
00558         using DirectProductMemArray<T, MDIMS>::Components;
00559 
00560         enum { COMPONENTS = T::SIZE };
00561 
00563         typedef typename T::value_type component_type;
00564 
00565         const T baseValue;
00566         const DeltaT deltaValue;
00567 
00568         override const T&Origin()      const { return baseValue; }
00569         override const DeltaT&Delta()  const { return deltaValue; }
00570 
00579         LinearDirectProductMemArray(const index_t dims[MDIMS], const T&base, const DeltaT&delta, const MemBase::Creator_t&C = MemCore::NullPtr() )
00580         : MemBase(C)
00581         , DirectProductMemArray<T, MDIMS>(C)
00582         , baseValue(base)
00583         , deltaValue(delta)
00584         {
00585                 for(int c=0; c<COMPONENTS; c++)
00586                 {
00587                 int     length = c<MDIMS ? dims[c] : 0;
00588 
00589                 RefPtr<LinearArray<component_type> > 
00590                         LA = new LinearArray<component_type>( base[c], delta[c], length, C );
00591 
00592                         Components[c] = LA;
00593                 }
00594         }
00595 
00600         LinearDirectProductMemArray(const MultiIndex<MDIMS>&dims, const T&base, const DeltaT&delta, const MemBase::Creator_t&C = MemCore::NullPtr() )
00601         : MemBase(C)
00602         , DirectProductMemArray<T, MDIMS>(C)
00603         , baseValue(base)
00604         , deltaValue(delta)
00605         {
00606                 for(int c=0; c<COMPONENTS; c++)
00607                 {
00608                 int     length = c<MDIMS ? dims[c] : 0;
00609 
00610                 RefPtr<LinearArray<component_type> > 
00611                         LA = new LinearArray<component_type>( base[c], delta[c], length, C );
00612 
00613                         Components[c] = LA;
00614                 }
00615         }
00616 
00617         bool resize(int component, index_t newSize)
00618         {
00619                 if (RefPtr<LinearArray<component_type> > LA = Components[component])
00620                 {
00621                         LA->resize( newSize ); 
00622                         return true;
00623                 } 
00624                 return false;
00625         }
00626 };
00627 
00628 } /* namespace Fiber */ 
00629 
00630 #endif /* __FIBER_DIRECTPRODUCT_HPP */
00631