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.
Adder()
Default constructor.
bool operator==(const Element &rhs)
Ignore the matrix value for comparisons.
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.
bool operator!=(const Element &rhs)
Ignore the matrix value for comparisons.
void merge(const Element &rhs, const bool replace=false)
Merge rhs into this Element, either by addition or replacement.
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.