Blender V2.61 - r43446

region2d.h

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