|
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), 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
1.7.6.1