42 #ifndef __Teuchos_MatrixMarket_Raw_Adder_hpp 43 #define __Teuchos_MatrixMarket_Raw_Adder_hpp 46 #include "Teuchos_ArrayRCP.hpp" 47 #include "Teuchos_CommHelpers.hpp" 49 #include "Teuchos_MatrixMarket_Banner.hpp" 50 #include "Teuchos_MatrixMarket_CoordDataReader.hpp" 86 template<
class Scalar,
class Ordinal>
97 Element (
const Ordinal i,
const Ordinal j,
const Scalar& Aij) :
98 rowIndex_ (i), colIndex_ (j), value_ (Aij) {}
102 return rowIndex_ == rhs.rowIndex_ && colIndex_ == rhs.colIndex_;
107 return ! (*
this == rhs);
112 if (rowIndex_ < rhs.rowIndex_)
114 else if (rowIndex_ > rhs.rowIndex_)
117 return colIndex_ < rhs.colIndex_;
126 template<
class BinaryFunction>
130 std::invalid_argument,
131 "Attempt to merge elements at different locations in the sparse " 132 "matrix. The current element is at (" <<
rowIndex() <<
", " 133 <<
colIndex() <<
") and the element you asked me to merge with it " 135 "probably indicates a bug in the sparse matrix reader.");
137 value_ = f (rhs.value_, value_);
149 std::invalid_argument,
150 "Attempt to merge elements at different locations in the sparse " 151 "matrix. The current element is at (" <<
rowIndex() <<
", " 152 <<
colIndex() <<
") and the element you asked me to merge with it " 154 "probably indicates a bug in the sparse matrix reader.");
160 value_ += rhs.value_;
171 Scalar
value()
const {
return value_; }
174 Ordinal rowIndex_, colIndex_;
188 template<
class Scalar,
class Ordinal>
190 operator<< (std::ostream& out, const Element<Scalar, Ordinal>& elt)
193 std::ios::fmtflags f( out.flags() );
210 if (! STS::isOrdinal) {
215 out << std::scientific;
218 out << std::setbase (10);
224 const double numDigitsAsDouble =
227 const int numDigits =
static_cast<int> (numDigitsAsDouble + 0.5);
232 out << std::setprecision (numDigits + 1);
234 out << elt.rowIndex () <<
" " << elt.colIndex () <<
" ";
235 if (STS::isComplex) {
236 out << STS::real (elt.value ()) <<
" " << STS::imag (elt.value ());
282 template<
class Scalar,
class Ordinal>
285 typedef Ordinal index_type;
286 typedef Scalar value_type;
288 typedef typename std::vector<element_type>::size_type size_type;
303 expectedNumEntries_(0),
328 Adder (
const Ordinal expectedNumRows,
329 const Ordinal expectedNumCols,
330 const Ordinal expectedNumEntries,
331 const bool tolerant=
false,
332 const bool debug=
false) :
333 expectedNumRows_(expectedNumRows),
334 expectedNumCols_(expectedNumCols),
335 expectedNumEntries_(expectedNumEntries),
339 tolerant_ (tolerant),
364 operator() (
const Ordinal i,
367 const bool countAgainstTotal=
true)
370 const bool indexPairOutOfRange = i < 1 || j < 1 ||
371 i > expectedNumRows_ || j > expectedNumCols_;
374 std::invalid_argument,
"Matrix is " << expectedNumRows_ <<
" x " 375 << expectedNumCols_ <<
", so entry A(" << i <<
"," << j <<
") = " 376 << Aij <<
" is out of range.");
377 if (countAgainstTotal) {
379 std::invalid_argument,
"Cannot add entry A(" << i <<
"," << j
380 <<
") = " << Aij <<
" to matrix; already have expected number " 381 "of entries " << expectedNumEntries_ <<
".");
385 elts_.push_back (element_type (i-1, j-1, Aij));
392 seenNumRows_ = std::max (seenNumRows_, i);
393 seenNumCols_ = std::max (seenNumCols_, j);
394 if (countAgainstTotal) {
409 print (std::ostream& out,
const bool doMerge,
const bool replace=
false)
414 std::sort (elts_.begin(), elts_.end());
417 typedef std::ostream_iterator<element_type> iter_type;
418 std::copy (elts_.begin(), elts_.end(), iter_type (out,
"\n"));
443 std::pair<size_type, size_type>
446 typedef typename std::vector<element_type>::iterator iter_type;
455 std::sort (elts_.begin(), elts_.end());
462 size_type numUnique = 0;
463 iter_type cur = elts_.begin();
464 if (cur == elts_.end()) {
465 return std::make_pair (numUnique, size_type (0));
468 iter_type next = cur;
471 while (next != elts_.end()) {
474 cur->merge (*next, replace);
486 const size_type numRemoved = elts_.size() - numUnique;
487 elts_.resize (numUnique);
488 return std::make_pair (numUnique, numRemoved);
536 size_type& numRemovedElts,
540 const bool replace=
false)
545 std::pair<size_type, size_type> mergeResult =
merge (replace);
553 const Ordinal nrows = tolerant_ ? seenNumRows_ : expectedNumRows_;
562 typedef typename std::vector<element_type>::const_iterator iter_type;
564 for (iter_type it = elts_.begin(); it != elts_.end(); ++it) {
565 const Ordinal i = it->rowIndex ();
566 const Ordinal j = it->colIndex ();
567 const Scalar Aij = it->value ();
570 "current matrix entry's row index " << i <<
" is less then what " 571 "should be the current row index lower bound " << curRow <<
".");
572 for (Ordinal k = curRow+1; k <= i; ++k) {
578 static_cast<size_t> (curInd) >= elts_.size (),
579 std::logic_error,
"The current index " << curInd <<
" into ind " 580 "and val is >= the number of matrix entries " << elts_.size ()
586 for (Ordinal k = curRow+1; k <= nrows; ++k) {
596 numUniqueElts = mergeResult.first;
597 numRemovedElts = mergeResult.second;
616 const Ordinal
numRows()
const {
return seenNumRows_; }
621 const Ordinal
numCols()
const {
return seenNumCols_; }
624 Ordinal expectedNumRows_, expectedNumCols_, expectedNumEntries_;
625 Ordinal seenNumRows_, seenNumCols_, seenNumEntries_;
630 std::vector<element_type> elts_;
636 #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.
"Raw" input of sparse matrices from Matrix Market files.
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.
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.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
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.
Adder(const Ordinal expectedNumRows, const Ordinal expectedNumCols, const Ordinal expectedNumEntries, const bool tolerant=false, const bool debug=false)
Standard constructor.
Matrix Market file utilities.
Reference-counted smart pointer for managing arrays.
To be used with Checker for "raw" sparse matrix input.