10 #ifndef __Teuchos_MatrixMarket_Raw_Adder_hpp
11 #define __Teuchos_MatrixMarket_Raw_Adder_hpp
14 #include "Teuchos_ArrayRCP.hpp"
15 #include "Teuchos_CommHelpers.hpp"
17 #include "Teuchos_MatrixMarket_Banner.hpp"
18 #include "Teuchos_MatrixMarket_CoordDataReader.hpp"
29 namespace MatrixMarket {
54 template<
class Scalar,
class Ordinal>
65 Element (
const Ordinal i,
const Ordinal j,
const Scalar& Aij) :
66 rowIndex_ (i), colIndex_ (j), value_ (Aij) {}
70 return rowIndex_ == rhs.rowIndex_ && colIndex_ == rhs.colIndex_;
75 return ! (*
this == rhs);
80 if (rowIndex_ < rhs.rowIndex_)
82 else if (rowIndex_ > rhs.rowIndex_)
85 return colIndex_ < rhs.colIndex_;
94 template<
class BinaryFunction>
98 std::invalid_argument,
99 "Attempt to merge elements at different locations in the sparse "
100 "matrix. The current element is at (" <<
rowIndex() <<
", "
101 <<
colIndex() <<
") and the element you asked me to merge with it "
103 "probably indicates a bug in the sparse matrix reader.");
105 value_ = f (rhs.value_, value_);
117 std::invalid_argument,
118 "Attempt to merge elements at different locations in the sparse "
119 "matrix. The current element is at (" <<
rowIndex() <<
", "
120 <<
colIndex() <<
") and the element you asked me to merge with it "
122 "probably indicates a bug in the sparse matrix reader.");
128 value_ += rhs.value_;
139 Scalar
value()
const {
return value_; }
142 Ordinal rowIndex_, colIndex_;
156 template<
class Scalar,
class Ordinal>
158 operator<< (std::ostream& out, const Element<Scalar, Ordinal>& elt)
161 std::ios::fmtflags f( out.flags() );
178 if (! STS::isOrdinal) {
183 out << std::scientific;
186 out << std::setbase (10);
192 const double numDigitsAsDouble =
195 const int numDigits =
static_cast<int> (numDigitsAsDouble + 0.5);
200 out << std::setprecision (numDigits + 1);
202 out << elt.rowIndex () <<
" " << elt.colIndex () <<
" ";
203 if (STS::isComplex) {
204 out << STS::real (elt.value ()) <<
" " << STS::imag (elt.value ());
250 template<
class Scalar,
class Ordinal>
253 typedef Ordinal index_type;
254 typedef Scalar value_type;
256 typedef typename std::vector<element_type>::size_type size_type;
271 expectedNumEntries_(0),
296 Adder (
const Ordinal expectedNumRows,
297 const Ordinal expectedNumCols,
298 const Ordinal expectedNumEntries,
299 const bool tolerant=
false,
300 const bool debug=
false) :
301 expectedNumRows_(expectedNumRows),
302 expectedNumCols_(expectedNumCols),
303 expectedNumEntries_(expectedNumEntries),
307 tolerant_ (tolerant),
335 const bool countAgainstTotal=
true)
338 const bool indexPairOutOfRange = i < 1 || j < 1 ||
339 i > expectedNumRows_ || j > expectedNumCols_;
342 std::invalid_argument,
"Matrix is " << expectedNumRows_ <<
" x "
343 << expectedNumCols_ <<
", so entry A(" << i <<
"," << j <<
") = "
344 << Aij <<
" is out of range.");
345 if (countAgainstTotal) {
347 std::invalid_argument,
"Cannot add entry A(" << i <<
"," << j
348 <<
") = " << Aij <<
" to matrix; already have expected number "
349 "of entries " << expectedNumEntries_ <<
".");
360 seenNumRows_ = std::max (seenNumRows_, i);
361 seenNumCols_ = std::max (seenNumCols_, j);
362 if (countAgainstTotal) {
377 print (std::ostream& out,
const bool doMerge,
const bool replace=
false)
382 std::sort (elts_.begin(), elts_.end());
385 typedef std::ostream_iterator<element_type> iter_type;
386 std::copy (elts_.begin(), elts_.end(), iter_type (out,
"\n"));
411 std::pair<size_type, size_type>
414 typedef typename std::vector<element_type>::iterator iter_type;
423 std::sort (elts_.begin(), elts_.end());
430 size_type numUnique = 0;
431 iter_type cur = elts_.begin();
432 if (cur == elts_.end()) {
433 return std::make_pair (numUnique, size_type (0));
436 iter_type next = cur;
439 while (next != elts_.end()) {
442 cur->merge (*next, replace);
454 const size_type numRemoved = elts_.size() - numUnique;
455 elts_.resize (numUnique);
456 return std::make_pair (numUnique, numRemoved);
504 size_type& numRemovedElts,
508 const bool replace=
false)
513 std::pair<size_type, size_type> mergeResult =
merge (replace);
521 const Ordinal nrows = tolerant_ ? seenNumRows_ : expectedNumRows_;
530 typedef typename std::vector<element_type>::const_iterator iter_type;
532 for (iter_type it = elts_.begin(); it != elts_.end(); ++it) {
533 const Ordinal i = it->rowIndex ();
534 const Ordinal j = it->colIndex ();
535 const Scalar Aij = it->value ();
538 "current matrix entry's row index " << i <<
" is less then what "
539 "should be the current row index lower bound " << curRow <<
".");
540 for (Ordinal k = curRow+1; k <= i; ++k) {
546 static_cast<size_t> (curInd) >= elts_.size (),
547 std::logic_error,
"The current index " << curInd <<
" into ind "
548 "and val is >= the number of matrix entries " << elts_.size ()
554 for (Ordinal k = curRow+1; k <= nrows; ++k) {
564 numUniqueElts = mergeResult.first;
565 numRemovedElts = mergeResult.second;
584 const Ordinal
numRows()
const {
return seenNumRows_; }
589 const Ordinal
numCols()
const {
return seenNumCols_; }
598 Ordinal expectedNumRows_, expectedNumCols_, expectedNumEntries_;
599 Ordinal seenNumRows_, seenNumCols_, seenNumEntries_;
604 std::vector<element_type> elts_;
610 #endif // #ifndef __Teuchos_MatrixMarket_Raw_Adder_hpp
std::pair< size_type, size_type > merge(const bool replace=false)
Merge duplicate elements.
const std::vector< element_type > & getEntries() const
A temporary const view of the entries of the matrix.
bool operator<(const Element &rhs) const
Lexicographic order first by row index, then by column index.
Element(const Ordinal i, const Ordinal j, const Scalar &Aij)
Create a sparse matrix entry at (i,j) with value Aij.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Scalar value() const
Value (A(rowIndex(), colIndex()) of this Element.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
void clear()
Clear all the added matrix entries and reset metadata.
void mergeAndConvertToCSR(size_type &numUniqueElts, size_type &numRemovedElts, Teuchos::ArrayRCP< Ordinal > &rowptr, Teuchos::ArrayRCP< Ordinal > &colind, Teuchos::ArrayRCP< Scalar > &values, const bool replace=false)
Merge duplicate elements and convert to zero-based CSR.
Element()
Default constructor: an invalid entry of the matrix.
This structure defines some basic traits for a scalar field type.
Templated Parameter List class.
Ordinal rowIndex() const
Row index (zero-based) of this Element.
bool operator==(const Element &rhs) const
Ignore the matrix value for comparisons.
Adder()
Default constructor.
This structure defines some basic traits for the ordinal field type.
const Ordinal numRows() const
Computed number of rows.
void print(std::ostream &out, const bool doMerge, const bool replace=false)
Print the sparse matrix data.
Stores one entry of a sparse matrix.
void operator()(const Ordinal i, const Ordinal j, const Scalar &Aij, const bool countAgainstTotal=true)
Add an entry to the sparse matrix.
const Ordinal numCols() const
Computed number of columns.
void merge(const Element &rhs, const BinaryFunction &f)
Merge rhs into this Element, using custom binary function.
void merge(const Element &rhs, const bool replace=false)
Merge rhs into this Element, either by addition or replacement.
bool operator!=(const Element &rhs) const
Ignore the matrix value for comparisons.
Ordinal colIndex() const
Column index (zero-based) of this Element.
const Ordinal numEntries() const
Computed number of columns.
Adder(const Ordinal expectedNumRows, const Ordinal expectedNumCols, const Ordinal expectedNumEntries, const bool tolerant=false, const bool debug=false)
Standard constructor.
Reference-counted smart pointer for managing arrays.
To be used with Checker for "raw" sparse matrix input.