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_; }
624 Ordinal expectedNumRows_, expectedNumCols_, expectedNumEntries_;
625 Ordinal seenNumRows_, seenNumCols_, seenNumEntries_;
630 std::vector<element_type> elts_;
636 #endif // #ifndef __Teuchos_MatrixMarket_Raw_Adder_hpp