Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

region2d.h

00001 // Template Numerical Toolkit (TNT) for Linear Algebra
00002 //
00003 // BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
00004 // Please see http://math.nist.gov/tnt for updates
00005 //
00006 // R. Pozo
00007 // Mathematical and Computational Sciences Division
00008 // National Institute of Standards and Technology
00009 
00010 // 2D Regions for arrays and matrices
00011 
00012 #ifndef REGION2D_H
00013 #define REGION2D_H
00014 
00015 #include "index.h"
00016 
00017 // const_Region2D needs the T parameter -- cannot rely on 
00018 // TNT_Array2D::element_type for definition later. (possible compiler
00019 // g++ bug?)
00020 
00021 template <class TNT_Array2D, class T > class const_Region2D;
00022 
00023 template <class TNT_Array2D /*,  class T */>
00024 class Region2D
00025 {
00026     protected:
00027 
00028         TNT_Array2D &  A_;
00029         Subscript offset_[2];       // 0-offset internally
00030         Subscript dim_[2];
00031 
00032     public:
00033         typedef typename TNT_Array2D::value_type T;
00034         //        typedef TNT_Array2D::value_type T;
00035         typedef Subscript   size_type;
00036         typedef         T   value_type;
00037         typedef         T   element_type;
00038         typedef         T*  pointer;
00039         typedef         T*  iterator;
00040         typedef         T&  reference;
00041         typedef const   T*  const_iterator;
00042         typedef const   T&  const_reference;
00043 
00044         TNT_Array2D & array() { return A_; }
00045         const TNT_Array2D & array()  const { return A_; }
00046         Subscript lbound() const { return A_.lbound(); }
00047         Subscript num_rows() const { return dim_[0]; }
00048         Subscript num_cols() const { return dim_[1]; }
00049         Subscript offset(Subscript i) const                 // 1-offset
00050         {
00051 #ifdef TNT_BOUNDS_CHECK
00052             assert( A_.lbound() <= i);
00053             assert( i<= dim_[0] + A_.lbound()-1);
00054 #endif
00055             return offset_[i-A_.lbound()];
00056         }
00057 
00058         Subscript dim(Subscript i) const
00059         {
00060 #ifdef TNT_BOUNDS_CHECK
00061             assert( A_.lbound() <= i);
00062             assert( i<= dim_[0] + A_.lbound()-1);
00063 #endif
00064             return dim_[i-A_.lbound()];
00065         }
00066 
00067 
00068 
00069         Region2D(TNT_Array2D &A, Subscript i1, Subscript i2, Subscript j1,
00070                 Subscript j2) : A_(A)
00071         {
00072 #ifdef TNT_BOUNDS_CHECK
00073             assert( i1 <= i2 );
00074             assert( j1 <= j2);
00075             assert( A.lbound() <= i1);
00076             assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
00077             assert( A.lbound() <= j1);
00078             assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
00079 #endif
00080 
00081 
00082             offset_[0] = i1-A.lbound();
00083             offset_[1] = j1-A.lbound();
00084             dim_[0] = i2-i1+1;
00085             dim_[1] = j2-j1+1;
00086         }
00087 
00088         Region2D(TNT_Array2D &A, const Index1D &I, const Index1D &J) : A_(A)
00089         {
00090 #ifdef TNT_BOUNDS_CHECK
00091             assert( I.lbound() <= I.ubound() );
00092             assert( J.lbound() <= J.ubound() );
00093             assert( A.lbound() <= I.lbound());
00094             assert( I.ubound()<= A.dim(A.lbound()) + A.lbound()-1);
00095             assert( A.lbound() <= J.lbound());
00096             assert( J.ubound() <= A.dim(A.lbound()+1) + A.lbound()-1 );
00097 #endif
00098 
00099             offset_[0] = I.lbound()-A.lbound();
00100             offset_[1] = J.lbound()-A.lbound();
00101             dim_[0] = I.ubound() - I.lbound() + 1;
00102             dim_[1] = J.ubound() - J.lbound() + 1;
00103         }
00104 
00105         Region2D(Region2D<TNT_Array2D> &A, Subscript i1, Subscript i2,
00106             Subscript j1, Subscript j2) : A_(A.A_)
00107         {
00108 #ifdef TNT_BOUNDS_CHECK
00109             assert( i1 <= i2 );
00110             assert( j1 <= j2);
00111             assert( A.lbound() <= i1);
00112             assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
00113             assert( A.lbound() <= j1);
00114             assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
00115 #endif
00116             offset_[0] = (i1 - A.lbound()) + A.offset_[0];
00117             offset_[1] = (j1 - A.lbound()) + A.offset_[1];
00118             dim_[0] = i2-i1 + 1;
00119             dim_[1] = j2-j1+1;
00120         }
00121 
00122         Region2D<TNT_Array2D> operator()(Subscript i1, Subscript i2,
00123                 Subscript j1, Subscript j2)
00124         {
00125 #ifdef TNT_BOUNDS_CHECK
00126             assert( i1 <= i2 );
00127             assert( j1 <= j2);
00128             assert( A_.lbound() <= i1);
00129             assert( i2<= dim_[0] + A_.lbound()-1);
00130             assert( A_.lbound() <= j1);
00131             assert( j2<= dim_[1] + A_.lbound()-1 );
00132 #endif
00133             return Region2D<TNT_Array2D>(A_, 
00134                     i1+offset_[0], offset_[0] + i2, 
00135                     j1+offset_[1], offset_[1] + j2);
00136         }
00137 
00138 
00139         Region2D<TNT_Array2D> operator()(const Index1D &I,
00140                 const Index1D &J)
00141         {
00142 #ifdef TNT_BOUNDS_CHECK
00143             assert( I.lbound() <= I.ubound() );
00144             assert( J.lbound() <= J.ubound() );
00145             assert( A_.lbound() <= I.lbound());
00146             assert( I.ubound()<= dim_[0] + A_.lbound()-1);
00147             assert( A_.lbound() <= J.lbound());
00148             assert( J.ubound() <= dim_[1] + A_.lbound()-1 );
00149 #endif
00150 
00151             return Region2D<TNT_Array2D>(A_, I.lbound()+offset_[0],
00152                 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
00153                 offset_[1] + J.ubound());
00154         }
00155 
00156         inline T & operator()(Subscript i, Subscript j)
00157         {
00158 #ifdef TNT_BOUNDS_CHECK
00159             assert( A_.lbound() <= i);
00160             assert( i<= dim_[0] + A_.lbound()-1);
00161             assert( A_.lbound() <= j);
00162             assert( j<= dim_[1] + A_.lbound()-1 );
00163 #endif
00164             return A_(i+offset_[0], j+offset_[1]);
00165         }
00166 
00167         inline const T & operator() (Subscript i, Subscript j) const
00168         {
00169 #ifdef TNT_BOUNDS_CHECK
00170             assert( A_.lbound() <= i);
00171             assert( i<= dim_[0] + A_.lbound()-1);
00172             assert( A_.lbound() <= j);
00173             assert( j<= dim_[1] + A_.lbound()-1 );
00174 #endif
00175             return A_(i+offset_[0], j+offset_[1]);
00176         }
00177 
00178 
00179         Region2D<TNT_Array2D> & operator=(const Region2D<TNT_Array2D> &R)
00180         {
00181             Subscript M = num_rows(); 
00182             Subscript N = num_cols();
00183 
00184             // make sure both sides conform
00185             assert(M == R.num_rows());
00186             assert(N == R.num_cols());
00187 
00188 
00189             Subscript start = R.lbound();
00190             Subscript Mend =  start + M - 1;
00191             Subscript Nend =  start + N - 1;
00192             for (Subscript i=start; i<=Mend; i++)
00193               for (Subscript j=start; j<=Nend; j++)
00194                 (*this)(i,j) = R(i,j);
00195 
00196             return *this;
00197         }
00198 
00199         Region2D<TNT_Array2D> & operator=(const const_Region2D<TNT_Array2D,T> &R)
00200         {
00201             Subscript M = num_rows(); 
00202             Subscript N = num_cols();
00203 
00204             // make sure both sides conform
00205             assert(M == R.num_rows());
00206             assert(N == R.num_cols());
00207 
00208 
00209             Subscript start = R.lbound();
00210             Subscript Mend =  start + M - 1;
00211             Subscript Nend =  start + N - 1;
00212             for (Subscript i=start; i<=Mend; i++)
00213               for (Subscript j=start; j<=Nend; j++)
00214                 (*this)(i,j) = R(i,j);
00215 
00216             return *this;
00217         }
00218 
00219         Region2D<TNT_Array2D> & operator=(const TNT_Array2D &R)
00220         {
00221             Subscript M = num_rows(); 
00222             Subscript N = num_cols();
00223 
00224             // make sure both sides conform
00225             assert(M == R.num_rows());
00226             assert(N == R.num_cols());
00227 
00228 
00229             Subscript start = R.lbound();
00230             Subscript Mend =  start + M - 1;
00231             Subscript Nend =  start + N - 1;
00232             for (Subscript i=start; i<=Mend; i++)
00233               for (Subscript j=start; j<=Nend; j++)
00234                 (*this)(i,j) = R(i,j);
00235 
00236             return *this;
00237         }
00238 
00239         Region2D<TNT_Array2D> & operator=(const  T &scalar)
00240         {
00241             Subscript start = lbound();
00242             Subscript Mend = lbound() + num_rows() - 1;
00243             Subscript Nend = lbound() + num_cols() - 1;
00244 
00245 
00246             for (Subscript i=start; i<=Mend; i++)
00247               for (Subscript j=start; j<=Nend; j++)
00248                 (*this)(i,j) = scalar;
00249 
00250             return *this;
00251         }
00252 
00253 };
00254 
00255 //************************
00256 
00257 template <class TNT_Array2D, class T>
00258 class const_Region2D
00259 {
00260     protected:
00261 
00262         const TNT_Array2D &  A_;
00263         Subscript offset_[2];       // 0-offset internally
00264         Subscript dim_[2];
00265 
00266     public:
00267 
00268         typedef         T   value_type;
00269         typedef         T   element_type;
00270         typedef const   T*  const_iterator;
00271         typedef const   T&  const_reference;
00272 
00273         const TNT_Array2D & array() const { return A_; }
00274         Subscript lbound() const { return A_.lbound(); }
00275         Subscript num_rows() const { return dim_[0]; }
00276         Subscript num_cols() const { return dim_[1]; }
00277         Subscript offset(Subscript i) const                 // 1-offset
00278         {
00279 #ifdef TNT_BOUNDS_CHECK
00280             assert( TNT_BASE_OFFSET <= i);
00281             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
00282 #endif
00283             return offset_[i-TNT_BASE_OFFSET];
00284         }
00285 
00286         Subscript dim(Subscript i) const
00287         {
00288 #ifdef TNT_BOUNDS_CHECK
00289             assert( TNT_BASE_OFFSET <= i);
00290             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
00291 #endif
00292             return dim_[i-TNT_BASE_OFFSET];
00293         }
00294 
00295 
00296         const_Region2D(const TNT_Array2D &A, Subscript i1, Subscript i2, 
00297                 Subscript j1, Subscript j2) : A_(A)
00298         {
00299 #ifdef TNT_BOUNDS_CHECK
00300             assert( i1 <= i2 );
00301             assert( j1 <= j2);
00302             assert( TNT_BASE_OFFSET <= i1);
00303             assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
00304             assert( TNT_BASE_OFFSET <= j1);
00305             assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
00306 #endif
00307 
00308             offset_[0] = i1-TNT_BASE_OFFSET;
00309             offset_[1] = j1-TNT_BASE_OFFSET;
00310             dim_[0] = i2-i1+1;
00311             dim_[1] = j2-j1+1;
00312         }
00313 
00314         const_Region2D(const TNT_Array2D &A, const Index1D &I, const Index1D &J) 
00315                 : A_(A)
00316         {
00317 #ifdef TNT_BOUNDS_CHECK
00318             assert( I.lbound() <= I.ubound() );
00319             assert( J.lbound() <= J.ubound() );
00320             assert( TNT_BASE_OFFSET <= I.lbound());
00321             assert( I.ubound()<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
00322             assert( TNT_BASE_OFFSET <= J.lbound());
00323             assert( J.ubound() <= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
00324 #endif
00325 
00326             offset_[0] = I.lbound()-TNT_BASE_OFFSET;
00327             offset_[1] = J.lbound()-TNT_BASE_OFFSET;
00328             dim_[0] = I.ubound() - I.lbound() + 1;
00329             dim_[1] = J.ubound() - J.lbound() + 1;
00330         }
00331 
00332 
00333         const_Region2D(const_Region2D<TNT_Array2D,T> &A, Subscript i1, 
00334                 Subscript i2,
00335             Subscript j1, Subscript j2) : A_(A.A_)
00336         {
00337 #ifdef TNT_BOUNDS_CHECK
00338             assert( i1 <= i2 );
00339             assert( j1 <= j2);
00340             assert( TNT_BASE_OFFSET <= i1);
00341             assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
00342             assert( TNT_BASE_OFFSET <= j1);
00343             assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
00344 #endif
00345             offset_[0] = (i1 - TNT_BASE_OFFSET) + A.offset_[0];
00346             offset_[1] = (j1 - TNT_BASE_OFFSET) + A.offset_[1];
00347             dim_[0] = i2-i1 + 1;
00348             dim_[1] = j2-j1+1;
00349         }
00350 
00351         const_Region2D<TNT_Array2D,T> operator()(Subscript i1, Subscript i2,
00352                 Subscript j1, Subscript j2)
00353         {
00354 #ifdef TNT_BOUNDS_CHECK
00355             assert( i1 <= i2 );
00356             assert( j1 <= j2);
00357             assert( TNT_BASE_OFFSET <= i1);
00358             assert( i2<= dim_[0] + TNT_BASE_OFFSET-1);
00359             assert( TNT_BASE_OFFSET <= j1);
00360             assert( j2<= dim_[0] + TNT_BASE_OFFSET-1 );
00361 #endif
00362             return const_Region2D<TNT_Array2D,T>(A_, 
00363                     i1+offset_[0], offset_[0] + i2, 
00364                     j1+offset_[1], offset_[1] + j2);
00365         }
00366 
00367 
00368         const_Region2D<TNT_Array2D,T> operator()(const Index1D &I,
00369                 const Index1D &J)
00370         {
00371 #ifdef TNT_BOUNDS_CHECK
00372             assert( I.lbound() <= I.ubound() );
00373             assert( J.lbound() <= J.ubound() );
00374             assert( TNT_BASE_OFFSET <= I.lbound());
00375             assert( I.ubound()<= dim_[0] + TNT_BASE_OFFSET-1);
00376             assert( TNT_BASE_OFFSET <= J.lbound());
00377             assert( J.ubound() <= dim_[1] + TNT_BASE_OFFSET-1 );
00378 #endif
00379 
00380             return const_Region2D<TNT_Array2D,T>(A_, I.lbound()+offset_[0],
00381                 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
00382                 offset_[1] + J.ubound());
00383         }
00384 
00385 
00386         inline const T & operator() (Subscript i, Subscript j) const
00387         {
00388 #ifdef TNT_BOUNDS_CHECK
00389             assert( TNT_BASE_OFFSET <= i);
00390             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
00391             assert( TNT_BASE_OFFSET <= j);
00392             assert( j<= dim_[1] + TNT_BASE_OFFSET-1 );
00393 #endif
00394             return A_(i+offset_[0], j+offset_[1]);
00395         }
00396 
00397 };
00398 
00399 
00400 //  ************** ostream algorithms *******************************
00401 
00402 template <class TNT_Array2D,class T>
00403 ostream& operator<<(ostream &s, const const_Region2D<TNT_Array2D,T> &A)
00404 {
00405     Subscript start = A.lbound();
00406     Subscript Mend=A.lbound()+ A.num_rows() - 1;
00407     Subscript Nend=A.lbound() + A.num_cols() - 1;
00408 
00409 
00410     s << A.num_rows() << "  " << A.num_cols() << endl;
00411     for (Subscript i=start; i<=Mend; i++)
00412     {
00413         for (Subscript j=start; j<=Nend; j++)
00414         {
00415             s << A(i,j) << " ";
00416         }
00417         s << endl;
00418     }
00419 
00420 
00421     return s;
00422 }
00423 
00424 template <class TNT_Array2D>
00425 ostream& operator<<(ostream &s, const Region2D<TNT_Array2D> &A)
00426 {
00427     Subscript start = A.lbound();
00428     Subscript Mend=A.lbound()+ A.num_rows() - 1;
00429     Subscript Nend=A.lbound() + A.num_cols() - 1;
00430 
00431 
00432     s << A.num_rows() << "  " << A.num_cols() << endl;
00433     for (Subscript i=start; i<=Mend; i++)
00434     {
00435         for (Subscript j=start; j<=Nend; j++)
00436         {
00437             s << A(i,j) << " ";
00438         }
00439         s << endl;
00440     }
00441 
00442 
00443     return s;
00444 
00445 }
00446 
00447 #endif
00448 // REGION2D_H

Generated on Tue Feb 17 02:03:07 2004 for harlem by doxygen 1.3.6