00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <algorithm>
00019 #include <stdexcept>
00020 #include <iostream>
00021 #include <iomanip>
00022 #include <string>
00023 #include "mtxdataiterator.h"
00024
00025 MtxDataIterator::MtxDataIterator(istream& istr, bool iterate_mirror)
00026 : _istr(&istr), _nnz_read(0)
00027 {
00028 read_header();
00029 if (get_storage_scheme() == general)
00030 _iterate_mirror = false;
00031 else
00032 _iterate_mirror = iterate_mirror;
00033 _last_mirrored = false;
00034 read_next_triplet();
00035 }
00036
00037 MtxDataIterator::~MtxDataIterator()
00038 {}
00039
00041 void MtxDataIterator::read_header()
00042 {
00043 std::string banner, mtx, crd, dataType, storageScheme;
00044 std::istream& istr = *_istr;
00045
00046
00047
00048
00049 if (!(istr >> banner >> mtx >> crd >> dataType >> storageScheme))
00050 throw std::runtime_error("Error reading header line");
00051
00052
00053 int (*pf)(int)=tolower;
00054 std::transform(banner.begin(), banner.end(), banner.begin(), pf);
00055 std::transform(mtx.begin(), mtx.end(), mtx.begin(), pf);
00056 std::transform(crd.begin(), crd.end(), crd.begin(), pf);
00057 std::transform(dataType.begin(), dataType.end(), dataType.begin(), pf);
00058 std::transform(storageScheme.begin(), storageScheme.end(), storageScheme.begin(), pf);
00059
00060 if (banner != "%%matrixmarket")
00061 throw std::runtime_error("Invalid header");
00062
00063 if (mtx != "matrix")
00064 throw std::runtime_error("Unsupported matrix type");
00065
00066 if (crd != "coordinate")
00067 throw std::runtime_error("Unsupported matrix storage format");
00068 _matrix_type = sparse;
00069
00070 if (dataType == "real")
00071 _element_type = real;
00072 else if (dataType == "complex")
00073 _element_type = complex;
00074 else if (dataType == "integer")
00075 _element_type = integer;
00076 else if (dataType == "pattern")
00077 _element_type = pattern;
00078 else
00079 throw std::runtime_error("Unsupported element datatype");
00080
00081 if (storageScheme == "general")
00082 _storage_scheme = general;
00083 else if (storageScheme == "symmetric")
00084 _storage_scheme = symmetric;
00085 else if (storageScheme == "hermitian")
00086 _storage_scheme = hermitian;
00087 else if (storageScheme == "skew")
00088 _storage_scheme = skew;
00089 else
00090 throw std::runtime_error("Unsupported storage scheme");
00091
00092
00093
00094
00095 std::string line;
00096
00097 istr.get();
00098 while (istr.peek() == '%')
00099 getline(istr, line);
00100
00101
00102
00103
00104 if (!(istr >> _rows >> _cols >> _nnz))
00105 throw std::runtime_error("Error reading matrix dimensions");
00106 }
00107
00109 const int& MtxDataIterator::get_rows() const
00110 {
00111 return _rows;
00112 }
00113
00115 const int& MtxDataIterator::get_cols() const
00116 {
00117 return _cols;
00118 }
00119
00123 const int& MtxDataIterator::get_nnz() const
00124 {
00125 return _nnz;
00126 }
00127
00130 void MtxDataIterator::read_next_triplet()
00131 {
00132 int row, col;
00133 double val;
00134
00135 if (eof())
00136 throw std::runtime_error("Read past end of matrix data");
00137
00138 if (_nnz_read < _nnz) {
00139 if (!((*_istr) >> row >> col >> val))
00140 throw std::runtime_error("Error reading matrix data");
00141
00142 _triplet.row = row-1;
00143 _triplet.col = col-1;
00144 _triplet.val = val;
00145 }
00146 _nnz_read ++;
00147 }
00148
00150 MtxDataIterator& MtxDataIterator::operator++()
00151 {
00152 if (_iterate_mirror && !_last_mirrored && _triplet.row != _triplet.col) {
00153
00154 int temp = _triplet.row;
00155 _triplet.row = _triplet.col;
00156 _triplet.col = temp;
00157 if (get_storage_scheme() == skew)
00158 _triplet.val = -_triplet.val;
00159 _last_mirrored = true;
00160
00161 } else {
00162 read_next_triplet();
00163 _last_mirrored = false;
00164 }
00165 return *this;
00166 }