AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects Version of the Day
AbstractLinAlgPack_GenPermMatrixSliceIterator.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef GEN_PERM_MATRIX_SLICE_ITERATOR_H
00043 #define GEN_PERM_MATRIX_SLICE_ITERATOR_H
00044 
00045 #include <assert.h>
00046 
00047 #include <iterator>
00048 
00049 #include "AbstractLinAlgPack_Types.hpp"
00050 
00051 namespace AbstractLinAlgPack {
00052 
00053 namespace GenPermMatrixSliceIteratorPack {
00054 
00056 enum EOrderedBy { BY_ROW, BY_COL, BY_ROW_AND_COL, UNORDERED };
00057 
00062 template< class T >
00063 class external_row_col_value_type {
00064 public:
00066   typedef T     index_type;
00068   typedef ptrdiff_t difference_type;
00070   external_row_col_value_type(
00071       difference_type row_off
00072     , difference_type col_off
00073     , index_type    row_i
00074     , index_type    col_j
00075     )
00076   :
00077     row_off_(row_off), col_off_(col_off), row_i_(row_i), col_j_(col_j)
00078   {}
00079   difference_type row_off_;
00080   difference_type col_off_;
00081   index_type    row_i_;
00082   index_type    col_j_;
00083 };
00084 
00088 template< class T >
00089 class row_col_value_type {
00090 public:
00092   typedef T     index_type;
00094   typedef ptrdiff_t difference_type;
00096   row_col_value_type( 
00097       difference_type row_off
00098     , difference_type col_off
00099     , index_type    row_i[]
00100     , index_type    col_j[]
00101     , size_type     nz
00102     );
00104   void bind_view( const row_col_value_type<T>& val );
00106   void increment(difference_type);
00108   index_type  row_i() const;
00110   index_type  col_j() const;
00112   index_type* row_i_ptr() const;
00114   row_col_value_type<T>& operator=( const row_col_value_type<T>& val );
00116   operator const external_row_col_value_type<T>() const
00117   {
00118     return external_row_col_value_type<T>(row_off_,col_off_,*row_i_,*col_j_);
00119   }
00121   row_col_value_type<T>& operator=( const external_row_col_value_type<T>& val )
00122   {
00123     TEUCHOS_TEST_FOR_EXCEPT( !(  row_off_ == val.row_off_  ) );
00124     TEUCHOS_TEST_FOR_EXCEPT( !(  col_off_ == val.col_off_  ) );
00125     *row_i_ = val.row_i_;
00126     *col_j_ = val.col_j_;
00127     return *this;
00128   }
00129   
00130 private:
00131   difference_type row_off_;
00132   difference_type col_off_;
00133   index_type    *row_i_;
00134   index_type    *col_j_;
00135   size_type   nz_;
00136   int       k_; // zero based
00138   void assert_in_range() const;
00140   row_col_value_type();
00141 
00142 };  // end class row_col_value_type
00143 
00145 template< class T >
00146 inline
00147 void swap( row_col_value_type<T>& v1, row_col_value_type<T>& v2 )
00148 {
00149   row_col_value_type<T> tmp = v1;
00150   v1 = v2;
00151   v2 = tmp;
00152 }
00153 
00157 template< class T >
00158 class row_col_iterator
00159 #if defined(_WINDOWS) || defined(_INTEL_CXX) || defined(_PG_CXX) 
00160   : public std::iterator< std::random_access_iterator_tag, external_row_col_value_type<T>, ptrdiff_t >
00161 #endif
00162 {
00163 public:
00165   typedef T               index_type;
00167   typedef std::random_access_iterator_tag iterator_category;
00169   typedef external_row_col_value_type<T>  value_type;
00171   typedef row_col_value_type<T>&      reference;
00173   typedef row_col_value_type<T>*      pointer;
00175   typedef ptrdiff_t           difference_type;
00177   row_col_iterator();
00179   row_col_iterator(
00180      difference_type  row_off
00181     ,difference_type  col_off
00182     ,index_type   row_i[]
00183     ,index_type   col_j[]
00184     ,size_type      nz      // Number of elements in row_i[] and col_j[]
00185     );
00187   row_col_iterator<T>& operator=( const row_col_iterator<T>& itr );
00189   reference operator*();
00191   reference operator*() const;
00193   pointer operator->() const;
00195   row_col_iterator<T> operator+(difference_type) const;
00197   row_col_iterator<T> operator-(difference_type);
00199   row_col_iterator<T>&  operator+=(difference_type);
00201   row_col_iterator<T>&  operator-=(difference_type);
00203   row_col_iterator<T>&  operator++();
00205   const row_col_iterator<T> operator++(int);
00207   row_col_iterator<T>&  operator--();
00209   const row_col_iterator<T> operator--(int);
00211   difference_type operator-(const row_col_iterator<T>& itr) const;
00213   bool operator<( const row_col_iterator<T>& itr) const;
00215   bool operator<=( const row_col_iterator<T>& itr) const;
00217   bool operator>( const row_col_iterator<T>& itr) const;
00219   bool operator>=( const row_col_iterator<T>& itr) const;
00221   bool operator==( const row_col_iterator<T>& itr) const;
00223   bool operator!=( const row_col_iterator<T>& itr) const;
00225   bool operator!() const;
00226   
00227 private:
00228   mutable row_col_value_type<T> value_;
00229   
00230 };  // end class row_col_iterator<T>
00231 
00232 // //////////////////////////////////////////////////////////
00233 // Inline members for row_col_value_type<T>
00234 
00235 template<class T>
00236 inline
00237 row_col_value_type<T>::row_col_value_type( 
00238       difference_type row_off
00239     , difference_type col_off
00240     , index_type    row_i[]
00241     , index_type    col_j[]
00242     , size_type     nz
00243     )
00244   :
00245     row_off_(row_off)
00246     ,col_off_(col_off)
00247     ,row_i_(row_i)
00248     ,col_j_(col_j)
00249     ,nz_(nz)
00250     ,k_(0)
00251 {}
00252 
00253 template<class T>
00254 inline
00255 void row_col_value_type<T>::bind_view( const row_col_value_type<T>& val )
00256 {
00257     row_off_  = val.row_off_;
00258     col_off_  = val.col_off_;
00259     row_i_    = val.row_i_;
00260     col_j_    = val.col_j_;
00261     nz_     = val.nz_;
00262     k_      = val.k_;
00263 }
00264 
00265 template< class T >
00266 inline
00267 void row_col_value_type<T>::increment(difference_type d)
00268 {
00269   row_i_  += d;
00270   col_j_  += d;
00271   k_    += d;
00272 }
00273 
00274 template< class T >
00275 inline
00276 typename row_col_value_type<T>::index_type row_col_value_type<T>::row_i() const
00277 {
00278   assert_in_range();
00279   return *row_i_ + row_off_;
00280 }
00281 
00282 template< class T >
00283 inline
00284 typename row_col_value_type<T>::index_type row_col_value_type<T>::col_j() const
00285 {
00286   assert_in_range();
00287   return *col_j_ + col_off_;
00288 }
00289 
00290 template< class T >
00291 inline
00292 typename row_col_value_type<T>::index_type* row_col_value_type<T>::row_i_ptr() const
00293 {
00294   return row_i_;
00295 }
00296 
00297 template< class T >
00298 inline
00299 row_col_value_type<T>& row_col_value_type<T>::operator=(
00300   const row_col_value_type<T>& val )
00301 {
00302   *row_i_ = *val.row_i_;
00303   *col_j_ = *val.col_j_;
00304   return *this;
00305 }
00306 
00307 template< class T >
00308 inline
00309 void row_col_value_type<T>::assert_in_range() const
00310 {
00311   // ToDo: Finish this!
00312   TEUCHOS_TEST_FOR_EXCEPT( !(  0 <= k_ && k_ < nz_  ) );
00313 }
00314 
00316 void GPMS_row_col_iterator_assert_not_null(const void* p);
00317 
00318 // //////////////////////////////////////////////////////////
00319 // Inline members for row_col_iterator<T>
00320 
00321 template< class T >
00322 inline
00323 row_col_iterator<T>::row_col_iterator()
00324   :
00325     value_(0,0,NULL,NULL,0)
00326 {}
00327 
00328 template< class T >
00329 inline
00330 row_col_iterator<T>::row_col_iterator(
00331      difference_type  row_off
00332     ,difference_type  col_off
00333     ,index_type         row_i[]
00334     ,index_type         col_j[]
00335     ,size_type      nz
00336     )
00337   :
00338     value_(row_off,col_off,row_i,col_j,nz)
00339 {}
00340 
00341 template< class T >
00342 inline
00343 row_col_iterator<T>& row_col_iterator<T>::operator=( const row_col_iterator<T>& itr )
00344 {
00345   value_.bind_view( itr.value_ );
00346   return *this;
00347 }
00348 
00349 template< class T >
00350 inline
00351 typename row_col_iterator<T>::reference
00352 row_col_iterator<T>::operator*()
00353 {
00354   GPMS_row_col_iterator_assert_not_null(value_.row_i_ptr());
00355   return value_;
00356 }
00357 
00358 
00359 template< class T >
00360 inline
00361 typename row_col_iterator<T>::reference
00362 row_col_iterator<T>::operator*() const
00363 {
00364   GPMS_row_col_iterator_assert_not_null(value_.row_i_ptr());
00365   return value_;
00366 }
00367 
00368 template< class T >
00369 inline
00370 typename row_col_iterator<T>::pointer
00371 row_col_iterator<T>::operator->() const
00372 {
00373   GPMS_row_col_iterator_assert_not_null(value_.row_i_ptr());
00374   return &value_;
00375 }
00376 
00377 template< class T >
00378 inline
00379 row_col_iterator<T>
00380 row_col_iterator<T>::operator+(difference_type d) const
00381 {
00382   row_col_iterator<T> itr = *this;
00383   itr.value_.increment(d);
00384   return itr;
00385 }
00386 
00387 template< class T >
00388 inline
00389 row_col_iterator<T>
00390 row_col_iterator<T>::operator-(difference_type d)
00391 {
00392   row_col_iterator<T> itr = *this;
00393   itr.value_.increment(-d);
00394   return itr;
00395 }
00396 
00397 template< class T >
00398 inline
00399 row_col_iterator<T>&
00400 row_col_iterator<T>::operator+=(difference_type d)
00401 {
00402   value_.increment(d);
00403   return *this;
00404 }
00405 
00406 template< class T >
00407 inline
00408 row_col_iterator<T>&
00409 row_col_iterator<T>::operator-=(difference_type d)
00410 {
00411   value_.increment(-d);
00412   return *this;
00413 }
00414 
00415 template< class T >
00416 inline
00417 row_col_iterator<T>&
00418 row_col_iterator<T>::operator++()
00419 {
00420   value_.increment(1);
00421   return *this;
00422 }
00423 
00424 template< class T >
00425 inline
00426 const row_col_iterator<T>
00427 row_col_iterator<T>::operator++(int)
00428 {
00429   row_col_iterator<T> itr = *this;
00430   value_.increment(1);
00431   return itr;
00432 }
00433 
00434 template< class T >
00435 inline
00436 row_col_iterator<T>&
00437 row_col_iterator<T>::operator--()
00438 {
00439   value_.increment(-1);
00440   return *this;
00441 }
00442 
00443 template< class T >
00444 inline
00445 const row_col_iterator<T>
00446 row_col_iterator<T>::operator--(int)
00447 {
00448   row_col_iterator<T> itr = *this;
00449   value_.increment(-1);
00450   return itr;
00451 }
00452 
00453 template< class T >
00454 inline
00455 typename row_col_iterator<T>::difference_type
00456 row_col_iterator<T>::operator-(const row_col_iterator<T>& itr) const
00457 {
00458   return value_.row_i_ptr() - itr.value_.row_i_ptr();
00459 }
00460 
00461 template< class T >
00462 inline
00463 bool row_col_iterator<T>::operator<( const row_col_iterator<T>& itr) const
00464 {
00465   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00466       &&  ( value_.row_i_ptr() < itr.value_.row_i_ptr() );
00467 }
00468 
00469 template< class T >
00470 inline
00471 bool row_col_iterator<T>::operator<=( const row_col_iterator<T>& itr) const
00472 {
00473   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00474       &&  ( value_.row_i_ptr() <= itr.value_.row_i_ptr() );
00475 }
00476 
00477 template< class T >
00478 inline
00479 bool row_col_iterator<T>::operator>( const row_col_iterator<T>& itr) const
00480 {
00481   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00482       &&  ( value_.row_i_ptr() > itr.value_.row_i_ptr() );
00483 }
00484 
00485 template< class T >
00486 inline
00487 bool row_col_iterator<T>::operator>=( const row_col_iterator<T>& itr) const
00488 {
00489   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00490       &&  ( value_.row_i_ptr() >= itr.value_.row_i_ptr() );
00491 }
00492 
00493 template< class T >
00494 inline
00495 bool row_col_iterator<T>::operator==( const row_col_iterator<T>& itr) const
00496 {
00497   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00498       &&  ( value_.row_i_ptr() == itr.value_.row_i_ptr() );
00499 }
00500 
00501 template< class T >
00502 inline
00503 bool row_col_iterator<T>::operator!=( const row_col_iterator<T>& itr) const
00504 {
00505   return ( value_.row_i_ptr() && itr.value_.row_i_ptr() )
00506       &&  ( value_.row_i_ptr() != itr.value_.row_i_ptr() );
00507 }
00508 
00509 template< class T >
00510 inline
00511 bool row_col_iterator<T>::operator!() const
00512 {
00513   return  value_.row_i_ptr() == NULL;
00514 }
00515 
00516 } // end namespace GenPermMatrixSliceIteratorPack
00517 
00518 } // end namespace AbstractLinAlgPack
00519 
00520 #endif   // GEN_PERM_MATRIX_SLICE_ITERATOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends