Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Teuchos_TwoDArray.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) 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 Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_TWODARRAY_HPP
00043 #define TEUCHOS_TWODARRAY_HPP
00044 
00045 
00051 #include "Teuchos_Array.hpp"
00052 
00053 
00054 namespace Teuchos{
00055 
00067 template<class T>
00068 class TwoDArray{
00069 public:
00073   typedef Ordinal size_type;
00074 
00077 
00086   TwoDArray(size_type numRows, size_type numCols, T value=T()):
00087     _numRows(numRows),
00088     _numCols(numCols),
00089     _data(Array<T>(numCols*numRows, value)),
00090     _symmetrical(false)
00091     {}
00095   TwoDArray():
00096     _numRows(0),_numCols(0),_data(Array<T>()),_symmetrical(false){}
00097 
00099   virtual ~TwoDArray(){}
00100 
00102 
00105 
00107   inline ArrayView<T> operator[](size_type i);
00108 
00110   inline const ArrayView<T> operator[](size_type i) const;
00111 
00113   inline size_type getNumRows() const{
00114     return _numRows;
00115   }
00116 
00118   inline size_type getNumCols() const{
00119     return _numCols;
00120   }
00121 
00123   inline const Array<T>& getDataArray() const{
00124     return _data;
00125   }
00126 
00128   inline T& operator()(size_type i, size_type j){
00129     return _data[(i*_numCols)+j];
00130   }
00131 
00133   inline const T& operator()(size_type i, size_type j) const{
00134     return _data[(i*_numCols)+j];
00135   }
00136 
00138   inline void clear(){
00139     _data.clear();
00140     _numRows =0;
00141     _numCols =0;
00142   }
00143 
00144   inline bool isEmpty(){
00145     return _numRows == 0 &&
00146       _numCols == 0 &&
00147       _data.size() == 0;
00148   }
00149 
00163   inline bool isSymmetrical() const{
00164     return _symmetrical;
00165   }
00166 
00182   inline void setSymmetrical(bool symmetrical){
00183     _symmetrical = symmetrical;
00184   }
00185 
00187 
00190 
00202   void resizeRows(size_type numberOfRows);
00203 
00218   void resizeCols(size_type numberOfCols);
00219 
00221 
00222 
00225 
00229   static const std::string& getMetaSeperator(){
00230     static const std::string metaSeperator = ":";
00231     return metaSeperator;
00232   }
00233 
00237   static const std::string& getDimensionsDelimiter(){
00238     static const std::string dimensionsDelimiter = "x";
00239     return dimensionsDelimiter;
00240   }
00241 
00243   static std::string toString(const TwoDArray<T> array);
00244 
00246   static TwoDArray<T> fromString(const std::string& string);
00247 
00249 
00250 private:
00251   size_type _numRows,_numCols;
00252   Array<T> _data;
00253   TwoDArray(size_type numRows, size_type numCols, Array<T> data):
00254     _numRows(numRows),
00255     _numCols(numCols),
00256     _data(data),
00257     _symmetrical(false)
00258   {}
00259 
00260   bool _symmetrical;
00261 };
00262 
00263 template<class T> inline
00264 ArrayView<T> TwoDArray<T>::operator[](size_type i){
00265   return _data.view(_numCols*i, _numCols);
00266 }
00267 
00268 template<class T> inline
00269 const ArrayView<T> TwoDArray<T>::operator[](size_type i) const{
00270   return _data.view(_numCols*i, _numCols);
00271 }
00272 
00273 template<class T>
00274 void TwoDArray<T>::resizeRows(size_type numberOfRows){
00275   _data.resize(_numCols*numberOfRows);
00276   _numRows = numberOfRows;
00277 }
00278 
00279 
00280 template<class T>
00281 void TwoDArray<T>::resizeCols(size_type numberOfCols){
00282   Array<T> newData(numberOfCols*_numRows);
00283   size_type colLimit = (numberOfCols < _numCols ? numberOfCols : _numCols);
00284   for(size_type i = 0; i<_numRows; i++){
00285     for(size_type j = 0; j<colLimit; j++){
00286       newData[i*numberOfCols+j] = _data[i*_numCols+j];
00287     }
00288   }
00289   _data = newData;
00290   _numCols=numberOfCols;
00291 }
00292 
00293 
00294 template<class T>
00295 std::string TwoDArray<T>::toString(const TwoDArray<T> array){
00296   std::stringstream numColsStream;
00297   std::stringstream numRowsStream;
00298   numColsStream << array.getNumCols();
00299   numRowsStream << array.getNumRows();
00300   std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
00301   return
00302     numRowsStream.str() +
00303     TwoDArray<T>::getDimensionsDelimiter() +
00304     numColsStream.str() +
00305     metaSeperator +
00306     (array.isSymmetrical() ? "sym"+metaSeperator : "") +
00307     array.getDataArray().toString();
00308 }
00309 
00310 template<class T>
00311 TwoDArray<T> TwoDArray<T>::fromString(const std::string& string_in){
00312   std::string curString = string_in;
00313   std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
00314   size_t curPos = curString.find(metaSeperator);
00315   std::string dimString = curString.substr(0, curPos);
00316   curString = curString.substr(curPos+1);
00317 
00318   //process dimensions
00319   size_t dimCharPos =
00320     dimString.find(TwoDArray<T>::getDimensionsDelimiter());
00321   std::istringstream numRowsStream(dimString.substr(0,dimCharPos));
00322   std::istringstream numColsStream(dimString.substr(dimCharPos+1));
00323   size_t numRows, numCols;
00324   numRowsStream >> numRows;
00325   numColsStream >> numCols;
00326 
00327   //determine symetry state
00328   bool symmetrical = false;
00329   curPos = curString.find(metaSeperator);
00330   if(curPos != std::string::npos){
00331     symmetrical = true;
00332     curString = curString.substr(curPos+1);
00333   }
00334 
00335   //Get actual data
00336   Array<T> array = fromStringToArray<T>(curString);
00337 
00338   TEUCHOS_TEST_FOR_EXCEPTION(array.size() != (typename Array<T>::size_type)(numRows*numCols),
00339     InvalidArrayStringRepresentation,
00340     "Error: You've specified an TwoDArray as having the dimensions of "
00341     << numRows << "x" << numCols << ". This means you should have " <<
00342     (numRows*numCols) << " entries specified in your array. However you "
00343     "only specified " << array.size() << " entries."
00344   )
00345 
00346   //Construct object to return
00347   TwoDArray<T> toReturn(numRows, numCols, array);
00348   toReturn.setSymmetrical(symmetrical);
00349   return toReturn;
00350 }
00351 
00352 /* \brief .
00353  * \relates TwoDArray
00354  */
00355 template<class T>
00356 std::istringstream& operator>> (std::istringstream& in, TwoDArray<T>& array){
00357   array = TwoDArray<T>::fromString(in.str());
00358   return in;
00359 }
00360 
00361 /* \brief .
00362  * \relates TwoDArray
00363  */
00364 template<class T> inline
00365 std::ostream& operator<<(std::ostream& os, const TwoDArray<T>& array){
00366   return os << TwoDArray<T>::toString(array);
00367 }
00368 
00369 
00370 namespace TwoDDetails {
00371 
00380 template<typename T>
00381 bool symmetricCompare(const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
00382   if(a1.getNumRows() != a2.getNumRows() ||
00383     a1.getNumRows() != a2.getNumRows())
00384   {
00385     return false;
00386   }
00387   else{
00388     typedef typename TwoDArray<T>::size_type ST;
00389     for(ST i=0;i<a1.getNumRows(); ++i){
00390       for(ST j=0;j<a1.getNumCols()-a1.getNumRows()+i; ++j){
00391         if(a1(i,j) != a2(i,j)){
00392           return false;
00393         }
00394       }
00395     }
00396     return true;
00397   }
00398 }
00399 
00400 
00401 }
00402 
00403 /* \brief Returns true of the two TwoDArrays have the same contents and
00404  * their dimensions are the same.
00405  *
00406  * \note If the arrays are symmetrical, only the values in the upper half
00407  * of the array are compared. For example: in a 4x4 array, only the values
00408  * indicated with x's in the figure below would be compared.
00409  *
00410  *   o o o o
00411  *   x o o o
00412  *   x x o o
00413  *   x x x o
00414  *
00415  * \relates TwoDArray
00416  */
00417 template<typename T>
00418 bool operator==( const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
00419   if(a1.isSymmetrical() != a2.isSymmetrical()){
00420     return false;
00421   }
00422   if(a1.isSymmetrical()){
00423     return TwoDDetails::symmetricCompare(a1,a2);
00424   }
00425   else{
00426     return a1.getDataArray() == a2.getDataArray() &&
00427     a1.getNumRows() == a2.getNumRows() &&
00428     a1.getNumCols() == a2.getNumCols();
00429   }
00430 }
00431 
00441 inline
00442 std::string getTwoDArrayTypeNameTraitsFormat(){
00443   return "TwoDArray(*)";
00444 }
00445 
00447 template<typename T>
00448 class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<TwoDArray<T> > {
00449 public:
00450   static std::string name(){
00451     std::string formatString = getTwoDArrayTypeNameTraitsFormat();
00452     size_t starPos = formatString.find("*");
00453     std::string prefix = formatString.substr(0,starPos);
00454     std::string postFix = formatString.substr(starPos+1);
00455     return prefix+TypeNameTraits<T>::name()+postFix;
00456   }
00457   static std::string concreteName(const TwoDArray<T>&)
00458     { return name(); }
00459 };
00460 
00461 } //namespace Teuchos
00462 
00463 
00464 #endif // TEUCHOS_TWODARRAY_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines