Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
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
18
19#include "Teuchos_Array.hpp"
20#include <limits>
21
22
23namespace Teuchos{
24
36template<class T>
38public:
42 typedef Ordinal size_type;
43
46
55 TwoDArray(size_type numRows, size_type numCols, T value=T()):
56 _numRows(numRows),
57 _numCols(numCols),
58 _data(Array<T>(numCols*numRows, value)),
59 _symmetrical(false)
60 {}
61
65 _numRows(0),_numCols(0),_data(Array<T>()),_symmetrical(false){}
66
68 virtual ~TwoDArray(){}
69
71
74
77
80
82 inline size_type getNumRows() const{
83 return _numRows;
84 }
85
87 inline size_type getNumCols() const{
88 return _numCols;
89 }
90
92 inline const Array<T>& getDataArray() const{
93 return _data;
94 }
95
98 return _data[(i*_numCols)+j];
99 }
100
102 inline const T& operator()(size_type i, size_type j) const{
103 return _data[(i*_numCols)+j];
104 }
105
107 inline void clear(){
108 _data.clear();
109 _numRows =0;
110 _numCols =0;
111 }
112
113 inline bool isEmpty(){
114 return _numRows == 0 &&
115 _numCols == 0 &&
116 _data.size() == 0;
117 }
118
132 inline bool isSymmetrical() const{
133 return _symmetrical;
134 }
135
151 inline void setSymmetrical(bool symmetrical){
152 _symmetrical = symmetrical;
153 }
154
156
159
171 void resizeRows(size_type numberOfRows);
172
187 void resizeCols(size_type numberOfCols);
188
190
191
194
198 static const std::string& getMetaSeperator(){
199 static const std::string metaSeperator = ":";
200 return metaSeperator;
201 }
202
206 static const std::string& getDimensionsDelimiter(){
207 static const std::string dimensionsDelimiter = "x";
208 return dimensionsDelimiter;
209 }
210
212 static std::string toString(const TwoDArray<T> array);
213
215 static TwoDArray<T> fromString(const std::string& string);
216
218
219private:
220 size_type _numRows,_numCols;
221 Array<T> _data;
222 TwoDArray(size_type numRows, size_type numCols, Array<T> data):
223 _numRows(numRows),
224 _numCols(numCols),
225 _data(data),
226 _symmetrical(false)
227 {}
228
229 bool _symmetrical;
230};
231
232template<class T> inline
234 return _data.view(_numCols*i, _numCols);
235}
236
237template<class T> inline
239 return _data.view(_numCols*i, _numCols);
240}
241
242template<class T>
244 _data.resize(_numCols*numberOfRows);
245 _numRows = numberOfRows;
246}
247
248
249template<class T>
251 Array<T> newData(numberOfCols*_numRows);
252 size_type colLimit = (numberOfCols < _numCols ? numberOfCols : _numCols);
253 for(size_type i = 0; i<_numRows; i++){
254 for(size_type j = 0; j<colLimit; j++){
255 newData[i*numberOfCols+j] = _data[i*_numCols+j];
256 }
257 }
258 _data = newData;
259 _numCols=numberOfCols;
260}
261
262
263template<class T>
264std::string TwoDArray<T>::toString(const TwoDArray<T> array){
265 std::stringstream numColsStream;
266 std::stringstream numRowsStream;
267 numColsStream << array.getNumCols();
268 numRowsStream << array.getNumRows();
269 std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
270 return
271 numRowsStream.str() +
273 numColsStream.str() +
274 metaSeperator +
275 (array.isSymmetrical() ? "sym"+metaSeperator : "") +
276 array.getDataArray().toString();
277}
278
279template<class T>
280TwoDArray<T> TwoDArray<T>::fromString(const std::string& string_in){
281 std::string curString = string_in;
282 std::string metaSeperator = TwoDArray<T>::getMetaSeperator();
283 size_t curPos = curString.find(metaSeperator);
284 std::string dimString = curString.substr(0, curPos);
285 curString = curString.substr(curPos+1);
286
287 //process dimensions
288 size_t dimCharPos =
289 dimString.find(TwoDArray<T>::getDimensionsDelimiter());
290 std::istringstream numRowsStream(dimString.substr(0,dimCharPos));
291 std::istringstream numColsStream(dimString.substr(dimCharPos+1));
292 size_t numRows, numCols;
293 numRowsStream >> numRows;
294 numColsStream >> numCols;
295
296 //determine symetry state
297 bool symmetrical = false;
298 curPos = curString.find(metaSeperator);
299 if(curPos != std::string::npos){
300 symmetrical = true;
301 curString = curString.substr(curPos+1);
302 }
303
304 //Get actual data
305 Array<T> array = fromStringToArray<T>(curString);
306
307 // Check for overflow in numRows*numCols
308 const size_t maxSize =
309 static_cast<size_t>(std::numeric_limits<typename Array<T>::size_type>::max());
310 TEUCHOS_TEST_FOR_EXCEPTION(numRows != 0 && numCols > maxSize / numRows,
312 "Error: TwoDArray dimensions " << numRows << "x" << numCols
313 << " exceed the maximum array size of " << maxSize << "."
314 )
315 typename Array<T>::size_type expectedSize = numRows * numCols;
316 TEUCHOS_TEST_FOR_EXCEPTION(array.size() != expectedSize,
318 "Error: You've specified an TwoDArray as having the dimensions of "
319 << numRows << "x" << numCols << ". This means you should have " <<
320 expectedSize << " entries specified in your array. However you "
321 "only specified " << array.size() << " entries."
322 )
323
324 //Construct object to return
325 TwoDArray<T> toReturn(numRows, numCols, array);
326 toReturn.setSymmetrical(symmetrical);
327 return toReturn;
328}
329
330/* \brief .
331 * \relates TwoDArray
332 */
333template<class T>
334std::istringstream& operator>> (std::istringstream& in, TwoDArray<T>& array){
335 array = TwoDArray<T>::fromString(in.str());
336 return in;
337}
338
339/* \brief .
340 * \relates TwoDArray
341 */
342template<class T> inline
343std::ostream& operator<<(std::ostream& os, const TwoDArray<T>& array){
344 return os << TwoDArray<T>::toString(array);
345}
346
347
348namespace TwoDDetails {
349
358template<typename T>
359bool symmetricCompare(const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
360 if(a1.getNumRows() != a2.getNumRows() ||
361 a1.getNumRows() != a2.getNumRows())
362 {
363 return false;
364 }
365 else{
366 typedef typename TwoDArray<T>::size_type ST;
367 for(ST i=0;i<a1.getNumRows(); ++i){
368 for(ST j=0;j<a1.getNumCols()-a1.getNumRows()+i; ++j){
369 if(a1(i,j) != a2(i,j)){
370 return false;
371 }
372 }
373 }
374 return true;
375 }
376}
377
378
379}
380
381/* \brief Returns true of the two TwoDArrays have the same contents and
382 * their dimensions are the same.
383 *
384 * \note If the arrays are symmetrical, only the values in the upper half
385 * of the array are compared. For example: in a 4x4 array, only the values
386 * indicated with x's in the figure below would be compared.
387 *
388 * o o o o
389 * x o o o
390 * x x o o
391 * x x x o
392 *
393 * \relates TwoDArray
394 */
395template<typename T>
396bool operator==( const TwoDArray<T> &a1, const TwoDArray<T> &a2 ){
397 if(a1.isSymmetrical() != a2.isSymmetrical()){
398 return false;
399 }
400 if(a1.isSymmetrical()){
401 return TwoDDetails::symmetricCompare(a1,a2);
402 }
403 else{
404 return a1.getDataArray() == a2.getDataArray() &&
405 a1.getNumRows() == a2.getNumRows() &&
406 a1.getNumCols() == a2.getNumCols();
407 }
408}
409
419inline
421 return "TwoDArray(*)";
422}
423
425template<typename T>
426class TEUCHOSCORE_LIB_DLL_EXPORT TypeNameTraits<TwoDArray<T> > {
427public:
428 static std::string name(){
429 std::string formatString = getTwoDArrayTypeNameTraitsFormat();
430 size_t starPos = formatString.find("*");
431 std::string prefix = formatString.substr(0,starPos);
432 std::string postFix = formatString.substr(starPos+1);
433 return prefix+TypeNameTraits<T>::name()+postFix;
434 }
435 static std::string concreteName(const TwoDArray<T>&)
436 { return name(); }
437};
438
439} //namespace Teuchos
440
441
442#endif // TEUCHOS_TWODARRAY_H
Templated array class derived from the STL std::vector.
bool symmetricCompare(const TwoDArray< T > &a1, const TwoDArray< T > &a2)
A function for comparing symmetrical arrarys.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
size_type size() const
Ordinal size_type
The type of Array sizes and capacities.
Array< T > fromStringToArray(const std::string &arrayStr)
Converts from std::string representation (as created by toString()) back into the array object.
Nonowning array view.
ArrayView< T > view(size_type offset, size_type size) const
Return a view of a contiguous range of elements.
A thin wrapper around the Array class which causes it to be interpreted as a 2D Array.
void resizeRows(size_type numberOfRows)
Changes the number of rows in the matrix.
const T & operator()(size_type i, size_type j) const
Returns the element located at i,j.
size_type getNumCols() const
returns the number of columns in the TwoDArray.
static const std::string & getDimensionsDelimiter()
returns the string used as the dimension dilimeter when convering the TwoDArray to a string.
T & operator()(size_type i, size_type j)
Returns the element located at i,j.
void resizeCols(size_type numberOfCols)
Changes the number of rows in the matrix.
void clear()
delets all the entries from the TwoDArray
size_type getNumRows() const
returns the number of rows in the TwoDArray.
std::string getTwoDArrayTypeNameTraitsFormat()
Get the format that is used for the specialization of the TypeName traits class for TwoDArray.
static const std::string & getMetaSeperator()
returns the string used to seperate meta information from actual data information when converting a T...
TwoDArray()
Constructs an empty TwoDArray.
static TwoDArray< T > fromString(const std::string &string)
Converts a valid string to it's corresponding TwoDArray.
const Array< T > & getDataArray() const
Returns the 1D array that is backing this TwoDArray.
bool isSymmetrical() const
A simple flag indicating whether or not this TwoDArray should be interpurted as symmetrical.
void setSymmetrical(bool symmetrical)
Sets whether or not the the TwoDArray should be interpurted as symetric.
static std::string toString(const TwoDArray< T > array)
Converts a given TwoDArray to a valid string representation.
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...
ArrayView< T > operator[](size_type i)
Returns an ArrayView containing the contents of row i.
Default traits class that just returns typeid(T).name().
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...