Blender  V2.59
region1d.h
Go to the documentation of this file.
00001 
00005 /*
00006 
00007 *
00008 * Template Numerical Toolkit (TNT): Linear Algebra Module
00009 *
00010 * Mathematical and Computational Sciences Division
00011 * National Institute of Technology,
00012 * Gaithersburg, MD USA
00013 *
00014 *
00015 * This software was developed at the National Institute of Standards and
00016 * Technology (NIST) by employees of the Federal Government in the course
00017 * of their official duties. Pursuant to title 17 Section 105 of the
00018 * United States Code, this software is not subject to copyright protection
00019 * and is in the public domain.  The Template Numerical Toolkit (TNT) is
00020 * an experimental system.  NIST assumes no responsibility whatsoever for
00021 * its use by other parties, and makes no guarantees, expressed or implied,
00022 * about its quality, reliability, or any other characteristic.
00023 *
00024 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
00025 * see http://math.nist.gov/tnt for latest updates.
00026 *
00027 */
00028 
00029 
00030 
00031 
00032 #ifndef REGION1D_H
00033 #define REGION1D_H
00034 
00035 
00036 #include "subscript.h"
00037 #include "index.h"
00038 #include <iostream>
00039 #include <cassert>
00040 
00041 namespace TNT
00042 {
00043 
00044 template <class Array1D>
00045 class const_Region1D;
00046 
00047 template <class Array1D>
00048 class Region1D
00049 {
00050     protected:
00051 
00052         Array1D &  A_;
00053         Subscript offset_;          // 0-based
00054         Subscript dim_;
00055 
00056         typedef typename Array1D::element_type T;
00057 
00058     public:
00059         const Array1D & array()  const { return A_; }
00060 
00061         Subscript offset() const { return offset_;}
00062         Subscript dim() const { return dim_; }
00063 
00064         Subscript offset(Subscript i) const
00065         {
00066 #ifdef TNT_BOUNDS_CHECK
00067             assert(i==TNT_BASE_OFFSET);
00068 #endif
00069             return offset_;
00070         }
00071 
00072         Subscript dim(Subscript i) const
00073         {
00074 #ifdef TNT_BOUNDS_CHECK
00075             assert(i== TNT_BASE_OFFSET);
00076 #endif
00077             return offset_;
00078         }
00079 
00080 
00081         Region1D(Array1D &A, Subscript i1, Subscript i2) : A_(A)
00082         {
00083 #ifdef TNT_BOUNDS_CHECK
00084             assert(TNT_BASE_OFFSET <= i1 );
00085             assert(i2 <= A.dim() + (TNT_BASE_OFFSET-1));
00086             assert(i1 <= i2);
00087 #endif
00088             offset_ = i1 - TNT_BASE_OFFSET;
00089             dim_ = i2-i1 + 1;
00090         }
00091 
00092         Region1D(Array1D &A, const Index1D &I) : A_(A)
00093         {
00094 #ifdef TNT_BOUNDS_CHECK
00095             assert(TNT_BASE_OFFSET <=I.lbound());
00096             assert(I.ubound() <= A.dim() + (TNT_BASE_OFFSET-1));
00097             assert(I.lbound() <= I.ubound());
00098 #endif
00099             offset_ = I.lbound() - TNT_BASE_OFFSET;
00100             dim_ = I.ubound() - I.lbound() + 1;
00101         }
00102 
00103         Region1D(Region1D<Array1D> &A, Subscript i1, Subscript i2) :
00104                 A_(A.A_)
00105         {
00106 #ifdef TNT_BOUNDS_CHECK
00107             assert(TNT_BASE_OFFSET <= i1 );
00108             assert(i2 <= A.dim() + (TNT_BASE_OFFSET - 1));
00109             assert(i1 <= i2);
00110 #endif
00111                     //     (old-offset)        (new-offset)
00112                     //
00113             offset_ =  (i1 - TNT_BASE_OFFSET) + A.offset_;
00114             dim_ = i2-i1 + 1;
00115         }
00116 
00117         Region1D<Array1D> operator()(Subscript i1, Subscript i2)
00118         {
00119 #ifdef TNT_BOUNDS_CHECK
00120             assert(TNT_BASE_OFFSET <= i1);
00121             assert(i2 <= dim() + (TNT_BASE_OFFSET -1));
00122             assert(i1 <= i2);
00123 #endif
00124                     // offset_ is 0-based, so no need for
00125                     //  ( - TNT_BASE_OFFSET)
00126                     //
00127             return Region1D<Array1D>(A_, i1+offset_,
00128                     offset_ + i2);
00129         }
00130 
00131 
00132         Region1D<Array1D> operator()(const Index1D &I)
00133         {
00134 #ifdef TNT_BOUNDS_CHECK
00135             assert(TNT_BASE_OFFSET<=I.lbound());
00136             assert(I.ubound() <= dim() + (TNT_BASE_OFFSET-1));
00137             assert(I.lbound() <= I.ubound());
00138 #endif
00139             return Region1D<Array1D>(A_, I.lbound()+offset_,
00140                 offset_ + I.ubound());
00141         }
00142 
00143 
00144 
00145 
00146         T & operator()(Subscript i)
00147         {
00148 #ifdef TNT_BOUNDS_CHECK
00149             assert(TNT_BASE_OFFSET <= i);
00150             assert(i <=  dim() + (TNT_BASE_OFFSET-1));
00151 #endif
00152             return A_(i+offset_);
00153         }
00154 
00155         const T & operator() (Subscript i) const
00156         {
00157 #ifdef TNT_BOUNDS_CHECK
00158             assert(TNT_BASE_OFFSET <= i);
00159             assert(i <= dim() + (TNT_BASE_OFFSET-1));
00160 #endif
00161             return A_(i+offset_);
00162         }
00163 
00164 
00165         Region1D<Array1D> & operator=(const Region1D<Array1D> &R)
00166         {
00167             // make sure both sides conform
00168             assert(dim() == R.dim());
00169 
00170             Subscript N = dim();
00171             Subscript i;
00172             Subscript istart = TNT_BASE_OFFSET;
00173             Subscript iend = istart + N-1;
00174 
00175             for (i=istart; i<=iend; i++)
00176                 (*this)(i) = R(i);
00177 
00178             return *this;
00179         }
00180 
00181 
00182 
00183         Region1D<Array1D> & operator=(const const_Region1D<Array1D> &R)
00184         {
00185             // make sure both sides conform
00186             assert(dim() == R.dim());
00187 
00188             Subscript N = dim();
00189             Subscript i;
00190             Subscript istart = TNT_BASE_OFFSET;
00191             Subscript iend = istart + N-1;
00192 
00193             for (i=istart; i<=iend; i++)
00194                 (*this)(i) = R(i);
00195 
00196             return *this;
00197 
00198         }
00199 
00200 
00201         Region1D<Array1D> & operator=(const T& t)
00202         {
00203             Subscript N=dim();
00204             Subscript i;
00205             Subscript istart = TNT_BASE_OFFSET;
00206             Subscript iend = istart + N-1;
00207 
00208             for (i=istart; i<= iend; i++)
00209                 (*this)(i) = t;
00210 
00211             return *this;
00212 
00213         }
00214 
00215 
00216         Region1D<Array1D> & operator=(const Array1D &R)
00217         {
00218             // make sure both sides conform
00219             Subscript N = dim();
00220             assert(dim() == R.dim());
00221 
00222             Subscript i;
00223             Subscript istart = TNT_BASE_OFFSET;
00224             Subscript iend = istart + N-1;
00225 
00226             for (i=istart; i<=iend; i++)
00227                 (*this)(i) = R(i);
00228 
00229             return *this;
00230 
00231         }
00232 
00233 };
00234 
00235 template <class Array1D>
00236 std::ostream& operator<<(std::ostream &s, Region1D<Array1D> &A)
00237 {
00238     Subscript N=A.dim();
00239     Subscript istart = TNT_BASE_OFFSET;
00240     Subscript iend = N - 1 + TNT_BASE_OFFSET;
00241 
00242     for (Subscript i=istart; i<=iend; i++)
00243         s << A(i) << endl;
00244 
00245     return s;
00246 }
00247 
00248 
00249 /*  ---------  class const_Region1D ------------ */
00250 
00251 template <class Array1D>
00252 class const_Region1D
00253 {
00254     protected:
00255 
00256         const Array1D &  A_;
00257         Subscript offset_;          // 0-based
00258         Subscript dim_;
00259        typedef typename Array1D::element_type T;
00260 
00261     public:
00262         const Array1D & array()  const { return A_; }
00263 
00264         Subscript offset() const { return offset_;}
00265         Subscript dim() const { return dim_; }
00266 
00267         Subscript offset(Subscript i) const
00268         {
00269 #ifdef TNT_BOUNDS_CHECK
00270             assert(i==TNT_BASE_OFFSET);
00271 #endif
00272             return offset_;
00273         }
00274 
00275         Subscript dim(Subscript i) const
00276         {
00277 #ifdef TNT_BOUNDS_CHECK
00278             assert(i== TNT_BASE_OFFSET);
00279 #endif
00280             return offset_;
00281         }
00282 
00283 
00284         const_Region1D(const Array1D &A, Subscript i1, Subscript i2) : A_(A)
00285         {
00286 #ifdef TNT_BOUNDS_CHECK
00287             assert(TNT_BASE_OFFSET <= i1 );
00288             assert(i2 <= A.dim() + (TNT_BASE_OFFSET-1));
00289             assert(i1 <= i2);
00290 #endif
00291             offset_ = i1 - TNT_BASE_OFFSET;
00292             dim_ = i2-i1 + 1;
00293         }
00294 
00295         const_Region1D(const Array1D &A, const Index1D &I) : A_(A)
00296         {
00297 #ifdef TNT_BOUNDS_CHECK
00298             assert(TNT_BASE_OFFSET <=I.lbound());
00299             assert(I.ubound() <= A.dim() + (TNT_BASE_OFFSET-1));
00300             assert(I.lbound() <= I.ubound());
00301 #endif
00302             offset_ = I.lbound() - TNT_BASE_OFFSET;
00303             dim_ = I.ubound() - I.lbound() + 1;
00304         }
00305 
00306         const_Region1D(const_Region1D<Array1D> &A, Subscript i1, Subscript i2) :
00307                 A_(A.A_)
00308         {
00309 #ifdef TNT_BOUNDS_CHECK
00310             assert(TNT_BASE_OFFSET <= i1 );
00311             assert(i2 <= A.dim() + (TNT_BASE_OFFSET - 1));
00312             assert(i1 <= i2);
00313 #endif
00314                     //     (old-offset)        (new-offset)
00315                     //
00316             offset_ =  (i1 - TNT_BASE_OFFSET) + A.offset_;
00317             dim_ = i2-i1 + 1;
00318         }
00319 
00320         const_Region1D<Array1D> operator()(Subscript i1, Subscript i2)
00321         {
00322 #ifdef TNT_BOUNDS_CHECK
00323             assert(TNT_BASE_OFFSET <= i1);
00324             assert(i2 <= dim() + (TNT_BASE_OFFSET -1));
00325             assert(i1 <= i2);
00326 #endif
00327                     // offset_ is 0-based, so no need for
00328                     //  ( - TNT_BASE_OFFSET)
00329                     //
00330             return const_Region1D<Array1D>(A_, i1+offset_,
00331                     offset_ + i2);
00332         }
00333 
00334 
00335         const_Region1D<Array1D> operator()(const Index1D &I)
00336         {
00337 #ifdef TNT_BOUNDS_CHECK
00338             assert(TNT_BASE_OFFSET<=I.lbound());
00339             assert(I.ubound() <= dim() + (TNT_BASE_OFFSET-1));
00340             assert(I.lbound() <= I.ubound());
00341 #endif
00342             return const_Region1D<Array1D>(A_, I.lbound()+offset_,
00343                 offset_ + I.ubound());
00344         }
00345 
00346 
00347         const T & operator() (Subscript i) const
00348         {
00349 #ifdef TNT_BOUNDS_CHECK
00350             assert(TNT_BASE_OFFSET <= i);
00351             assert(i <= dim() + (TNT_BASE_OFFSET-1));
00352 #endif
00353             return A_(i+offset_);
00354         }
00355 
00356 
00357 
00358 
00359 };
00360 
00361 template <class Array1D>
00362 std::ostream& operator<<(std::ostream &s, const_Region1D<Array1D> &A)
00363 {
00364     Subscript N=A.dim();
00365 
00366     for (Subscript i=1; i<=N; i++)
00367         s << A(i) << endl;
00368 
00369     return s;
00370 }
00371 
00372 
00373 } // namespace TNT
00374 
00375 #endif // const_Region1D_H
00376