QGpCoreTools/MatrixData.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 **  This file is part of QGpCoreTools.
00004 **
00005 **  This library is free software; you can redistribute it and/or
00006 **  modify it under the terms of the GNU Lesser General Public
00007 **  License as published by the Free Software Foundation; either
00008 **  version 2.1 of the License, or (at your option) any later version.
00009 **
00010 **  This file is distributed in the hope that it will be useful, but WITHOUT
00011 **  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 **  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00013 **  License for more details.
00014 **
00015 **  You should have received a copy of the GNU Lesser General Public
00016 **  License along with this library; if not, write to the Free Software
00017 **  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 **
00019 **  See http://www.geopsy.org for more information.
00020 **
00021 **  Created : 2008-07-15
00022 **  Authors :
00023 **    Marc Wathelet
00024 **    Marc Wathelet (LGIT, Grenoble, France)
00025 **
00026 ***************************************************************************/
00027 
00028 #ifndef MATRIXDATA_H
00029 #define MATRIXDATA_H
00030 
00031 #include "Global.h"
00032 #include "MatrixMultiply.h"
00033 #include "PermutationVector.h"
00034 #include "Number.h"
00035 #include "StringSection.h"
00036 
00037 namespace QGpCoreTools {
00038 
00039 template <typename T> class Matrix;
00040 
00041 template <typename T> class MatrixData : public QSharedData
00042 {
00043 public:
00044   inline MatrixData();
00045   inline MatrixData(const MatrixData<T>& m);
00046   inline ~MatrixData();
00047 
00048   inline void operator=(const MatrixData<T>& m);
00049   inline bool operator==(const MatrixData<T>& m) const;
00050   Matrix<T> operator+(const MatrixData<T>& m) const;
00051   Matrix<T> operator-(const MatrixData<T>& m) const;
00052   Matrix<T> operator*(const MatrixData<T>& m) const;
00053   inline void zero();
00054   void identity();
00055   void fill(const T& v);
00056   inline T& at(int row, int col);
00057   inline const T& at(int row, int col) const;
00058   const T * data() const {return _values;}
00059   T * data() {return _values;}
00060   Matrix<T> transposed() const;
00061   void mergeRow(const MatrixData<T>& row1, const MatrixData<T>& row2);
00062   void mergeColumn(const MatrixData<T>& col1, const MatrixData<T>& col2);
00063   void copyAt(int row, int col, const MatrixData<T>& m);
00064   Matrix<T> subMatrix(int rowStart, int colStart, int rowEnd, int colEnd) const;
00065   Matrix<T> sortedRows(const PermutationVector& p);
00066   Matrix<T> sortedColumns(const PermutationVector& p);
00067 
00068   int columnCount() const {return _ncol;}
00069   int rowCount() const {return _nrow;}
00070   T * values() {return _values;}
00071   const T * values() const {return _values;}
00072   int nextNullRow(int startRow) const;
00073   inline void resize(int ndim) {resize(ndim, ndim);}
00074   inline void resize(int nrow, int ncol);
00075 
00076   QString toUserString(int precision=6, char format='g') const;
00077   QString toString() const;
00078   bool fromString(const StringSection& s);
00079 
00080   void swapRowColumn();
00081 protected:
00082   int _nrow, _ncol;
00083   T * _values;
00084 };
00085 
00086 template <typename T> inline MatrixData<T>::MatrixData()
00087    : QSharedData()
00088 {
00089   _nrow=0;
00090   _ncol=0;
00091   _values=0;
00092 }
00093 
00094 template <typename T> inline MatrixData<T>::MatrixData(const MatrixData<T>& m)
00095    : QSharedData()
00096 {
00097   _values=0;
00098   resize(m._nrow, m._ncol);
00099   memcpy(_values, m._values, sizeof(T)*_nrow * _ncol);
00100 }
00101 
00102 template <typename T> inline MatrixData<T>::~MatrixData()
00103 {
00104   delete [] _values;
00105 }
00106 
00107 template <typename T> inline void MatrixData<T>::operator=(const MatrixData<T>& m)
00108 {
00109   resize(m._nrow, m._ncol);
00110   memcpy(_values, m._values, sizeof(T)*_nrow * _ncol);
00111 }
00112 
00113 template <typename T> inline void MatrixData<T>::resize(int nrow, int ncol)
00114 {
00115   ASSERT(nrow>0 && ncol>0);
00116   _nrow=nrow;
00117   _ncol=ncol;
00118   delete [] _values;
00119   _values=new T[_nrow*_ncol];
00120 }
00121 
00122 template <typename T> inline void MatrixData<T>::swapRowColumn()
00123 {
00124   qSwap(_nrow, _ncol);
00125 }
00126 
00127 template <typename T> inline bool MatrixData<T>::operator==(const MatrixData<T>& m) const
00128 {
00129   if(_nrow!=m._nrow || _ncol!=m._ncol) return false;
00130   for(int i=_nrow * _ncol-1; i>=0;i--) {
00131     if(_values[i]!=m._values[i]) return false;
00132   }
00133   return true;
00134 }
00135 
00136 template <typename T> inline void MatrixData<T>::zero()
00137 {
00138   memset(_values, 0, sizeof(T)*_nrow*_ncol);
00139 }
00140 
00141 template <typename T> inline void MatrixData<T>::identity()
00142 {
00143   zero();
00144   int offset=_ncol + 1;
00145   int n=_nrow * _ncol;
00146   for(int i=0; i<n;i+=offset) _values[i]=1.0;
00147 }
00148 
00149 template <typename T> void MatrixData<T>::fill(const T& v)
00150 {
00151   for(int i=_nrow*_ncol-1; i>=0; i--) {
00152     _values[i]=v;
00153   }
00154 }
00155 
00156 template <typename T> inline T& MatrixData<T>::at(int row, int col)
00157 {
00158   ASSERT(row>=0 && row<_nrow);
00159   ASSERT(col>=0 && col<_ncol);
00160   return _values[col*_nrow+row];
00161 }
00162 
00163 template <typename T> inline const T& MatrixData<T>::at(int row, int col) const
00164 {
00165   ASSERT(row>=0 && row<_nrow);
00166   ASSERT(col>=0 && col<_ncol);
00167   return _values[col*_nrow+row];
00168 }
00169 
00170 template <typename T> void MatrixData<T>::mergeRow(const MatrixData<T>& row1, const MatrixData<T>& row2)
00171 {
00172   ASSERT(row1._ncol==row2._ncol);
00173   resize(row1._nrow+row2._nrow, row1._ncol);
00174   int length1=sizeof(T)*row1._nrow;
00175   int length2=sizeof(T)*row2._nrow;
00176   T * values=_values;
00177   T * lastValue=_values+_nrow*_ncol;
00178   T * row1Values=row1._values;
00179   T * row2Values=row2._values;
00180   while(values<lastValue) {
00181     memcpy(values, row1Values, length1);
00182     values+=row1._nrow;
00183     row1Values+=row1._nrow;
00184     memcpy(values, row2Values, length2);
00185     values+=row2._nrow;
00186     row2Values+=row2._nrow;
00187   }
00188 }
00189 
00190 template <typename T> void MatrixData<T>::mergeColumn(const MatrixData<T>& col1, const MatrixData<T>& col2)
00191 {
00192   ASSERT(col1._nrow==col2._nrow);
00193   resize(col1._nrow, col1._ncol+col2._ncol);
00194   int offset=_nrow*col1._ncol;
00195   memcpy(_values, col1._values, sizeof(T)*offset);
00196   memcpy(_values+offset, col2._values, sizeof(T)*_nrow*col2._ncol);
00197 }
00198 
00199 template <typename T> int MatrixData<T>::nextNullRow(int startRow) const
00200 {
00201   for(int ir=startRow; ir<_nrow; ir++) {
00202     int ic=0;
00203     for(; ic<_ncol; ic++) {
00204       if(_values[ic*_nrow+ir]!=0.0) {
00205         break;
00206       }
00207     }
00208     if(ic==_ncol) {
00209       return ir;
00210     }
00211   }
00212   return -1;
00213 }
00214 
00215 template <typename T> QString MatrixData<T>::toUserString(int precision, char format) const
00216 {
00217   QString str("    | ");
00218   for(int j=0; j<_ncol; j++) {
00219     str+=QString(" %1 |").arg(j, 12, 10, QChar(' '));
00220   }
00221   str+="\n----|-";
00222   for(int j=0; j<_ncol; j++) {
00223     str+="--------------|";
00224   }
00225   str+="\n";
00226   for(int i=0; i<_nrow; i++) {
00227     str+=QString("%1 | ").arg(i, 3, 10, QChar(' '));
00228     for(int j=0; j<_ncol; j++) {
00229       str+=QString(" %1 |").arg(Number::toDouble(at(i, j)), 12, format, precision, QChar(' '));
00230     }
00231     str+="\n";
00232   }
00233   str+="----|-";
00234   for(int j=0; j<_ncol; j++) {
00235     str+="--------------|";
00236   }
00237   str+="\n";
00238   return str;
00239 }
00240 
00241 template <typename T> QString MatrixData<T>::toString() const
00242 {
00243   QString str;
00244   int n=_nrow*_ncol;
00245   for(int i=0; i<n; i++) {
00246     str+=Number::toString(_values[i], 20);
00247     str+=" ";
00248   }
00249   return str;
00250 }
00251 
00252 template <typename T> bool MatrixData<T>::fromString(const StringSection& s)
00253 {
00254   const QChar * ptr=0;
00255   int n=_nrow*_ncol;
00256   for(int i=0; i<n; i++) {
00257     if(!s.nextNumber(_values[i], ptr)) {
00258       return false;
00259     }
00260   }
00261   return true;
00262 }
00263 
00264 template <typename T> void MatrixData<T>::copyAt(int row, int col, const MatrixData<T>& m)
00265 {
00266   ASSERT(row>=0 && row+m.rowCount()<=rowCount());
00267   ASSERT(col>=0 && col+m.columnCount()<=columnCount());
00268   int mrow=m.rowCount();
00269   int length=sizeof(T)*mrow;
00270   T * values=m._values;
00271   T * lastValue=values+mrow*m.columnCount();
00272   T * thisValues=_values+row+col*_nrow;
00273   while(values<lastValue) {
00274     memcpy(thisValues, values, length);
00275     values+=mrow;
00276     thisValues+=_nrow;
00277   }
00278 }
00279 
00280 } // namespace QGpCoreTools
00281 
00282 #endif // MATRIXDATA_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines