Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SPARSEMATRIX_H
00028 #define SPARSEMATRIX_H
00029
00030 #include "Matrix.h"
00031 #include "QGpCoreToolsDLLExport.h"
00032
00033 namespace QGpCoreTools {
00034
00035 template <typename T> class QGPCORETOOLS_EXPORT SparseMatrix
00036 {
00037 public:
00038 SparseMatrix();
00039 SparseMatrix(int nrow, int ncol);
00040
00041 bool operator==(const Matrix<T>& m) const;
00042
00043 int rowCount() const {return _nrow;}
00044 int columnCount() const {return _ncol;}
00045 int realRowCount() const {return _values.count();}
00046 int valueCount() const;
00047
00048 void clear();
00049 void setRowCount(int nrow);
00050 void setColumnCount(int ncol);
00051
00052 T at(int row, int col) const;
00053 T& at(int row, int col);
00054
00055 typedef QHash<int, T> Row;
00056 typedef typename QHash<int, Row>::ConstIterator ConstRowIterator;
00057 typedef typename QHash<int, Row>::Iterator RowIterator;
00058 typedef typename Row::ConstIterator ConstColumnIterator;
00059 typedef typename Row::Iterator ColumnIterator;
00060
00061 Row& addRow(int row);
00062
00063 ConstRowIterator begin() const {return _values.begin();}
00064 RowIterator begin() {return _values.begin();}
00065 ConstRowIterator end() const {return _values.end();}
00066 RowIterator end() {return _values.end();}
00067
00068 Matrix<T> plainMatrix() const;
00069 void setPlainMatrix(const Matrix<T>& m);
00070
00071 Matrix<T> operator*(const Matrix<T>& m) const;
00072
00073 QString toUserString(int precision=6, char format='g') const;
00074 private:
00075 int _nrow, _ncol;
00076 QHash<int, Row> _values;
00077 };
00078
00079 template <typename T> SparseMatrix<T>::SparseMatrix()
00080 {
00081 _nrow=0;
00082 _ncol=0;
00083 }
00084
00085 template <typename T> SparseMatrix<T>::SparseMatrix(int nrow, int ncol)
00086 {
00087 _nrow=nrow;
00088 _ncol=ncol;
00089 }
00090
00091 template <typename T> bool SparseMatrix<T>::operator==(const Matrix<T>& m) const
00092 {
00093 if(_nrow!=m.rowCount() || _ncol!=m.columnCount()) {
00094 return false;
00095 }
00096 for(int ir=0; ir<_nrow; ir++) {
00097 for(int ic=0; ic<_ncol; ic++) {
00098 const T& v=m.at(ir, ic);
00099 if(v!=0.0 && at(ir, ic)!=v) {
00100 return false;
00101 }
00102 }
00103 }
00104 return true;
00105 }
00106
00107 template <typename T> Matrix<T> SparseMatrix<T>::plainMatrix() const
00108 {
00109 Matrix<T> m(_nrow, _ncol);
00110 for(int ir=0; ir<_nrow; ir++) {
00111 ConstRowIterator itr=_values.constFind(ir);
00112 if(itr!=_values.end()) {
00113 const Row& rowHash=itr.value();
00114 for(int ic=0; ic<_ncol; ic++) {
00115 ConstColumnIterator itc=rowHash.constFind(ic);
00116 if(itc!=rowHash.end()) {
00117 m.at(ir, ic)=itc.value();
00118 } else {
00119 m.at(ir, ic)=0.0;
00120 }
00121 }
00122 } else {
00123 for(int ic=0; ic<_ncol; ic++) {
00124 m.at(ir,ic)=0.0;
00125 }
00126 }
00127 }
00128 return m;
00129 }
00130
00131 template <typename T> void SparseMatrix<T>::setPlainMatrix(const Matrix<T>& m)
00132 {
00133 clear();
00134 setRowCount(m.rowCount());
00135 setColumnCount(m.columnCount());
00136 for(int ir=0; ir<_nrow; ir++) {
00137 for(int ic=0; ic<_ncol; ic++) {
00138 const T& v=m.at(ir, ic);
00139 if(v!=0.0) {
00140 at(ir, ic)=v;
00141 }
00142 }
00143 }
00144 }
00145
00146 template <typename T> int SparseMatrix<T>::valueCount() const
00147 {
00148 int n=0;
00149 for(ConstRowIterator itr=_values.begin(); itr!=_values.end(); itr++) {
00150 const Row& rowHash=itr.value();
00151 n+=rowHash.count();
00152 }
00153 return n;
00154 }
00155
00156 template <typename T> Matrix<T> SparseMatrix<T>::operator*(const Matrix<T>& m) const
00157 {
00158 Matrix<T> r(_nrow, m.columnCount());
00159 for(int ir=0; ir<_nrow; ir++) {
00160 ConstRowIterator itr=_values.constFind(ir);
00161 if(itr!=_values.end()) {
00162 const Row& rowHash=itr.value();
00163 for(int ic=0; ic<m.columnCount(); ic++) {
00164 T s=0.0;
00165 for(ConstColumnIterator itc=rowHash.begin(); itc!=rowHash.end(); itc++) {
00166 s+=itc.value()*m.at(itc.key(), ic);
00167 }
00168 r.at(ir, ic)=s;
00169 }
00170 } else {
00171 for(int ic=0; ic<r.columnCount(); ic++) {
00172 r.at(ir,ic)=0.0;
00173 }
00174 }
00175 }
00176 return r;
00177 }
00178
00179 template <typename T> void SparseMatrix<T>::clear()
00180 {
00181 _nrow=0;
00182 _ncol=0;
00183 _values.clear();
00184 }
00185
00186 template <typename T> void SparseMatrix<T>::setRowCount(int nrow)
00187 {
00188 _nrow=nrow;
00189 for(RowIterator itr=_values.begin(); itr!=_values.end(); itr++) {
00190 if(itr.key()>=nrow) {
00191 _values.remove(itr.key());
00192 }
00193 }
00194 }
00195
00196 template <typename T> void SparseMatrix<T>::setColumnCount(int ncol)
00197 {
00198 _ncol=ncol;
00199 for(RowIterator itr=_values.begin(); itr!=_values.end(); itr++) {
00200 Row& rowHash=itr.value();
00201 for(ColumnIterator itc=rowHash.begin(); itc!=rowHash.end(); itc++) {
00202 if(itc.key()>=ncol) {
00203 rowHash.remove(itc.key());
00204 }
00205 }
00206 }
00207 }
00208
00209 template <typename T> typename SparseMatrix<T>::Row& SparseMatrix<T>::addRow(int row)
00210 {
00211 RowIterator itr=_values.insert(row, QHash<int, T>());
00212 return itr.value();
00213 }
00214
00215 template <typename T> T SparseMatrix<T>::at(int row, int col) const
00216 {
00217 ConstRowIterator itr=_values.constFind(row);
00218 if(itr!=_values.end()) {
00219 const Row& rowHash=itr.value();
00220 ConstColumnIterator itc=rowHash.constFind(col);
00221 if(itc!=rowHash.end()) {
00222 return itc.value();
00223 } else {
00224 return 0.0;
00225 }
00226 } else {
00227 return 0.0;
00228 }
00229 }
00230
00231 template <typename T> T& SparseMatrix<T>::at(int row, int col)
00232 {
00233 RowIterator itr=_values.find(row);
00234 if(itr!=_values.end()) {
00235 Row& rowHash=itr.value();
00236 ColumnIterator itc=rowHash.find(col);
00237 if(itc!=rowHash.end()) {
00238 return itc.value();
00239 } else {
00240 ColumnIterator itc=rowHash.insert(col, 0.0);
00241 return itc.value();
00242 }
00243 } else {
00244 Row& rowHash=addRow(row);
00245 ColumnIterator itc=rowHash.insert(col, 0.0);
00246 return itc.value();
00247 }
00248 }
00249
00250 template <typename T> QString SparseMatrix<T>::toUserString(int precision, char format) const
00251 {
00252 QString str(" | ");
00253 for(int j=0; j<_ncol; j++) {
00254 str+=QString(" %1 |").arg(j, 12, 10, QChar(' '));
00255 }
00256 str+="\n----|-";
00257 for(int j=0; j<_ncol; j++) {
00258 str+="--------------|";
00259 }
00260 str+="\n";
00261 for(int i=0; i<_nrow; i++) {
00262 str+=QString("%1 | ").arg(i, 3, 10, QChar(' '));
00263 for(int j=0; j<_ncol; j++) {
00264 str+=QString(" %1 |").arg(Number::toDouble(at(i, j)), 12, format, precision, QChar(' '));
00265 }
00266 str+="\n";
00267 }
00268 str+="----|-";
00269 for(int j=0; j<_ncol; j++) {
00270 str+="--------------|";
00271 }
00272 str+="\n";
00273 return str;
00274 }
00275
00276 template <typename T> QDataStream& operator<<(QDataStream& s, const SparseMatrix<T>& m)
00277 {
00278 s << m.rowCount() << m.columnCount();
00279 s << m.realRowCount();
00280 for(typename SparseMatrix<T>::ConstRowIterator itr=m.begin(); itr!=m.end(); itr++) {
00281 const typename SparseMatrix<T>::Row& rowHash=itr.value();
00282 s << itr.key() << rowHash.count();
00283 for(typename SparseMatrix<T>::ConstColumnIterator itc=rowHash.begin(); itc!=rowHash.end(); itc++) {
00284 s<< itc.key() << itc.value();
00285 }
00286 }
00287 return s;
00288 }
00289
00290 template <typename T> QDataStream& operator>>(QDataStream& s, SparseMatrix<T>& m)
00291 {
00292 m.clear();
00293 int nrow, ncol;
00294 s >> nrow >> ncol;
00295 m.setRowCount(nrow);
00296 m.setColumnCount(ncol);
00297 s >> nrow;
00298 int index;
00299 T value;
00300 for(int ir=0; ir<nrow; ir++) {
00301 s >> index >> ncol;
00302 typename SparseMatrix<T>::Row& rowHash=m.addRow(index);
00303 for(int ic=0; ic<ncol; ic++) {
00304 s >> index >> value;
00305 rowHash.insert(index, value);
00306 }
00307 }
00308 return s;
00309 }
00310
00311 }
00312
00313 #endif // SPARSEMATRIX_H