Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_TwoDArray.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_TWODARRAY_HPP
43 #define TEUCHOS_TWODARRAY_HPP
44 
45 
51 #include "Teuchos_Array.hpp"
52 
53 
54 namespace Teuchos{
55 
67 template<class T>
68 class TwoDArray{
69 public:
73  typedef Ordinal size_type;
74 
77 
86  TwoDArray(size_type numRows, size_type numCols, T value=T()):
87  _numRows(numRows),
88  _numCols(numCols),
89  _data(Array<T>(numCols*numRows, value)),
90  _symmetrical(false)
91  {}
96  _numRows(0),_numCols(0),_data(Array<T>()),_symmetrical(false){}
97 
99  virtual ~TwoDArray(){}
100 
102 
105 
108 
110  inline ArrayView<const T> operator[](size_type i) const;
111 
113  inline size_type getNumRows() const{
114  return _numRows;
115  }
116 
118  inline size_type getNumCols() const{
119  return _numCols;
120  }
121 
123  inline const Array<T>& getDataArray() const{
124  return _data;
125  }
126 
128  inline T& operator()(size_type i, size_type j){
129  return _data[(i*_numCols)+j];
130  }
131 
133  inline const T& operator()(size_type i, size_type j) const{
134  return _data[(i*_numCols)+j];
135  }
136 
138  inline void clear(){
139  _data.clear();
140  _numRows =0;
141  _numCols =0;
142  }
143 
144  inline bool isEmpty(){
145  return _numRows == 0 &&
146  _numCols == 0 &&
147  _data.size() == 0;
148  }
149 
163  inline bool isSymmetrical() const{
164  return _symmetrical;
165  }
166 
182  inline void setSymmetrical(bool symmetrical){
183  _symmetrical = symmetrical;
184  }
185 
187 
190 
202  void resizeRows(size_type numberOfRows);
203 
218  void resizeCols(size_type numberOfCols);
219 
221 
222 
225 
229  static const std::string& getMetaSeperator(){
230  static const std::string metaSeperator = ":";
231  return metaSeperator;
232  }
233 
237  static const std::string& getDimensionsDelimiter(){
238  static const std::string dimensionsDelimiter = "x";
239  return dimensionsDelimiter;
240  }
241 
243  static std::string toString(const TwoDArray<T> array);
244 
246  static TwoDArray<T> fromString(const std::string& string);
247 
249 
250 private:
253  TwoDArray(size_type numRows, size_type numCols, Array<T> data):
254  _numRows(numRows),
255  _numCols(numCols),
256  _data(data),
257  _symmetrical(false)
258  {}
259 
261 };
262 
263 template<class T> inline
265  return _data.view(_numCols*i, _numCols);
266 }
267 
268 template<class T> inline
270  return _data.view(_numCols*i, _numCols);
271 }
272 
273 template<class T>
275  _data.resize(_numCols*numberOfRows);
276  _numRows = numberOfRows;
277 }
278 
279 
280 template<class T>
282  Array<T> newData(numberOfCols*_numRows);
283  size_type colLimit = (numberOfCols < _numCols ? numberOfCols : _numCols);
284  for(size_type i = 0; i<_numRows; i++){
285  for(size_type j = 0; j<colLimit; j++){
286  newData[i*numberOfCols+j] = _data[i*_numCols+j];
287  }
288  }
289  _data = newData;
290  _numCols=numberOfCols;
291 }
292 
293 
294 template<class T>
295 std::string TwoDArray<T>::toString(const TwoDArray<T> array){
296  std::stringstream numColsStream;
297  std::stringstream numRowsStream;
298  numColsStream << array.getNumCols();
299  numRowsStream << array.getNumRows();
300  std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
301  return
302  numRowsStream.str() +
304  numColsStream.str() +
305  metaSeperator +
306  (array.isSymmetrical() ? "sym"+metaSeperator : "") +
307  array.getDataArray().toString();
308 }
309 
310 template<class T>
311 TwoDArray<T> TwoDArray<T>::fromString(const std::string& string_in){
312  std::string curString = string_in;
313  std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
314  size_t curPos = curString.find(metaSeperator);
315  std::string dimString = curString.substr(0, curPos);
316  curString = curString.substr(curPos+1);
317 
318  //process dimensions
319  size_t dimCharPos =
320  dimString.find(TwoDArray<T>::getDimensionsDelimiter());
321  std::istringstream numRowsStream(dimString.substr(0,dimCharPos));
322  std::istringstream numColsStream(dimString.substr(dimCharPos+1));
323  size_t numRows, numCols;
324  numRowsStream >> numRows;
325  numColsStream >> numCols;
326 
327  //determine symetry state
328  bool symmetrical = false;
329  curPos = curString.find(metaSeperator);
330  if(curPos != std::string::npos){
331  symmetrical = true;
332  curString = curString.substr(curPos+1);
333  }
334 
335  //Get actual data
336  Array<T> array = fromStringToArray<T>(curString);
337 
338  TEUCHOS_TEST_FOR_EXCEPTION(array.size() != (typename Array<T>::size_type)(numRows*numCols),
340  "Error: You've specified an TwoDArray as having the dimensions of "
341  << numRows << "x" << numCols << ". This means you should have " <<
342  (numRows*numCols) << " entries specified in your array. However you "
343  "only specified " << array.size() << " entries."
344  )
345 
346  //Construct object to return
347  TwoDArray<T> toReturn(numRows, numCols, array);
348  toReturn.setSymmetrical(symmetrical);
349  return toReturn;
350 }
351 
352 /* \brief .
353  * \relates TwoDArray
354  */
355 template<class T>
356 std::istringstream& operator>> (std::istringstream& in, TwoDArray<T>& array){
357  array = TwoDArray<T>::fromString(in.str());
358  return in;
359 }
360 
361 /* \brief .
362  * \relates TwoDArray
363  */
364 template<class T> inline
365 std::ostream& operator<<(std::ostream& os, const TwoDArray<T>& array){
366  return os << TwoDArray<T>::toString(array);
367 }
368 
369 
370 namespace TwoDDetails {
371 
380 template<typename T>
381 bool symmetricCompare(const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
382  if(a1.getNumRows() != a2.getNumRows() ||
383  a1.getNumRows() != a2.getNumRows())
384  {
385  return false;
386  }
387  else{
388  typedef typename TwoDArray<T>::size_type ST;
389  for(ST i=0;i<a1.getNumRows(); ++i){
390  for(ST j=0;j<a1.getNumCols()-a1.getNumRows()+i; ++j){
391  if(a1(i,j) != a2(i,j)){
392  return false;
393  }
394  }
395  }
396  return true;
397  }
398 }
399 
400 
401 }
402 
403 /* \brief Returns true of the two TwoDArrays have the same contents and
404  * their dimensions are the same.
405  *
406  * \note If the arrays are symmetrical, only the values in the upper half
407  * of the array are compared. For example: in a 4x4 array, only the values
408  * indicated with x's in the figure below would be compared.
409  *
410  * o o o o
411  * x o o o
412  * x x o o
413  * x x x o
414  *
415  * \relates TwoDArray
416  */
417 template<typename T>
418 bool operator==( const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
419  if(a1.isSymmetrical() != a2.isSymmetrical()){
420  return false;
421  }
422  if(a1.isSymmetrical()){
423  return TwoDDetails::symmetricCompare(a1,a2);
424  }
425  else{
426  return a1.getDataArray() == a2.getDataArray() &&
427  a1.getNumRows() == a2.getNumRows() &&
428  a1.getNumCols() == a2.getNumCols();
429  }
430 }
431 
441 inline
443  return "TwoDArray(*)";
444 }
445 
447 template<typename T>
449 public:
450  static std::string name(){
451  std::string formatString = getTwoDArrayTypeNameTraitsFormat();
452  size_t starPos = formatString.find("*");
453  std::string prefix = formatString.substr(0,starPos);
454  std::string postFix = formatString.substr(starPos+1);
455  return prefix+TypeNameTraits<T>::name()+postFix;
456  }
457  static std::string concreteName(const TwoDArray<T>&)
458  { return name(); }
459 };
460 
461 } //namespace Teuchos
462 
463 
464 #endif // TEUCHOS_TWODARRAY_H
TwoDArray(size_type numRows, size_type numCols, Array< T > data)
std::string getTwoDArrayTypeNameTraitsFormat()
Get the format that is used for the specialization of the TypeName traits class for TwoDArray...
const Array< T > & getDataArray() const
Returns the 1D array that is backing this TwoDArray.
void setSymmetrical(bool symmetrical)
Sets whether or not the the TwoDArray should be interpurted as symetric.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
void clear()
delets all the entries from the TwoDArray
static std::string concreteName(const TwoDArray< T > &)
static std::string toString(const TwoDArray< T > array)
Converts a given TwoDArray to a valid string representation.
std::istringstream & operator>>(std::istringstream &in, TwoDArray< T > &array)
A thin wrapper around the Array class which causes it to be interpreted as a 2D Array.
Ordinal size_type
The type of Array sizes and capacities.
#define TEUCHOSCORE_LIB_DLL_EXPORT
std::string toString(const HashSet< Key > &h)
size_type getNumCols() const
returns the number of columns in the TwoDArray.
void resizeCols(size_type numberOfCols)
Changes the number of rows in the matrix.
void resizeRows(size_type numberOfRows)
Changes the number of rows in the matrix.
size_type getNumRows() const
returns the number of rows in the TwoDArray.
Templated array class derived from the STL std::vector.
Nonowning array view.
Default traits class that just returns typeid(T).name().
static const std::string & getMetaSeperator()
returns the string used to seperate meta information from actual data information when converting a T...
static const std::string & getDimensionsDelimiter()
returns the string used as the dimension dilimeter when convering the TwoDArray to a string...
ArrayView< T > operator[](size_type i)
Returns an ArrayView containing the contents of row i.
size_type size() const
TwoDArray()
Constructs an empty TwoDArray.
const T & operator()(size_type i, size_type j) const
Returns the element located at i,j.
TwoDArray(size_type numRows, size_type numCols, T value=T())
Constructs a TwoDArray with the given number of rows and columns with each entry being populated with...
Partial specialization of ArrayView for const T.
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)
static TwoDArray< T > fromString(const std::string &string)
Converts a valid string to it&#39;s corresponding TwoDArray.
bool isSymmetrical() const
A simple flag indicating whether or not this TwoDArray should be interpurted as symmetrical.
bool symmetricCompare(const TwoDArray< T > &a1, const TwoDArray< T > &a2)
A function for comparing symmetrical arrarys.
T & operator()(size_type i, size_type j)
Returns the element located at i,j.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...