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 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TEUCHOS_TWODARRAY_HPP
11 #define TEUCHOS_TWODARRAY_HPP
12 
13 
19 #include "Teuchos_Array.hpp"
20 
21 
22 namespace Teuchos{
23 
35 template<class T>
36 class TwoDArray{
37 public:
41  typedef Ordinal size_type;
42 
45 
54  TwoDArray(size_type numRows, size_type numCols, T value=T()):
55  _numRows(numRows),
56  _numCols(numCols),
57  _data(Array<T>(numCols*numRows, value)),
58  _symmetrical(false)
59  {}
64  _numRows(0),_numCols(0),_data(Array<T>()),_symmetrical(false){}
65 
67  virtual ~TwoDArray(){}
68 
70 
73 
76 
78  inline ArrayView<const T> operator[](size_type i) const;
79 
81  inline size_type getNumRows() const{
82  return _numRows;
83  }
84 
86  inline size_type getNumCols() const{
87  return _numCols;
88  }
89 
91  inline const Array<T>& getDataArray() const{
92  return _data;
93  }
94 
96  inline T& operator()(size_type i, size_type j){
97  return _data[(i*_numCols)+j];
98  }
99 
101  inline const T& operator()(size_type i, size_type j) const{
102  return _data[(i*_numCols)+j];
103  }
104 
106  inline void clear(){
107  _data.clear();
108  _numRows =0;
109  _numCols =0;
110  }
111 
112  inline bool isEmpty(){
113  return _numRows == 0 &&
114  _numCols == 0 &&
115  _data.size() == 0;
116  }
117 
131  inline bool isSymmetrical() const{
132  return _symmetrical;
133  }
134 
150  inline void setSymmetrical(bool symmetrical){
151  _symmetrical = symmetrical;
152  }
153 
155 
158 
170  void resizeRows(size_type numberOfRows);
171 
186  void resizeCols(size_type numberOfCols);
187 
189 
190 
193 
197  static const std::string& getMetaSeperator(){
198  static const std::string metaSeperator = ":";
199  return metaSeperator;
200  }
201 
205  static const std::string& getDimensionsDelimiter(){
206  static const std::string dimensionsDelimiter = "x";
207  return dimensionsDelimiter;
208  }
209 
211  static std::string toString(const TwoDArray<T> array);
212 
214  static TwoDArray<T> fromString(const std::string& string);
215 
217 
218 private:
221  TwoDArray(size_type numRows, size_type numCols, Array<T> data):
222  _numRows(numRows),
223  _numCols(numCols),
224  _data(data),
225  _symmetrical(false)
226  {}
227 
229 };
230 
231 template<class T> inline
233  return _data.view(_numCols*i, _numCols);
234 }
235 
236 template<class T> inline
238  return _data.view(_numCols*i, _numCols);
239 }
240 
241 template<class T>
243  _data.resize(_numCols*numberOfRows);
244  _numRows = numberOfRows;
245 }
246 
247 
248 template<class T>
250  Array<T> newData(numberOfCols*_numRows);
251  size_type colLimit = (numberOfCols < _numCols ? numberOfCols : _numCols);
252  for(size_type i = 0; i<_numRows; i++){
253  for(size_type j = 0; j<colLimit; j++){
254  newData[i*numberOfCols+j] = _data[i*_numCols+j];
255  }
256  }
257  _data = newData;
258  _numCols=numberOfCols;
259 }
260 
261 
262 template<class T>
263 std::string TwoDArray<T>::toString(const TwoDArray<T> array){
264  std::stringstream numColsStream;
265  std::stringstream numRowsStream;
266  numColsStream << array.getNumCols();
267  numRowsStream << array.getNumRows();
268  std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
269  return
270  numRowsStream.str() +
272  numColsStream.str() +
273  metaSeperator +
274  (array.isSymmetrical() ? "sym"+metaSeperator : "") +
275  array.getDataArray().toString();
276 }
277 
278 template<class T>
279 TwoDArray<T> TwoDArray<T>::fromString(const std::string& string_in){
280  std::string curString = string_in;
281  std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
282  size_t curPos = curString.find(metaSeperator);
283  std::string dimString = curString.substr(0, curPos);
284  curString = curString.substr(curPos+1);
285 
286  //process dimensions
287  size_t dimCharPos =
288  dimString.find(TwoDArray<T>::getDimensionsDelimiter());
289  std::istringstream numRowsStream(dimString.substr(0,dimCharPos));
290  std::istringstream numColsStream(dimString.substr(dimCharPos+1));
291  size_t numRows, numCols;
292  numRowsStream >> numRows;
293  numColsStream >> numCols;
294 
295  //determine symetry state
296  bool symmetrical = false;
297  curPos = curString.find(metaSeperator);
298  if(curPos != std::string::npos){
299  symmetrical = true;
300  curString = curString.substr(curPos+1);
301  }
302 
303  //Get actual data
304  Array<T> array = fromStringToArray<T>(curString);
305 
306  TEUCHOS_TEST_FOR_EXCEPTION(array.size() != (typename Array<T>::size_type)(numRows*numCols),
308  "Error: You've specified an TwoDArray as having the dimensions of "
309  << numRows << "x" << numCols << ". This means you should have " <<
310  (numRows*numCols) << " entries specified in your array. However you "
311  "only specified " << array.size() << " entries."
312  )
313 
314  //Construct object to return
315  TwoDArray<T> toReturn(numRows, numCols, array);
316  toReturn.setSymmetrical(symmetrical);
317  return toReturn;
318 }
319 
320 /* \brief .
321  * \relates TwoDArray
322  */
323 template<class T>
324 std::istringstream& operator>> (std::istringstream& in, TwoDArray<T>& array){
325  array = TwoDArray<T>::fromString(in.str());
326  return in;
327 }
328 
329 /* \brief .
330  * \relates TwoDArray
331  */
332 template<class T> inline
333 std::ostream& operator<<(std::ostream& os, const TwoDArray<T>& array){
334  return os << TwoDArray<T>::toString(array);
335 }
336 
337 
338 namespace TwoDDetails {
339 
348 template<typename T>
349 bool symmetricCompare(const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
350  if(a1.getNumRows() != a2.getNumRows() ||
351  a1.getNumRows() != a2.getNumRows())
352  {
353  return false;
354  }
355  else{
356  typedef typename TwoDArray<T>::size_type ST;
357  for(ST i=0;i<a1.getNumRows(); ++i){
358  for(ST j=0;j<a1.getNumCols()-a1.getNumRows()+i; ++j){
359  if(a1(i,j) != a2(i,j)){
360  return false;
361  }
362  }
363  }
364  return true;
365  }
366 }
367 
368 
369 }
370 
371 /* \brief Returns true of the two TwoDArrays have the same contents and
372  * their dimensions are the same.
373  *
374  * \note If the arrays are symmetrical, only the values in the upper half
375  * of the array are compared. For example: in a 4x4 array, only the values
376  * indicated with x's in the figure below would be compared.
377  *
378  * o o o o
379  * x o o o
380  * x x o o
381  * x x x o
382  *
383  * \relates TwoDArray
384  */
385 template<typename T>
386 bool operator==( const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
387  if(a1.isSymmetrical() != a2.isSymmetrical()){
388  return false;
389  }
390  if(a1.isSymmetrical()){
391  return TwoDDetails::symmetricCompare(a1,a2);
392  }
393  else{
394  return a1.getDataArray() == a2.getDataArray() &&
395  a1.getNumRows() == a2.getNumRows() &&
396  a1.getNumCols() == a2.getNumCols();
397  }
398 }
399 
409 inline
411  return "TwoDArray(*)";
412 }
413 
415 template<typename T>
417 public:
418  static std::string name(){
419  std::string formatString = getTwoDArrayTypeNameTraitsFormat();
420  size_t starPos = formatString.find("*");
421  std::string prefix = formatString.substr(0,starPos);
422  std::string postFix = formatString.substr(starPos+1);
423  return prefix+TypeNameTraits<T>::name()+postFix;
424  }
425  static std::string concreteName(const TwoDArray<T>&)
426  { return name(); }
427 };
428 
429 } //namespace Teuchos
430 
431 
432 #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...