src/Index/IndexInlines.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef INDEX_INLINES_H
00012 #define INDEX_INLINES_H
00013 
00014 // include files
00015 #include "Utility/Unique.h"
00016 #include "Utility/PAssert.h"
00017 
00019 // Null ctor.
00021 inline 
00022 Index::Index()
00023 : First(0),
00024   Stride(0),
00025   Length(0),
00026   BaseFirst(0),
00027   Base(Unique::get())
00028 {
00029 }
00030 
00032 // Ctor for [0..n-1]
00034 
00035 inline 
00036 Index::Index(unsigned n)
00037 : First(0),
00038   Stride(1),
00039   Length(n),
00040   BaseFirst(0),
00041   Base(Unique::get())
00042 {
00043 }
00044 
00045 
00047 // ctor for range.
00049 inline 
00050 Index::Index(int f, int l)
00051 : First(f),
00052   Stride(1),
00053   Length(l-f+1),
00054   BaseFirst(0),
00055   Base(Unique::get())
00056 {
00057   PAssert(l-f+1>=0);
00058 }
00059 
00060 inline 
00061 Index::Index(int f, int l, int s)
00062 : First(f),
00063   Stride(s),
00064   BaseFirst(0),
00065   Base(Unique::get())
00066 {
00067   PAssert(s!=0);
00068   if ( f==l ) {
00069     Length = 1;
00070   }
00071   else if ( (l>f) ^ (s<0) ) {
00072     Length = (l-f)/s + 1;
00073   }
00074   else {
00075     Length = 0;
00076   }
00077 }
00078 
00080 // Some ctors for internal use.
00082 
00083 inline 
00084 Index::Index(int m, int a, const Index &b)
00085 : First(b.First*m+a),
00086   Stride(b.Stride*m),
00087   Length(b.Length),
00088   BaseFirst( b.BaseFirst ),
00089   Base(b.Base)
00090 {
00091 }
00092 
00093 inline 
00094 Index::Index(int f, int s, const Index *b)
00095 : First(f),
00096   Stride(s),
00097   Length(b->Length),
00098   BaseFirst(b->BaseFirst),
00099   Base(b->Base)
00100 {
00101 }
00102 
00104 //
00105 // Informational functions about Index.
00106 //
00107 // first: return the first index.
00108 // length: return the number of elements.
00109 // stride: the stride between elements.
00110 //
00111 // min: the minimum value.
00112 // max: the maximum value.
00113 //
00115 
00116 inline int  Index::first()  const
00117 {
00118   return First;
00119 }
00120 
00121 inline int  Index::stride() const
00122 {
00123   return Stride;
00124 }
00125 
00126 inline bool Index::empty()  const
00127 {
00128   return Length==0;
00129 }
00130 
00131 inline int  Index::length() const
00132 {
00133   return Length;
00134 }
00135 
00136 inline int Index::last() const
00137 {
00138   return Length==0 ? First : First + Stride*(Length-1);
00139 }
00140 
00141 inline int Index::min() const 
00142 {
00143   return Stride>=0 ? First : First+Stride*(Length-1); 
00144 }
00145 
00146 inline int Index::max() const 
00147 {
00148   return Stride>=0 ? First+Stride*(Length-1) : First; 
00149 }
00150 
00151 inline int Index::getBase() const
00152 {
00153   return Base;
00154 }
00155 
00157 //
00158 // Operations on Index's.
00159 //
00161 
00162 inline Index operator+(const Index& i, int off)
00163 {
00164   return Index(1,off,i);
00165 }
00166 
00167 inline Index operator+(int off, const Index& i)
00168 {
00169   return Index(1,off,i);
00170 }
00171 
00172 inline Index operator-(const Index& i, int off)
00173 {
00174   return Index(1,-off,i);
00175 }
00176 
00177 inline Index operator-(int off, const Index& i)
00178 {
00179   return Index(-1,off,i);
00180 }
00181 
00182 inline Index operator-(const Index& i)
00183 {
00184   return Index(-1,0,i);
00185 }
00186 
00187 inline Index operator*(const Index& i, int m)
00188 {
00189   return Index(m,0,i);
00190 }
00191 
00192 inline Index operator*(int m, const Index& i)
00193 {
00194   return Index(m,0,i);
00195 }
00196 
00197 inline Index operator/(const Index& i, int d)
00198 {
00199   return Index(i.First/d, i.Stride/d, &i);
00200 }
00201 
00203 //
00204 // Comparison operators.
00205 //
00207 
00208 inline bool Index::sameBase(const Index& i) const 
00209 {
00210   return Base == i.Base;
00211 }
00212 
00214 
00215 inline Index Index::plugBase(const Index &a) const
00216 {
00217   Index ret;
00218   ret.BaseFirst = a.BaseFirst;
00219   ret.Length = a.Length;
00220   ret.Stride = Stride;
00221   ret.First = First + Stride*(a.BaseFirst-BaseFirst);
00222   ret.Base = Base;
00223   return ret;
00224 }
00225 
00227 
00228 inline Index Index::reverse() const
00229 {
00230   Index j;
00231   j.First = last();
00232   j.Length = Length;
00233   j.Stride = -Stride;
00234   j.Base = Base;
00235   j.BaseFirst = BaseFirst;  
00236   return j;
00237 }
00238 
00240 
00241 // Test to see if there is any overlap between two Indexes.
00242 inline bool Index::touches(const Index&a) const
00243 {
00244   return (min()<=a.max())&&(max()>=a.min());
00245 }
00246 
00247 // Test to see if one index completely contains another.
00248 inline bool Index::contains(const Index&a) const
00249 {
00250   return (min()<=a.min())&&(max()>=a.max());
00251 }
00252 
00253 inline bool Index::containsAllPoints(const Index &b) const
00254 {
00255   // Find min and max values of type domains
00256   int a0 = min();
00257   int a1 = max();
00258   int  s = stride();
00259   int b0 = b.min();
00260   int b1 = b.max();
00261   int  t = b.stride();
00262   if (s < 0)
00263     s = -s;
00264   if (t < 0)
00265     t = -t;
00266 
00267   // We can do a quick short-circuit check to make sure they do not overlap
00268   // at all just from their endpoints.  If they don't even do this, we can
00269   // quit and say they do not touch.
00270   bool quicktest = (a0 <= b0 && a1 >= b1);
00271   if (!quicktest || s == 1)
00272     return quicktest;
00273 
00274   // OK, the endpoints of a contain those of b, and we must find out if
00275   // all the points in b are found in a.  This will be true if:
00276   //   1. The stride of b is a multipple of the stride of a
00277   //   2. The endpoints of b are found in a
00278   // If either of these conditions are false, a does not contain b 
00279   return (t % s == 0) && ((b0-a0) % s == 0) && ((a1-b1) % s == 0);
00280 }
00281 
00282 
00283 
00284 // Split an index into equal parts
00285 inline bool Index::split(Index& l, Index& r) const
00286 {
00287   PAssert(Stride==1);
00288   PAssert(Length > 1);
00289   //if ( Length <= 1 )
00290   //  return false;
00291   //else
00292   //  {
00293       int first = First;
00294       int length = Length;
00295       int mid = first + length/2 - 1;
00296       l = Index(first, mid);
00297       r = Index(mid+1,first+length-1);
00298       return true;
00299   //  }
00300 }
00301 
00302 // Split an index with the given ratio
00303 inline bool Index::split(Index& l, Index& r, double a) const
00304 {
00305   PAssert(Stride==1);
00306   PAssert(Length > 1);
00307   PAssert((a<1.0)&&(a>0.0));
00308   //if ( Length <= 1 )
00309   //  return false;
00310   //else
00311   //  {
00312       int first = First;
00313       int length = Length;
00314       int mid = first + static_cast<int>(length*a+0.5) - 1;
00315       l = Index(first, mid);
00316       r = Index(mid+1,first+length-1);
00317       return true;
00318   //  }
00319 }
00320 
00322 
00323 #define INDEX_PETE_DOUBLE_OPERATOR(OP,APP)                           \
00324                                                                      \
00325 inline                                                               \
00326 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<double> >        \
00327 OP ( const Index& idx, double x )                                    \
00328 {                                                                    \
00329   typedef                                                            \
00330     PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<double> >    \
00331     Return_t;                                                        \
00332   return Return_t( idx.MakeExpression(), PETE_Scalar<double>(x) );   \
00333 }                                                                    \
00334                                                                      \
00335 inline                                                               \
00336 PETE_TBTree< APP , PETE_Scalar<double> , Index::PETE_Expr_t >        \
00337 OP ( double x , const Index& idx )                                   \
00338 {                                                                    \
00339   typedef                                                            \
00340     PETE_TBTree< APP , PETE_Scalar<double> , Index::PETE_Expr_t >    \
00341     Return_t;                                                        \
00342   return Return_t( PETE_Scalar<double>(x) , idx.MakeExpression());   \
00343 }
00344 
00345 INDEX_PETE_DOUBLE_OPERATOR(operator+,OpAdd)
00346 INDEX_PETE_DOUBLE_OPERATOR(operator-,OpSubtract)
00347 INDEX_PETE_DOUBLE_OPERATOR(operator*,OpMultipply)
00348 INDEX_PETE_DOUBLE_OPERATOR(operator/,OpDivide)
00349 INDEX_PETE_DOUBLE_OPERATOR(operator%,OpMod)
00350 
00351 INDEX_PETE_DOUBLE_OPERATOR(lt,OpLT)
00352 INDEX_PETE_DOUBLE_OPERATOR(le,OpLE)
00353 INDEX_PETE_DOUBLE_OPERATOR(gt,OpGT)
00354 INDEX_PETE_DOUBLE_OPERATOR(ge,OpGE)
00355 INDEX_PETE_DOUBLE_OPERATOR(eq,OpEQ)
00356 INDEX_PETE_DOUBLE_OPERATOR(ne,OpNE)
00357 
00358 INDEX_PETE_DOUBLE_OPERATOR(Max,FnMax)
00359 INDEX_PETE_DOUBLE_OPERATOR(Min,FnMin)
00360 
00361 #undef INDEX_PETE_DOUBLE_OPERATOR
00362 
00364 
00365 #define INDEX_PETE_FLOAT_OPERATOR(OP,APP)                            \
00366                                                                      \
00367 inline                                                               \
00368 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<float> >         \
00369 OP ( const Index& idx, float x )                                     \
00370 {                                                                    \
00371   typedef                                                            \
00372     PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<float> >    \
00373     Return_t;                                                        \
00374   return Return_t( idx.MakeExpression(), PETE_Scalar<float>(x) );   \
00375 }                                                                    \
00376                                                                      \
00377 inline                                                               \
00378 PETE_TBTree< APP , PETE_Scalar<float> , Index::PETE_Expr_t >         \
00379 OP ( float x , const Index& idx )                                    \
00380 {                                                                    \
00381   typedef                                                            \
00382     PETE_TBTree< APP , PETE_Scalar<float> , Index::PETE_Expr_t >    \
00383     Return_t;                                                        \
00384   return Return_t( PETE_Scalar<float>(x) , idx.MakeExpression());   \
00385 }
00386 
00387 INDEX_PETE_FLOAT_OPERATOR(operator+,OpAdd)
00388 INDEX_PETE_FLOAT_OPERATOR(operator-,OpSubtract)
00389 INDEX_PETE_FLOAT_OPERATOR(operator*,OpMultipply)
00390 INDEX_PETE_FLOAT_OPERATOR(operator/,OpDivide)
00391 INDEX_PETE_FLOAT_OPERATOR(operator%,OpMod)
00392 
00393 INDEX_PETE_FLOAT_OPERATOR(lt,OpLT)
00394 INDEX_PETE_FLOAT_OPERATOR(le,OpLE)
00395 INDEX_PETE_FLOAT_OPERATOR(gt,OpGT)
00396 INDEX_PETE_FLOAT_OPERATOR(ge,OpGE)
00397 INDEX_PETE_FLOAT_OPERATOR(eq,OpEQ)
00398 INDEX_PETE_FLOAT_OPERATOR(ne,OpNE)
00399 
00400 INDEX_PETE_FLOAT_OPERATOR(Max,FnMax)
00401 INDEX_PETE_FLOAT_OPERATOR(Min,FnMin)
00402 
00403 #undef INDEX_PETE_FLOAT_OPERATOR
00404 
00406 
00407 #define INDEX_PETE_INT_OPERATOR(OP,APP)                              \
00408                                                                      \
00409 inline                                                               \
00410 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<int> >           \
00411 OP ( const Index& idx, int x )                                       \
00412 {                                                                    \
00413   typedef                                                            \
00414     PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<int> >       \
00415     Return_t;                                                        \
00416   return Return_t( idx.MakeExpression(), PETE_Scalar<int>(x) );      \
00417 }                                                                    \
00418                                                                      \
00419 inline                                                               \
00420 PETE_TBTree< APP , PETE_Scalar<int> , Index::PETE_Expr_t >           \
00421 OP ( int x , const Index& idx )                                      \
00422 {                                                                    \
00423   typedef                                                            \
00424     PETE_TBTree< APP , PETE_Scalar<int> , Index::PETE_Expr_t >       \
00425     Return_t;                                                        \
00426   return Return_t( PETE_Scalar<int>(x) , idx.MakeExpression());      \
00427 }
00428 
00429 INDEX_PETE_INT_OPERATOR(operator%,OpMod)
00430 
00431 INDEX_PETE_INT_OPERATOR(lt,OpLT)
00432 INDEX_PETE_INT_OPERATOR(le,OpLE)
00433 INDEX_PETE_INT_OPERATOR(gt,OpGT)
00434 INDEX_PETE_INT_OPERATOR(ge,OpGE)
00435 INDEX_PETE_INT_OPERATOR(eq,OpEQ)
00436 INDEX_PETE_INT_OPERATOR(ne,OpNE)
00437 
00438 INDEX_PETE_INT_OPERATOR(Max,FnMax)
00439 INDEX_PETE_INT_OPERATOR(Min,FnMin)
00440 
00441 #undef INDEX_PETE_INT_OPERATOR
00442 
00444 
00445 #endif // INDEX_INLINES_H
00446 
00447 /***************************************************************************
00448  * $RCSfile: IndexInlines.h,v $   $Author: adelmann $
00449  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:27 $
00450  * IPPL_VERSION_ID: $Id: IndexInlines.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $ 
00451  ***************************************************************************/

Generated on Mon Jan 16 13:23:48 2006 for IPPL by  doxygen 1.4.6