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
00029
00030
00031 #ifndef _DENSE_MATRIX_H_
00032 #define _DENSE_MATRIX_H_
00033
00034 #include "RealVector.h"
00035 #include "Matrix.h"
00036 #include <string>
00037
00038
00039 #define QR_MIN_NORM 1.0e-20
00040
00041 namespace FDDlib {
00042
00046 template<class T>
00047 class DenseMatrix : public Matrix<T>
00048 {
00049 protected:
00051 int rows_;
00053 int cols_;
00055 T* valVec_;
00056
00057 public:
00062 DenseMatrix(int rows, int cols);
00063
00065 DenseMatrix();
00066
00068 DenseMatrix(const DenseMatrix<T>& dm);
00069
00071 virtual ~DenseMatrix();
00072
00074 void deallocate();
00075
00080 void init(int rows, int cols);
00081
00083 DenseMatrix<T>& operator=(const DenseMatrix<T>& dm);
00084
00088 DenseMatrix<T>& operator*=(const T v);
00089
00091 template<class Vector>
00092 Vector operator*(const Vector& m) const;
00093
00095 int getNumRows() const;
00096
00098 int getNumCols() const;
00099
00101 T val(int row, int col) const;
00102
00104 void set(int row, int col, T v) throw(std::string);
00105
00111 void QRDecomp(DenseMatrix<T>& Q, DenseMatrix<T>& R) const throw(std::string);
00112
00118 template<class Vector>
00119 void LSSolve(Vector& x, const Vector& b) const throw(std::string);
00120
00122 DenseMatrix<T> operator*(const DenseMatrix<T>& a) const;
00123
00125 DenseMatrix<T> operator+(const DenseMatrix<T>& a) const;
00126
00128 DenseMatrix<T> operator-(const DenseMatrix<T>& a) const;
00129
00131 DenseMatrix<T> transpose() const;
00132
00134 RealVector<T> getRow(int row) const;
00135
00137 RealVector<T> getColumn(int col) const;
00138
00140 T& operator()(int row, int col);
00141
00143 T operator()(int row, int col) const;
00144
00145 };
00146
00147 template<class T>
00148 DenseMatrix<T>::DenseMatrix(int rows, int cols)
00149 {
00150 int i;
00151
00152 rows_ = rows;
00153 cols_ = cols;
00154 valVec_ = new T[rows_*cols_];
00155 for (i = 0; i < rows_*cols_; i++)
00156 {
00157 valVec_[i] = (T) 0;
00158 }
00159 }
00160
00161 template<class T>
00162 DenseMatrix<T>::DenseMatrix()
00163 {
00164 rows_ = 0;
00165 cols_ = 0;
00166 valVec_ = (T*) NULL;
00167 }
00168
00169 template<class T>
00170 DenseMatrix<T>::DenseMatrix(const DenseMatrix<T>& dm)
00171 {
00172 int i, j;
00173
00174 rows_ = dm.getNumRows();
00175 cols_ = dm.getNumCols();
00176 valVec_ = new T[rows_*cols_];
00177 for (i = 0; i < rows_; i++)
00178 {
00179 for (j = 0; j < cols_; j++)
00180 {
00181 set(i,j, dm.val(i,j));
00182 }
00183 }
00184 }
00185
00186 template<class T>
00187 void DenseMatrix<T>::deallocate()
00188 {
00189 delete[] valVec_;
00190 }
00191
00192
00193 template<class T>
00194 DenseMatrix<T>::~DenseMatrix()
00195 {
00196 delete[] valVec_;
00197 }
00198
00199 template<class T>
00200 void DenseMatrix<T>::init(int rows, int cols)
00201 {
00202 int i;
00203
00204 rows_ = rows;
00205 cols_ = cols;
00206 if (valVec_ != (T*) NULL)
00207 {
00208 delete[] valVec_;
00209 }
00210
00211 valVec_ = new T[rows*cols];
00212 for (i = 0; i < rows_*cols_; i++)
00213 {
00214 valVec_[i] = (T) 0;
00215 }
00216 }
00217
00218 template<class T>
00219 DenseMatrix<T>& DenseMatrix<T>::operator=(const DenseMatrix<T>& dm)
00220 {
00221 int i, j;
00222
00223 if (valVec_ != (T*) NULL)
00224 delete[] valVec_;
00225
00226 rows_ = dm.getNumRows();
00227 cols_ = dm.getNumCols();
00228 valVec_ = new T[rows_*cols_];
00229 for (i = 0; i < rows_; i++)
00230 {
00231 for (j =0; j < cols_; j++)
00232 {
00233 set(i,j,dm.val(i,j));
00234 }
00235 }
00236 return *this;
00237 }
00238
00239 template<class T>
00240 inline DenseMatrix<T>& DenseMatrix<T>::operator*=(const T v)
00241 {
00242 int i, j;
00243
00244 for (i = 0; i < rows_; i++)
00245 {
00246 for (j = 0; j < cols_; j++)
00247 {
00248 set(i,j, val(i,j) * v);
00249 }
00250 }
00251
00252 return *this;
00253 }
00254
00255 template<class T>
00256 template<class Vector>
00257 inline Vector DenseMatrix<T>::operator*(const Vector& m) const
00258 {
00259 int i, j;
00260 T v;
00261 Vector ret(getNumRows());
00262
00263 for (i = 0; i < getNumRows(); i++)
00264 {
00265 v = (T) 0;
00266 for (j = 0; j < getNumCols(); j++)
00267 {
00268 v += (T) (val(i,j) * m(j));
00269 }
00270 ret(i) = v;
00271 }
00272
00273 return ret;
00274 }
00275
00276 template<class T>
00277 inline int DenseMatrix<T>::getNumRows() const
00278 {
00279 return rows_;
00280 }
00281
00282 template<class T>
00283 inline int DenseMatrix<T>::getNumCols() const
00284 {
00285 return cols_;
00286 }
00287
00288 template<class T>
00289 inline T DenseMatrix<T>::val(int row, int col) const
00290 {
00291 return valVec_[row*cols_ + col];
00292 }
00293
00294 template<class T>
00295 inline void DenseMatrix<T>::set(int row, int col, T v) throw(std::string)
00296 {
00297 valVec_[row*cols_ + col] = v;
00298 }
00299
00300 template<class T>
00301 void DenseMatrix<T>::QRDecomp(DenseMatrix<T>& Q, DenseMatrix<T>& R) const throw(std::string)
00302 {
00303 int i, j;
00304 T v;
00305 double n;
00306 T proj;
00307
00308
00309
00310 RealVector<T> * rv = new RealVector<T>[getNumCols()];
00311 for (i = 0; i < getNumCols(); i++)
00312 {
00313 rv[i].init(getNumRows());
00314 }
00315
00316 for (i = 0; i < getNumRows(); i++)
00317 {
00318 for (j = 0; j < getNumCols(); j++)
00319 {
00320 v = val(i,j);
00321 rv[j].set(i, v);
00322 }
00323 }
00324
00325
00326
00327
00328 Q.init(getNumRows(), getNumCols());
00329 R.init(getNumCols(), getNumCols());
00330
00331 for (i = 0; i < getNumCols(); i++)
00332 {
00333 n = norm(rv[i]);
00334 if (n < QR_MIN_NORM)
00335 throw std::string("DenseMatrix::QRDecomp: norm of basis is too small");
00336 rv[i] *= (T) (1/n);
00337 R(i,i) = (T) n;
00338 for (j = i+1; j < getNumCols(); j++)
00339 {
00340 proj = (T) dot(rv[i], rv[j]);
00341 R(i,j) = proj;
00342 rv[j] -= proj*rv[i];
00343 }
00344 }
00345
00346
00347
00348
00349 for (i = 0; i < getNumRows(); i++)
00350 {
00351 for (j = 0; j < getNumCols(); j++)
00352 {
00353 v = rv[j].val(i);
00354 Q(i,j) = v;
00355 }
00356 }
00357
00358 }
00359
00360
00361 template<class T>
00362 template<class Vector>
00363 void DenseMatrix<T>::LSSolve(Vector& x, const Vector& b) const throw(std::string)
00364 {
00365 int i, j;
00366 DenseMatrix<T> Q,R;
00367 Vector rhs;
00368 T v;
00369
00370 try {
00371 QRDecomp(Q,R);
00372 } catch (std::string s) {
00373 throw std::string("DenseMatrix::LSSolve: QR Decomposition failed.");
00374 }
00375
00376
00377 rhs = (Q.transpose())*b;
00378
00379 Vector sol(R.getNumCols());
00380 for (i = 0; i < R.getNumCols(); i++)
00381 {
00382 sol(i) = 0;
00383 }
00384
00385
00386 for (i = R.getNumCols()-1; i >= 0; i--)
00387 {
00388 v = rhs(i);
00389 for (j = i+1; j < R.getNumCols(); j++)
00390 {
00391 v -= (T) sol(j)*R(i,j);
00392 }
00393 v = v/( (T) R(i,i));
00394 sol(i) = v;
00395 }
00396
00397 x = sol;
00398 }
00399
00400 template<class T>
00401 inline DenseMatrix<T> DenseMatrix<T>::operator*(const DenseMatrix<T>& a) const
00402 {
00403
00404 int i,j,k;
00405 T v;
00406 DenseMatrix<T> dm(getNumRows(), a.getNumCols());
00407
00408 for (i = 0; i < getNumRows(); i++)
00409 {
00410 for (j = 0; j < a.getNumCols(); j++)
00411 {
00412 v = (T) 0;
00413 for (k = 0; k < getNumCols(); k++)
00414 {
00415 v += val(i,k) * a.val(k,j);
00416 }
00417 dm(i,j) = v;
00418 }
00419 }
00420
00421 return dm;
00422 }
00423
00424 template<class T>
00425 inline DenseMatrix<T> DenseMatrix<T>::operator+(const DenseMatrix<T>& a) const
00426 {
00427 int i,j;
00428
00429 DenseMatrix<T> dm(getNumRows(), getNumCols());
00430
00431 for (i = 0; i < getNumRows(); i++)
00432 {
00433 for (j = 0; j < getNumCols(); i++)
00434 {
00435 dm(i,j) = val(i,j) + b.val(i,j);
00436 }
00437 }
00438
00439 return dm;
00440
00441 }
00442
00443 template<class T>
00444 inline DenseMatrix<T> DenseMatrix<T>::operator-(const DenseMatrix<T>& a) const
00445 {
00446 int i,j;
00447
00448 DenseMatrix<T> dm(getNumRows(), getNumCols());
00449
00450 for (i = 0; i < getNumRows(); i++)
00451 {
00452 for (j = 0; j < getNumCols(); i++)
00453 {
00454 dm(i,j) = val(i,j) - a.val(i,j);
00455 }
00456 }
00457
00458 return dm;
00459
00460 }
00461
00462 template<class T>
00463 inline DenseMatrix<T> DenseMatrix<T>::transpose() const
00464 {
00465 int i,j;
00466
00467 DenseMatrix<T> dm(getNumCols(), getNumRows());
00468
00469 for (i = 0; i < getNumRows(); i++)
00470 {
00471 for (j = 0; j < getNumCols(); j++)
00472 {
00473 dm(j,i) = val(i,j);
00474 }
00475
00476 }
00477
00478 return dm;
00479
00480 }
00481
00482 template<class T>
00483 RealVector<T> DenseMatrix<T>::getRow(int row) const
00484 {
00485 RealVector<T> ret(cols_);
00486 int i, j;
00487
00488 for(i=(row*cols_), j=0; i < ((row+1)*cols_); i++, j++)
00489 ret.set(j, valVec_[i]);
00490
00491 return ret;
00492 }
00493
00494 template <class T>
00495 RealVector<T> DenseMatrix<T>::getColumn(int col) const
00496 {
00497 RealVector<T> ret(rows_);
00498 int i, j;
00499
00500 for(i=col, j=0; i<rows_*cols_; i+=cols_, j++)
00501 ret.set(j, valVec_[i]);
00502
00503 return ret;
00504 }
00505
00506 template <class T>
00507 inline T& DenseMatrix<T>::operator()(int row, int col)
00508 {
00509 return valVec_[row*cols_ + col];
00510 }
00511
00512 template <class T>
00513 inline T DenseMatrix<T>::operator()(int row, int col) const
00514 {
00515 return valVec_[row*cols_ + col];
00516 }
00517
00518 }
00519 #endif