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),
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_ <<
".");
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_; }
630 Ordinal expectedNumRows_, expectedNumCols_, expectedNumEntries_;
631 Ordinal seenNumRows_, seenNumCols_, seenNumEntries_;
636 std::vector<element_type> elts_;
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Templated Parameter List class.
Reference-counted smart pointer for managing arrays.
To be used with Checker for "raw" sparse matrix input.
void operator()(const Ordinal i, const Ordinal j, const Scalar &Aij, const bool countAgainstTotal=true)
Add an entry to the sparse matrix.
void print(std::ostream &out, const bool doMerge, const bool replace=false)
Print the sparse matrix data.
const std::vector< element_type > & getEntries() const
A temporary const view of the entries of the matrix.
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.
std::pair< size_type, size_type > merge(const bool replace=false)
Merge duplicate elements.
const Ordinal numCols() const
Computed number of columns.
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.
void clear()
Clear all the added matrix entries and reset metadata.
Adder()
Default constructor.
const Ordinal numRows() const
Computed number of rows.
Stores one entry of a sparse matrix.
Scalar value() const
Value (A(rowIndex(), colIndex()) of this Element.
bool operator<(const Element &rhs) const
Lexicographic order first by row index, then by column index.
void merge(const Element &rhs, const BinaryFunction &f)
Merge rhs into this Element, using custom binary function.
Ordinal colIndex() const
Column index (zero-based) of this Element.
Ordinal rowIndex() const
Row index (zero-based) of this Element.
void merge(const Element &rhs, const bool replace=false)
Merge rhs into this Element, either by addition or replacement.
Element()
Default constructor: an invalid entry of the matrix.
bool operator==(const Element &rhs)
Ignore the matrix value for comparisons.
bool operator!=(const Element &rhs)
Ignore the matrix value for comparisons.
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.
Matrix Market file utilities.
"Raw" input of sparse matrices from Matrix Market files.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
This structure defines some basic traits for the ordinal field type.
This structure defines some basic traits for a scalar field type.