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" 
   61   namespace MatrixMarket {
 
   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_; }
 
  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. 
 
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. 
 
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.