|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
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),_numCols(numCols),_data(data){} 00255 bool _symmetrical; 00256 }; 00257 00258 template<class T> inline 00259 ArrayView<T> TwoDArray<T>::operator[](size_type i){ 00260 return _data.view(_numCols*i, _numCols); 00261 } 00262 00263 template<class T> inline 00264 const ArrayView<T> TwoDArray<T>::operator[](size_type i) const{ 00265 return _data.view(_numCols*i, _numCols); 00266 } 00267 00268 template<class T> 00269 void TwoDArray<T>::resizeRows(size_type numberOfRows){ 00270 _data.resize(_numCols*numberOfRows); 00271 _numRows = numberOfRows; 00272 } 00273 00274 00275 template<class T> 00276 void TwoDArray<T>::resizeCols(size_type numberOfCols){ 00277 Array<T> newData(numberOfCols*_numRows); 00278 size_type colLimit = (numberOfCols < _numCols ? numberOfCols : _numCols); 00279 for(size_type i = 0; i<_numRows; i++){ 00280 for(size_type j = 0; j<colLimit; j++){ 00281 newData[i*numberOfCols+j] = _data[i*_numCols+j]; 00282 } 00283 } 00284 _data = newData; 00285 _numCols=numberOfCols; 00286 } 00287 00288 00289 template<class T> 00290 std::string TwoDArray<T>::toString(const TwoDArray<T> array){ 00291 std::stringstream numColsStream; 00292 std::stringstream numRowsStream; 00293 numColsStream << array.getNumCols(); 00294 numRowsStream << array.getNumRows(); 00295 std::string metaSeperator = TwoDArray<T>::getMetaSeperator(); 00296 return 00297 numRowsStream.str() + 00298 TwoDArray<T>::getDimensionsDelimiter() + 00299 numColsStream.str() + 00300 metaSeperator + 00301 (array.isSymmetrical() ? "sym"+metaSeperator : "") + 00302 array.getDataArray().toString(); 00303 } 00304 00305 template<class T> 00306 TwoDArray<T> TwoDArray<T>::fromString(const std::string& string_in){ 00307 std::string curString = string_in; 00308 std::string metaSeperator = TwoDArray<T>::getMetaSeperator(); 00309 size_t curPos = curString.find(metaSeperator); 00310 std::string dimString = curString.substr(0, curPos); 00311 curString = curString.substr(curPos+1); 00312 00313 //process dimensions 00314 size_t dimCharPos = 00315 dimString.find(TwoDArray<T>::getDimensionsDelimiter()); 00316 std::istringstream numRowsStream(dimString.substr(0,dimCharPos)); 00317 std::istringstream numColsStream(dimString.substr(dimCharPos+1)); 00318 size_t numRows, numCols; 00319 numRowsStream >> numRows; 00320 numColsStream >> numCols; 00321 00322 //determine symetry state 00323 bool symmetrical = false; 00324 curPos = curString.find(metaSeperator); 00325 if(curPos != std::string::npos){ 00326 symmetrical = true; 00327 curString = curString.substr(curPos+1); 00328 } 00329 00330 //Get actual data 00331 Array<T> array = fromStringToArray<T>(curString); 00332 00333 TEUCHOS_TEST_FOR_EXCEPTION(array.size() != (typename Array<T>::size_type)(numRows*numCols), 00334 InvalidArrayStringRepresentation, 00335 "Error: You've specified an TwoDArray as having the dimensions of " 00336 << numRows << "x" << numCols << ". This means you should have " << 00337 (numRows*numCols) << " entries specified in your array. However you " 00338 "only specified " << array.size() << " entries." 00339 ) 00340 00341 //Construct object to return 00342 TwoDArray<T> toReturn(numRows, numCols, array); 00343 toReturn.setSymmetrical(symmetrical); 00344 return toReturn; 00345 } 00346 00347 /* \brief . 00348 * \relates TwoDArray 00349 */ 00350 template<class T> 00351 std::istringstream& operator>> (std::istringstream& in, TwoDArray<T>& array){ 00352 array = TwoDArray<T>::fromString(in.str()); 00353 return in; 00354 } 00355 00356 /* \brief . 00357 * \relates TwoDArray 00358 */ 00359 template<class T> inline 00360 std::ostream& operator<<(std::ostream& os, const TwoDArray<T>& array){ 00361 return os << TwoDArray<T>::toString(array); 00362 } 00363 00364 00365 namespace TwoDDetails { 00366 00375 template<typename T> 00376 bool symmetricCompare(const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){ 00377 if(a1.getNumRows() != a2.getNumRows() || 00378 a1.getNumRows() != a2.getNumRows()) 00379 { 00380 return false; 00381 } 00382 else{ 00383 typedef typename TwoDArray<T>::size_type ST; 00384 for(ST i=0;i<a1.getNumRows(); ++i){ 00385 for(ST j=0;j<a1.getNumCols()-a1.getNumRows()+i; ++j){ 00386 if(a1(i,j) != a2(i,j)){ 00387 return false; 00388 } 00389 } 00390 } 00391 return true; 00392 } 00393 } 00394 00395 00396 } 00397 00398 /* \brief Returns true of the two TwoDArrays have the same contents and 00399 * their dimensions are the same. 00400 * 00401 * \note If the arrays are symmetrical, only the values in the upper half 00402 * of the array are compared. For example: in a 4x4 array, only the values 00403 * indicated with x's in the figure below would be compared. 00404 * 00405 * o o o o 00406 * x o o o 00407 * x x o o 00408 * x x x o 00409 * 00410 * \relates TwoDArray 00411 */ 00412 template<typename T> 00413 bool operator==( const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){ 00414 if(a1.isSymmetrical() != a2.isSymmetrical()){ 00415 return false; 00416 } 00417 if(a1.isSymmetrical()){ 00418 return TwoDDetails::symmetricCompare(a1,a2); 00419 } 00420 else{ 00421 return a1.getDataArray() == a2.getDataArray() && 00422 a1.getNumRows() == a2.getNumRows() && 00423 a1.getNumCols() == a2.getNumCols(); 00424 } 00425 } 00426 00436 inline 00437 std::string getTwoDArrayTypeNameTraitsFormat(){ 00438 return "TwoDArray(*)"; 00439 } 00440 00442 template<typename T> 00443 class TEUCHOS_LIB_DLL_EXPORT TypeNameTraits<TwoDArray<T> > { 00444 public: 00445 static std::string name(){ 00446 std::string formatString = getTwoDArrayTypeNameTraitsFormat(); 00447 size_t starPos = formatString.find("*"); 00448 std::string prefix = formatString.substr(0,starPos); 00449 std::string postFix = formatString.substr(starPos+1); 00450 return prefix+TypeNameTraits<T>::name()+postFix; 00451 } 00452 static std::string concreteName(const TwoDArray<T>&) 00453 { return name(); } 00454 }; 00455 00456 } //namespace Teuchos 00457 00458 00459 #endif // TEUCHOS_TWODARRAY_H
1.7.6.1