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
00347
00348
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();
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
00381
00382
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)
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
00466
00467
00468
00469
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
00481 }
00482
00483 override RefPtr<MemBase> getVectorArray() const
00484 {
00485 return MemCore::NullPtr();
00486
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 }
00629
00630 #endif
00631