Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

TensorArray.H

Go to the documentation of this file.
00001 
00030 #ifndef _TENSORARRAY_H
00031 #define _TENSORARRAY_H
00032 
00033 
00034 #include <vector>
00035 #include <cstdarg>
00036 #include <iterator>
00037 
00038 #include <TensorArrayRowIterator.H>
00039 #include <TensorArrayIndexIterator.H>
00040 #include <TensorArraySliceIterator.H>
00041 #include <arglst.H>
00042 #include <xmath.H>
00043 #include <ListAssignment.H>
00044 #include <tensor_array_typedef.H>
00045 #include <Transform.H>
00046 
00047 using namespace std;
00048 
00049 namespace xchen
00050 {
00051   //   template<typename T, int dims>
00052   //   class TensorArraySliceIterator;
00053   
00057   template<typename T, int dims>
00058   class TensorArray
00059   {
00060       def_type_name_for_tensor_array(T, dims);
00061 
00062       friend class TensorArray<T,dims-1>;
00063 
00064   public:
00065       TensorArray();                                   
00066       explicit TensorArray(int sz, ...);               
00067       explicit TensorArray(int* sz);                   
00068       TensorArray(MyType const&);                      
00069       TensorArray(MyType const&, int d, int s, int e); 
00070       TensorArray(MyType const&, int*start, int*end);  
00071 
00072       TensorArray(TensorArray<T,dims+1> const& rhs, int d, int s); 
00073 
00074 
00075       ~TensorArray()                                   { delete [] data; delete idx_itr; }
00076 
00077       TensorArray& Transform(xchen::Transform const&); 
00078       
00079       void Clear();                                    
00080       bool Empty() const                               { return find(sz, sz+dims, 0) != sz+dims; }
00081 
00082       void PopFront(int i=0);                         
00083       void PopBack(int i=0);                           
00084 
00085       void Insert(linear_iterator itr, T const& val); 
00086       void Insert(int dir, int before);                
00087       
00088       void SetN(int N);                                
00089 
00090       void InsertMiddlePoints(bool average=true);      
00091 
00092       void Averaging();                                
00093 
00094       TensorArray& operator=(const TensorArray& rhs);  
00095       
00096       int GetSize(int dir=0) const                     { return sz[dir]; }  
00097       void GetSize(int* Sz) const                      { copy(sz, sz+dims, Sz); } 
00098       int GetTotalSize() const                         { return totalSz; }  
00099       
00100       void Reserve(int newCapacity,...);               
00101       void Reserve(int* newCapacity);                  
00102       void Resize(int newSz, ...);                     
00103       void Resize(int* newSz);                         
00104       void ResizeOneDirection(int i, int new_sz);      
00105       void CopyExtend(int left, ...);                  
00106       void CopyExtend(int* rightleft);                 
00107       void CopyExtendAtDirection(int i, 
00108                                  int left, int right); 
00109       void ExtendAtDirection(int i, 
00110                              int left, int right);     
00111       void Extend(int left, ...);                      
00112       void Extend(int* rightleft);                     
00113 
00114       slc_iterator SliceIterate(int dir=0, int start=0, int end=0)        { return slc_iterator(this, dir, start, end); }
00115       
00116       linear_iterator LinearIterate(int dir, int start, int len);         
00117       linear_iterator LinearIterate(int*start=0, int*end=0)               { return linear_iterator(this, start, end); }  
00118       linear_iterator Begin()                                             { return LinearIterate().Begin(); }            
00119       linear_iterator End()                                               { return LinearIterate().End(); }              
00120 
00121       linear_riterator LinearReverseIterate(int dir, int start, int len); 
00122       linear_riterator LinearReverseIterate(int*start=0, int*end=0)       { return linear_riterator(this, start, end); } 
00123       linear_riterator Rbegin()                                           { return LinearReverseIterate().Begin(); }     
00124       linear_riterator Rend()                                             { return LinearReverseIterate().End(); }       
00125 
00126       row_iterator RowIterate(int row_d,int subarray_d,int start,int len);
00127       row_iterator RowIterate(int d=0, int* start = 0, int* end=0)        { return row_iterator(d, this, start, end); }  
00128       row_riterator RowReverseIterate(int r_d,int sub_d,int start,int L); 
00129       row_riterator RowReverseIterate(int d=0, int* start=0, int* end=0)  { return row_riterator(d, this, start, end); } 
00130 
00131       idx_op_ret_t operator[](int i);                                     
00132       T& operator[](Vector<int,dims>const &i);                            
00133       ListAssignmentCheckSzRt<T,linear_iterator> operator=(T);            
00134 
00135       T const& GetElement(int* idx) const;                                
00136       T const& GetElement(int i, ...) const;                              
00137       
00138       friend ostream& operator<< <>(ostream& os, const TensorArray&);
00139       void PrintShape() const;                                            
00140 
00141   private:
00142       T* data;
00143       int sz[dims], totalSz;                                              // acutal elements in each dimension and total elements.
00144       int capacity[dims];                                                 // capacity in each dimension.
00145       int n;                                                              // reserved space between eles(rows) for subdivision.
00146       int stride[dims+1];                                                 // stride[i]: ptr_diff between ele[same]..[i]..[Same] and ele[same]..[i+1]..[Same]
00147       idx_itr_t* idx_itr;
00148 
00149   private:
00150       void compute_stride_totalSz();                                      // compute stride.
00151       void allocate()                                                     { delete [] data; data = stride[dims]? new T[stride[dims]] : 0; }
00152       void new_idx_itr()                                                  { delete idx_itr; idx_itr = new idx_itr_t(stride, sz); }
00153 
00154       void reset_after_resize();                                          // change capcaity and reallocate if necessary.
00155       void init_after_resize();                                           // init after only sz set: set cap = sz and allocate.
00156       void init_after_reshape();                                          // init after both sz and cap set.
00157 
00158       void initElements(const TensorArray& rhs);                          // Initialize the maximal common subarray as rhs.
00159       
00160       bool generate_even_idx_in_i_plus_dimension(int i=-1, int* start=0); // For InsertMiddlePoints(). Default call () to generate idx into start.
00161       bool generate_idx_of_boundary_element(int* idx=0, int*s=0,int*e=0); // For extend(). Pass paras to init; default call () to generate idx.
00162       void copy_extend(int* idx, int* start, int* end);                   // Copy-extend ele[idx].
00163       void extend(bool cpy, int* leftright);  
00164   };
00165 
00166 
00167 
00168   // Just for correct compilation.
00169   template<typename T>
00170   class TensorArray<T,0>
00171   {
00172   public:
00173       TensorArray(TensorArray<T,1> const&, int, int) { }
00174       friend  ostream&  operator<< (ostream& os, const TensorArray&) { return os; }
00175   };
00176 
00177   struct IdxRange 
00178   {
00179       IdxRange(int _d, int _s, int _e) : d(_d), s(_s), e(_e) { }
00180       int d, s, e;  // index range: [s, e) along direction d.
00181   };
00182 
00183 
00184 
00185   template<typename T, int dims>
00186   inline TensorArray<T,dims> :: TensorArray() : data(0), n(0), idx_itr(0)
00187   {
00188     bzero(sz, sizeof(int) * dims);
00189     bzero(capacity, sizeof(int) * dims);
00190     compute_stride_totalSz();
00191   }
00192   template<typename T, int dims>
00193   inline TensorArray<T,dims> :: TensorArray(int arg1, ...) : data(0), n(0), idx_itr(0)
00194   {
00195     get_reverse_ints_va(sz, dims);
00196     init_after_resize();
00197   }
00198 
00199   template<typename T, int dims>
00200   inline TensorArray<T,dims> :: TensorArray(int* Sz) : data(0), n(0), idx_itr(0)
00201   {
00202     copy(Sz, Sz+dims, sz);
00203     init_after_resize();
00204   }
00205   template<typename T, int dims>
00206   inline TensorArray<T,dims> :: TensorArray(MyType const& rhs) : data(0), n(0), idx_itr(0)
00207   {
00208     copy(&rhs.sz[0], &rhs.sz[0]+dims, sz);
00209     copy(&rhs.capacity[0], &rhs.capacity[0]+dims, capacity);
00210     init_after_reshape();
00211 
00212     TensorArray& _rhs = (TensorArray&) rhs;
00213     std::copy(_rhs.Begin(), _rhs.End(), Begin());
00214   }
00215 
00216   template<typename T, int dims>
00217   inline TensorArray<T,dims> :: TensorArray(MyType const& rhs, int d, int s, int e) : data(0), n(0), idx_itr(0)
00218   {
00219     copy(&rhs.sz[0], &rhs.sz[0]+dims, sz);
00220     sz[d] = e - s;
00221 
00222     init_after_resize();
00223 
00224     TensorArray& _rhs = (TensorArray&)rhs;
00225     linear_iterator itr = _rhs.LinearIterate(d, s, e);
00226     std::copy(itr.Begin(), itr.End(), Begin());
00227   }
00228   
00229   
00230   template<typename T, int dims>
00231   inline TensorArray<T,dims> :: TensorArray(TensorArray<T,dims+1> const& rhs, int d, int s) : data(0), n(0), idx_itr(0)
00232   {
00233     copy(&rhs.sz[0], &rhs.sz[0]+d, sz);
00234     copy(&rhs.sz[0]+d+1, &rhs.sz[0]+dims+1, sz);
00235 
00236     init_after_resize();
00237 
00238     SuperType& _rhs = (SuperType&)rhs;
00239     typename SuperType::linear_iterator itr = _rhs.LinearIterate(d, s, 1);
00240     std::copy(itr.Begin(), itr.End(), Begin());
00241   }
00242   
00243   
00244   template<typename T, int dims>
00245   inline TensorArray<T,dims> :: TensorArray(MyType const& rhs, int* s, int* e) : data(0), n(0), idx_itr(0)
00246   {
00247     transform(s, s+dims, e, sz, minus<int>());
00248       
00249     init_after_resize();
00250 
00251     TensorArray& _rhs = (TensorArray&)rhs;
00252     linear_iterator itr = _rhs.LinearIterate(s, e);
00253     std::copy(itr.Begin(), itr.End(), Begin());
00254   }
00255   
00256   
00257   template<typename T, int dims>
00258   inline TensorArray<T,dims>& TensorArray<T,dims>::Transform(xchen::Transform const& trans)
00259   {
00260     for(linear_iterator itr = Begin(); itr!=End(); ++itr)
00261     {
00262       *itr = trans(*itr);
00263     }
00264     return *this;
00265   }
00266   
00267 
00268 
00269   template<typename T, int dims>
00270   inline void TensorArray<T,dims> :: Clear()
00271   {
00272     delete [] data; delete idx_itr;
00273 
00274     data = 0; idx_itr = 0; n = 0;
00275     
00276     bzero(sz, sizeof(int) * dims);
00277     bzero(capacity, sizeof(int) * dims);
00278     compute_stride_totalSz();
00279   }
00280 
00281   template<typename T, int dims>
00282   TensorArray<T,dims>& TensorArray<T,dims> :: operator=(const TensorArray& rhs)
00283   {
00284     if(this != &rhs)
00285     {
00286       copy(&rhs.sz[0], &rhs.sz[0]+dims, sz);
00287 
00288       reset_after_resize();
00289       
00290       TensorArray& _rhs = (TensorArray&)rhs;
00291       std::copy(_rhs.Begin(), _rhs.End(), Begin());
00292     }
00293     return *this;
00294   }
00295 
00296 
00297   template<typename T, int dims>
00298   ListAssignmentCheckSzRt<T, typename TensorArray<T,dims> :: linear_iterator> TensorArray<T,dims> ::  operator=(T x)
00299   {
00300     data[0] = x;
00301     return ListAssignmentCheckSzRt<T, linear_iterator>(Begin()+1, totalSz-1);
00302   }
00303 
00304   template<typename T, int dims>
00305   void TensorArray<T,dims> :: initElements(const TensorArray& rhs)
00306   {
00307     if(this != &rhs)
00308     {
00309       int end[dims];
00310       for(int i=0; i<dims; i++)
00311         end[i] = std::min(sz[i], rhs.sz[i]);
00312         
00313       linear_iterator itr1 = ((TensorArray&)rhs).LinearIterate(0, end);
00314       linear_iterator itr2 = LinearIterate(0, end);
00315       std::copy(itr1.Begin(), itr1.End(), itr2.Begin());
00316     }
00317   }
00318 
00319 
00320   template<typename T, int dims>
00321   inline void TensorArray<T,dims> :: Reserve(int arg1, ...)
00322   {
00323     int new_cap[dims];
00324     get_reverse_ints_va(new_cap, dims);
00325     Reserve(new_cap);
00326   }
00327   template<typename T, int dims>
00328   void TensorArray<T,dims> :: Reserve(int* _new_cap)
00329   {
00330     bool need_alloc = false;
00331     int new_cap[dims];
00332     copy(_new_cap, _new_cap+dims, new_cap);
00333     
00334     for(int i=0; i<dims; i++)
00335     {
00336       if(capacity[i] < new_cap[i])
00337         need_alloc = true;
00338       else
00339         new_cap[i] = capacity[i];
00340     }
00341 
00342     if(need_alloc)
00343     {
00344       TensorArray<T,dims> old_ar(*this);
00345 
00346       copy(new_cap, new_cap+dims, capacity);
00347       init_after_reshape();
00348 
00349       copy(old_ar.Begin(), old_ar.End(), Begin());
00350     }
00351   }
00352 
00353   template<typename T, int dims>
00354   inline void TensorArray<T,dims> :: reset_after_resize()
00355   {
00356     for(int i=0; i<dims; i++)
00357       if(capacity[i] < sz[i])
00358         capacity[i] = sz[i];
00359 
00360     int old_total_memsz = stride[dims];
00361     compute_stride_totalSz();
00362     new_idx_itr();
00363 
00364     if( !data || old_total_memsz < stride[dims] )
00365       allocate();
00366   }
00367   template<typename T, int dims>
00368   inline void TensorArray<T,dims> :: init_after_resize()
00369   {
00370     copy(sz, sz+dims, capacity);
00371     compute_stride_totalSz();
00372     new_idx_itr();
00373     allocate();
00374   }
00375   
00376   template<typename T, int dims>
00377   inline void TensorArray<T,dims> :: init_after_reshape()
00378   {
00379     compute_stride_totalSz();
00380     new_idx_itr();
00381     allocate();
00382   }
00383   
00384 
00385   template<typename T, int dims>
00386   inline void TensorArray<T,dims> :: Resize(int arg1, ...)
00387   {
00388     int new_sz[dims];
00389     get_reverse_ints_va(new_sz, dims);
00390     Resize(new_sz);
00391   }
00392   template<typename T, int dims>
00393   void TensorArray<T,dims> :: Resize(int* new_sz)
00394   {
00395     TensorArray<T,dims>* old_ar = data? new TensorArray<T,dims>(*this) : 0;
00396 
00397     copy(new_sz, new_sz+dims, sz);
00398     init_after_resize();
00399     
00400     if(old_ar)
00401     {
00402       initElements(*old_ar);
00403       delete old_ar;
00404     }
00405     
00406   }
00407 
00408   template<typename T, int dims>
00409   void TensorArray<T,dims> :: ResizeOneDirection(int i, int new_sz)
00410   {
00411     if(new_sz == sz[i])
00412       return;
00413     
00414     TensorArray<T,dims>* old_ar = data? new TensorArray<T,dims>(*this) : 0;
00415 
00416     bool need_alloc = false;
00417     int less_sz[dims];
00418     GetSize(less_sz);
00419 
00420     if(new_sz < sz[i]) 
00421       less_sz[i] = new_sz;
00422     else 
00423     {
00424       if(new_sz > capacity[i])
00425       {
00426         capacity[i] = new_sz;
00427         need_alloc = true;
00428       }
00429     }
00430     sz[i] = new_sz;
00431     
00432     compute_stride_totalSz();
00433     new_idx_itr();
00434 
00435     if(need_alloc)
00436       allocate();
00437 
00438     if(old_ar)
00439     {
00440       linear_iterator new_itr = LinearIterate(0, less_sz);
00441       linear_iterator old_itr = old_ar->LinearIterate(0, less_sz);
00442       std::copy(old_itr.Begin(), old_itr.End(), new_itr.Begin());
00443       delete old_ar;
00444     }
00445     
00446   }
00447 
00448   template<typename T, int dims>
00449   void TensorArray<T,dims> :: Insert(linear_iterator itr, T const& val) 
00450   {
00451     T* cpy = new T[totalSz];
00452     T *bgn = cpy, *inst, *end = cpy+totalSz;
00453 
00454     linear_iterator it = Begin();
00455     for(; it != itr; ++it, ++cpy) *cpy = *it;
00456 
00457     inst = cpy;
00458 
00459     for(; it != End(); ++it, ++cpy) *cpy = *it;
00460 
00461     ResizeOneDirection(dims-1, sz[dims-1]+1);
00462     
00463     cpy = bgn;
00464 
00465     for(it = Begin(); bgn != inst; ++bgn, ++it) *it = *bgn;
00466     
00467     *it = val; ++it;
00468     
00469     for(; bgn != end; ++bgn, ++it) *it = *bgn;
00470 
00471     delete [] cpy;
00472   }
00473   
00474 
00475   template<typename T, int dims>
00476   void TensorArray<T,dims> :: Insert(int dir, int before)
00477   {
00478     int len = sz[dir];
00479     TensorArray<T,dims> cpy(*this);
00480     ResizeOneDirection(dir, len+1);
00481     array_copy(dir,before,  cpy,0,  *this,0);
00482     array_copy(dir,len-before,  cpy,before,  *this,before+1);
00483   }
00484   
00485   
00486   template<typename T, int dims>
00487   inline typename TensorArray<T,dims> :: linear_iterator TensorArray<T,dims> :: LinearIterate(int dir, int start_idx, int len)
00488   {
00489     int start[dims], end[dims];
00490     bzero(start, sizeof(int) * dims); GetSize(end);
00491     start[dir] = start_idx, end[dir] = start_idx + len;
00492     return LinearIterate(start, end);
00493   }
00494   template<typename T, int dims>
00495   inline typename TensorArray<T,dims> :: linear_riterator TensorArray<T,dims> :: LinearReverseIterate(int dir, int start_idx, int len)
00496   {
00497     int start[dims], end[dims];
00498     bzero(start, sizeof(int) * dims); GetSize(end);
00499     start[dir] = start_idx, end[dir] = start_idx + len;
00500     return LinearReverseIterate(start, end);
00501   }
00502   template<typename T, int dims>
00503   inline typename TensorArray<T,dims> :: row_iterator TensorArray<T,dims> :: RowIterate(int row_dir, int subarray_dir, int start_idx, int len)
00504   {
00505     int start[dims], end[dims];
00506     bzero(start, sizeof(int) * dims); GetSize(end);
00507     start[subarray_dir] = start_idx, end[subarray_dir] = start_idx + len;
00508     return RowIterate(row_dir, start, end);
00509   }
00510   template<typename T, int dims>
00511   inline typename TensorArray<T,dims> :: row_riterator TensorArray<T,dims> :: RowReverseIterate(int row_dir, int subarray_dir, int start_idx, int len)
00512   {
00513     int start[dims], end[dims];
00514     bzero(start, sizeof(int) * dims); GetSize(end);
00515     start[subarray_dir] = start_idx, end[subarray_dir] = start_idx + len;
00516     return RowReverseIterate(row_dir, start, end);
00517   }
00518   
00519 
00520   template<typename T, int dims>
00521   void TensorArray<T,dims> :: PopFront(int i)
00522   {
00523     TensorArray<T,dims> cpy(*this);
00524     sz[i]--;
00525     compute_stride_totalSz();
00526     new_idx_itr();
00527 
00528     array_copy(i, sz[i], cpy, 1, *this, 0);
00529   }
00530   template<typename T, int dims>
00531   void TensorArray<T,dims> :: PopBack(int i)
00532   {
00533     sz[i]--;
00534     compute_stride_totalSz();
00535     new_idx_itr();
00536   }
00537 
00538   template<typename T, int dims>
00539   inline void TensorArray<T,dims> :: Extend(int arg1, ...)
00540   {
00541     int leftright[2*dims];
00542     get_reverse_ints_va(leftright, 2*dims);
00543     Extend(leftright);
00544   }
00545   template<typename T, int dims>
00546   inline void TensorArray<T,dims> :: Extend(int* rightleft)
00547   {
00548     extend(false, rightleft);
00549   }
00550   template<typename T, int dims>
00551   inline void TensorArray<T,dims> :: CopyExtend(int arg1, ...)
00552   {
00553     int rightleft[2*dims];
00554     get_reverse_ints_va(rightleft, 2*dims);
00555     CopyExtend(rightleft);
00556   }
00557   template<typename T, int dims>
00558   inline void TensorArray<T,dims> :: CopyExtend(int* rightleft)
00559   {
00560     extend(true, rightleft);
00561   }
00562   template<typename T, int dims>
00563   inline void TensorArray<T,dims> :: CopyExtendAtDirection(int i, int left, int right)
00564   {
00565     int rightleft[2*dims];
00566     bzero(rightleft, sizeof(int) * dims * 2);
00567     rightleft[2*i] = right, rightleft[2*i+1] = left;
00568     CopyExtend(rightleft);
00569   }
00570   template<typename T, int dims>
00571   inline void TensorArray<T,dims> :: ExtendAtDirection(int i, int left, int right)
00572   {
00573     int rightleft[2*dims];
00574     bzero(rightleft, sizeof(int) * dims * 2);
00575     rightleft[2*i] = right, rightleft[2*i+1] = left;
00576     Extend(rightleft);
00577   }
00578     
00579 
00580   template<typename T, int dims>
00581   void TensorArray<T,dims> :: extend(bool cpy_extend, int* rightleft)
00582   {
00583     TensorArray<T,dims> cpy(*this);
00584     int newsz[dims];
00585     int start[dims], end[dims];                       // old array as the subarray in the extended array.
00586     copy(sz, sz+dims, newsz);
00587     for(int i=0; i<dims; i++)
00588     {
00589       newsz[i] += rightleft[2*i] + rightleft[2*i+1];
00590       start[i] = rightleft[2*i+1];
00591       end[i] = start[i] + sz[i];
00592     }
00593     Resize(newsz);
00594     linear_riterator itr = LinearReverseIterate(start, end);
00595     copy(cpy.Rbegin(), cpy.Rend(), itr.Begin());
00596 
00597     if(cpy_extend) 
00598     {
00599       int idx[dims];
00600       generate_idx_of_boundary_element(idx, start, end);
00601       do 
00602       {
00603         copy_extend(idx, start, end);
00604       } while( generate_idx_of_boundary_element() );
00605     }
00606   }
00607 
00608   /* iterate all boundary indices */
00609   template<typename T, int dims>
00610   bool TensorArray<T,dims> :: generate_idx_of_boundary_element(int* idx, int* start, int* end)
00611   {
00612     const int at_interior = 0, at_start = 1, at_end = 2;  // where is the index[] value? at_end actually means right before end. 
00613     static int *index, s[dims], e[dims], at[dims], len[dims];
00614     
00615     if(idx && start && end)
00616     {
00617       index = idx;
00618       copy(start, start+dims, s);
00619       copy(end, end+dims, e);
00620       transform(e, e+dims, s, len, minus<int>());
00621 
00622       /* start with all 0s, i.e. all at_interiro except mandatory at_start or at_start at rightest position. */      
00623       for(int i=0; i<dims; i++)
00624       {
00625         if(len[i]>2)
00626         {
00627           at[i] = at_interior; index[i] = s[i] + 1;
00628         }
00629         else
00630         {
00631           at[i] = at_start; index[i] = s[i];      // no at_interior for this position.
00632         }
00633       }
00634       if(find(at, at+dims, at_start) == at+dims)
00635       {
00636         at[0] = at_start;  index[0] = s[0];
00637       }
00638       
00639       return true;
00640     }
00641 
00642     while(1) 
00643     {
00644       int i; 
00645       for(i=0; i<dims; i++)    // iterate all interior points with regarding to the current set of fixed end indices.
00646       {
00647         if(at[i] == at_interior)
00648         {
00649           if(++index[i] < e[i]-1)
00650             return true;
00651           index[i] = s[i] + 1;
00652         }
00653       }
00654       if(i==dims)             // generate next set of fixed end indices.
00655       {
00656         for(i=0; i<dims; i++)
00657         {
00658           if(len[i]==1) continue;
00659           ++at[i];
00660           if(at[i] == at_start)       { index[i] = s[i]; break; }
00661           else if(at[i] == at_end)    { index[i] = e[i]-1; break; }
00662           else  // carry occurs. 
00663             if(len[i]>2)              { at[i] = at_interior; index[i] = s[i] + 1; } 
00664             else                      { at[i] = at_start; index[i] = s[i]; }
00665         }
00666       }
00667       return i!=dims;
00668     }
00669   }
00670 
00671 
00672   
00673   template<typename T, int dims>
00674   void TensorArray<T,dims> :: copy_extend(int* idx, int* start, int* end)
00675   {
00676     int s[dims], e[dims];
00677     copy(idx, idx+dims, s);
00678     transform(idx, idx+dims, e, bind2nd(plus<int>(), 1)); // initialize to-be-extended-subarray as the element itself.
00679 
00680     bool need_ext = false;
00681     for(int i=0; i<dims; i++)
00682     {
00683       if(start[i] && idx[i] == start[i])
00684       {
00685         s[i] = 0; need_ext = true;
00686       }
00687       if(idx[i] == end[i]-1 && end[i] != sz[i])
00688       {
00689         e[i] = sz[i]; need_ext = true;
00690       }
00691     }
00692 
00693     if(need_ext)
00694     {
00695       linear_iterator itr = LinearIterate(s,e);
00696       fill(itr.Begin(), itr.End(), GetElement(idx));
00697     }
00698   }
00699   
00700       
00701     
00702   // improvment ....
00703   template<typename T, int dims>
00704   void TensorArray<T,dims> :: InsertMiddlePoints(bool average)
00705   {
00706     if(!n) SetN(1);
00707 
00708     assert( find(sz, sz+dims, 1) == sz+dims );
00709     
00710     for(int i=0; i<dims; i++)
00711     {
00712       sz[i] = 2*sz[i] - 1;
00713       capacity[i] = 2 * capacity[i];
00714     }
00715     n--;
00716     compute_stride_totalSz();
00717     new_idx_itr();
00718 
00719     if(!average) return;
00720     
00721     int subStart[dims], subEnd[dims];
00722     for(int i=0; i<dims; i++)
00723     {
00724       subStart[i] = 0;
00725       subEnd[i] = sz[i];
00726       generate_even_idx_in_i_plus_dimension(i, subStart);   // initialization.
00727       while(generate_even_idx_in_i_plus_dimension())
00728       {
00729         for(int j=i+1; j<dims; j++)
00730           subEnd[j] = subStart[j] + 1;
00731         
00732         for( row_iterator r_itr = RowIterate(i, subStart, subEnd); !r_itr.PastEnd(); ++r_itr)
00733         {
00734           element_iterator e_itr_left = r_itr.Begin();
00735           element_iterator e_itr_right = r_itr.Begin() + 2;
00736           element_iterator e_itr_middle = r_itr.Begin() + 1;
00737           for(; e_itr_right < r_itr.End(); e_itr_left += 2, e_itr_right += 2, e_itr_middle += 2)
00738           {
00739             *e_itr_middle = (*e_itr_left + *e_itr_right) / 2;
00740           }
00741         }
00742       }
00743     }
00744   }
00745 
00746   template<typename T, int dims>
00747   bool TensorArray<T,dims> :: generate_even_idx_in_i_plus_dimension(int ii, int * subStart)
00748   {
00749     static int i, *sub_start;
00750     static bool first = false;
00751     
00752     if(subStart)
00753     {
00754       i = ii+1;
00755       sub_start = subStart;
00756       for(int j=i; j<dims; j++)
00757         sub_start[j] = j==i? -2 : 0;
00758       first = true;
00759       return true;
00760     }
00761     else if(i >= dims)
00762       return first? (first=false, true) : false;
00763     else
00764     {
00765       for(int j=i; j<dims; j++)
00766       {
00767         if( (sub_start[j] += 2) < sz[j] )
00768           return true;
00769         else
00770           sub_start[j] = 0;
00771       }
00772 
00773       return false;
00774     }
00775   }
00776   
00777         
00778   template<typename T, int dims>
00779   inline void TensorArray<T,dims> :: SetN(int N)  
00780   {
00781     if(n!=N) 
00782     {
00783       TensorArray<T,dims> cpy(*this);
00784       n = N;
00785       compute_stride_totalSz();
00786       allocate();
00787       new_idx_itr();
00788     
00789       std::copy(cpy.Begin(), cpy.End(), Begin());
00790     }
00791   }
00792 
00793   /* Average each hyper cube into its 'lowerleft' corner.*/
00794   template<typename T, int dims>
00795   void TensorArray<T,dims> :: Averaging()
00796   {
00797     int eles_per_cell = int_pow(2, dims);
00798     linear_iterator itr[eles_per_cell];
00799     int start[dims], len[dims], end[dims];           // total eles_per_cell subarrays.
00800 
00801     bzero(start, sizeof(int) * dims);
00802     GetSize(len);
00803     transform(len, len+dims, len, bind2nd(minus<int>(), 1));
00804 
00805     
00806     /*
00807      * Generate indices of each vertex of the first hyper-cube via binaray number representation. 
00808      * The linear iterator for the vertex is generated based on that.
00809      */
00810     for(int i=0; i<eles_per_cell; i++)  
00811     {
00812       for(int j = 0; i && !(start[j] = 1 - start[j]) && j<dims; j++);
00813       transform(start, start+dims, len, end, plus<int>());
00814       itr[i] = LinearIterate(start, end);
00815     }
00816     
00817     /* Average while iterating the corresponding vertices of the sequential hypercubes. */
00818     while( !itr[0].PastEnd() )
00819     {
00820       for(int i=1; i<eles_per_cell; i++)
00821       {
00822         *itr[0] += *itr[i];          
00823       }
00824       *itr[0] /= eles_per_cell;
00825       for(int i=0; i<eles_per_cell; i++)
00826         ++itr[i];
00827     }
00828     GetSize(len);
00829     transform(len, len+dims, len, bind2nd(minus<int>(), 1));
00830     Resize(len);
00831   }
00832   
00833 
00834   
00835 
00836   template<typename T, int dims>
00837   inline void TensorArray<T,dims> :: compute_stride_totalSz()
00838   {
00839     int strd = (1 << n);
00840     stride[0] = strd;
00841     for(int i=1; i<=dims; i++)
00842       stride[i] = stride[i-1] * capacity[i-1]  * strd;
00843     totalSz = sz[0];
00844     for(int i=1; i<dims; i++)
00845       totalSz *= sz[i];
00846   }
00847 
00848 
00849   template<typename T, int dims>
00850   inline T& TensorArray<T,dims> :: operator[](Vector<int,dims>const& idx)
00851   {
00852     T* ptr = data;
00853     for(int i=dims-1; i>=0; i--)
00854     {
00855       ptr += stride[i] * idx[i];
00856     }
00857     return *ptr;
00858   }
00859   
00860 
00861   template<typename T, int dims>
00862   inline typename TensorArrayIndexOperatorTraits<T,dims>::ReturnType TensorArray<T,dims> :: operator[](int i)          
00863   { 
00864     assert(i<sz[dims-1]);
00865     if(dims>1) 
00866     {
00867       idx_itr->setPtr(data); 
00868       return (*idx_itr)[i];
00869     }
00870     return  idx_op_ret_t(data[i]); 
00871   }
00872 
00873   template<typename T, int dims>
00874   T const& TensorArray<T,dims> :: GetElement(int arg1, ...) const
00875   {
00876     int idx[dims];
00877     get_reverse_ints_va(idx, dims);
00878     return GetElement(idx);
00879   }
00880   template<typename T, int dims>
00881   T const& TensorArray<T,dims> :: GetElement(int* idx) const
00882   {
00883     T* ptr = data;
00884     for(int i=0; i<dims; i++)
00885       ptr += idx[i] * stride[i];
00886     return *ptr;
00887   }
00888   
00889 
00890   template<typename T, int dims>
00891   void TensorArray<T,dims> :: PrintShape() const
00892   {
00893     cout << "\nTensorArray of \nSize:\t\t";
00894     for(int i=dims-1; i>=0; i--)  cout << "["<< sz[i] << "]";
00895     cout << "\nCapacity:\t";
00896     for(int i=dims-1; i>=0; i--)  cout << "["<< capacity[i] << "]";
00897     cout << "\nReserve space:\t2^" << n << "-1\n";
00898   }
00899 
00900 
00901   template<typename T, int dims>
00902   ostream&  operator<< (ostream& os, const TensorArray<T, dims>& _ar)
00903   {
00904     TensorArray<T, dims>& ar = (TensorArray<T, dims>&) _ar;
00905     if(dims==1)
00906       std::copy(ar.Begin(), ar.End(), ostream_iterator<T>(os, " "));
00907     else 
00908     {
00909       for(int start = 0; start < ar.GetSize(dims-1); ++start)
00910       {
00911         TensorArray<T, dims-1> sub_array(ar, dims-1, start);
00912         os << sub_array << endl;
00913       }
00914     }
00915     return os ;
00916   }
00917 
00918 
00919 
00921   template<typename T, int dims1, int dims2>
00922   inline void array_copy(int sub_array_at_this_dir, int len, 
00923                          TensorArray<T,dims1>const& from, int from_start, 
00924                          TensorArray<T,dims2>& to, int to_start)
00925   {
00926     int i = sub_array_at_this_dir;
00927     int fromStart[dims1], fromEnd[dims1], toStart[dims2], toEnd[dims2];
00928 
00929     bzero(fromStart, sizeof(int) * dims1);
00930     from.GetSize(fromEnd); 
00931     fromStart[i] = from_start, fromEnd[i] = from_start + len;
00932 
00933     bzero(toStart, sizeof(int) * dims2);
00934     to.GetSize(toEnd); 
00935     toStart[i] = to_start; toEnd[i] = to_start + len;
00936 
00937     typename TensorArray<T,dims1> :: linear_iterator  
00938       from_itr = ( (TensorArray<T,dims1>&)(from) ).LinearIterate(fromStart, fromEnd);
00939     
00940     typename TensorArray<T,dims2> :: linear_iterator  
00941       to_itr = to.LinearIterate(toStart, toEnd);
00942 
00943     copy(from_itr.Begin(), from_itr.End(), to_itr.Begin());
00944   }
00945   
00946 
00947 
00948   template<typename T, int dims>
00949   inline TensorArray<T,dims> operator*(Transform const& trans, TensorArray<T,dims>const& ar)
00950   {
00951     TensorArray<T,dims> ret(ar);
00952     ret.Transform(trans);
00953     return ret;
00954   }
00955   
00956 
00957 
00958 }//end namespace xchen
00959 
00960 
00961 #endif

Generated on Wed Apr 7 21:40:49 2004 by doxygen1.2.18