src/matrixmarket/mtxdataiterator.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           mtxdataiterator.cpp  -  description
00003                              -------------------
00004     begin                : Thu Dec 4 2003
00005     copyright            : (C) 2003 by Roman Geus
00006     email                : roman.geus@psi.ch
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
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     // Read banner
00048     //
00049     if (!(istr >> banner >> mtx >> crd >> dataType >> storageScheme))
00050         throw std::runtime_error("Error reading header line");
00051 
00052     // convert to lower case
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     // Skip comment lines
00094     //
00095     std::string line;
00096     // skip one newline
00097     istr.get();
00098     while (istr.peek() == '%')
00099         getline(istr, line);
00100 
00101     //
00102     // Read size info
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         // swap row amd column
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         // hermitian case not supported
00161     } else {
00162         read_next_triplet();
00163         _last_mirrored = false;
00164     }
00165     return *this;
00166 }

Generated on Fri Oct 26 13:35:12 2007 for FEMAXX (Finite Element Maxwell Eigensolver) by  doxygen 1.4.7