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
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 }
00281
00282 #endif // MATRIXDATA_H