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 _SparseRowMatrix_H_
00032 #define _SparseRowMatrix_H_
00033
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <string>
00037 #include "Matrix.h"
00038 #include "RealVector.h"
00039
00040 namespace FDDlib {
00041
00048 template <class T>
00049 struct SparseRowEntry
00050 {
00052 int column;
00054 T val;
00055 };
00056
00065 template<class T>
00066 class SparseRowMatrix : public Matrix<T>
00067 {
00068 protected:
00070 int MaxRows_;
00072 int EntriesPerRow_;
00074 int* NumCols_;
00076 SparseRowEntry<T>* Entries_;
00077
00078 public:
00080 SparseRowMatrix();
00081
00083 SparseRowMatrix(int maxrows, int max_per_row);
00084
00086 SparseRowMatrix(const SparseRowMatrix<T>& SRM);
00087
00089 virtual ~SparseRowMatrix();
00090
00092 virtual SparseRowMatrix<T>& operator=(const SparseRowMatrix<T>& SRM);
00093
00095 virtual void init(int maxrows, int max_per_row);
00096
00098 virtual void deallocate();
00099
00103 virtual T val(int row, int col) const;
00104
00106 virtual int getEntriesPerRow() const;
00107
00109 virtual SparseRowEntry<T>* getRowEntry(int row) const;
00110
00112 virtual int getCol(int row, int n) const;
00113
00117 virtual int getCol(int row, int n, T& v) const;
00118
00120 virtual int getNumCols(int row) const;
00121
00123 virtual int getNumCols() const;
00124
00126 virtual int getNumRows() const;
00127
00131 virtual void set(int row, int col, T val) throw(std::string);
00132
00136 template<class Vector>
00137 Vector operator*(const Vector& m) const;
00138
00140 RealVector<T> getRow(int row) const;
00141
00143 RealVector<T> getColumn(int col) const;
00144
00145 };
00146
00147
00148 template <class T>
00149 SparseRowMatrix<T>::SparseRowMatrix()
00150 {
00151 MaxRows_ = 0;
00152 EntriesPerRow_ = 0;
00153 NumCols_ = (int*) NULL;
00154 Entries_ = (SparseRowEntry<T>*) NULL;
00155 }
00156
00157 template <class T>
00158 SparseRowMatrix<T>::SparseRowMatrix(int maxrows,
00159 int max_per_row)
00160 {
00161 MaxRows_ = maxrows;
00162 EntriesPerRow_ = max_per_row;
00163 NumCols_ = new int[MaxRows_];
00164 Entries_ = new SparseRowEntry<T>[MaxRows_*EntriesPerRow_];
00165 for (int i = 0; i < MaxRows_; i++)
00166 {
00167 NumCols_[i] = 0;
00168 }
00169 }
00170
00171 template<class T>
00172 SparseRowMatrix<T>::SparseRowMatrix(const SparseRowMatrix<T>& ESR)
00173 {
00174 int i;
00175 SparseRowEntry<T>* s, *d;
00176
00177 MaxRows_ = ESR.getNumRows();
00178 EntriesPerRow_ = ESR.getEntriesPerRow();
00179 NumCols_ = new int[MaxRows_];
00180 Entries_ = new SparseRowEntry<T>[MaxRows_*EntriesPerRow_];
00181 for (i = 0; i < MaxRows_; i++)
00182 {
00183 s = ESR.getRowEntry(i);
00184 d = getRowEntry(i);
00185 NumCols_[i] = ESR.getNumCols(i);
00186 for (j = 0; j < EntriesPerRow_; j++)
00187 {
00188 d[j].column = s[j].column;
00189 d[j].val = s[j].val;
00190 }
00191 }
00192 }
00193
00194 template<class T>
00195 SparseRowMatrix<T>& SparseRowMatrix<T>::operator=(const SparseRowMatrix<T>& ESR)
00196 {
00197 int i, j;
00198 SparseRowEntry<T>* s, *d;
00199
00200 if (getNumRows() > 0)
00201 {
00202 delete[] NumCols_;
00203 delete[] Entries_;
00204 }
00205
00206 MaxRows_ = ESR.getNumRows();
00207 EntriesPerRow_ = ESR.getEntriesPerRow();
00208
00209 NumCols_ = new int[ESR.getNumRows()];
00210 Entries_ = new SparseRowEntry<T>[MaxRows_*EntriesPerRow_];
00211 for (i = 0; i < MaxRows_; i++)
00212 {
00213 s = ESR.getRowEntry(i);
00214 d = getRowEntry(i);
00215 NumCols_[i] = ESR.getNumCols(i);
00216 for (j = 0; j < NumCols_[i]; j++)
00217 {
00218 d[j].column = s[j].column;
00219 d[j].val = s[j].val;
00220 }
00221 }
00222
00223 return *this;
00224 }
00225
00226 template <class T>
00227 void SparseRowMatrix<T>::init(int maxrows, int max_per_row)
00228 {
00229 MaxRows_ = maxrows;
00230 EntriesPerRow_ = max_per_row;
00231
00232 if (NumCols_ != (int*) NULL)
00233 delete[] NumCols_;
00234
00235 if (Entries_ != (SparseRowEntry<T>*) NULL)
00236 delete[] Entries_;
00237
00238 NumCols_ = new int[MaxRows_];
00239 Entries_ = new SparseRowEntry<T>[MaxRows_*EntriesPerRow_];
00240 for (int i = 0; i < MaxRows_; i++)
00241 {
00242 NumCols_[i] = 0;
00243 }
00244 }
00245
00246 template<class T>
00247 SparseRowMatrix<T>::~SparseRowMatrix()
00248 {
00249 if (Entries_ != (SparseRowEntry<T>*) NULL)
00250 delete[] Entries_;
00251
00252 if (NumCols_ != (int*) NULL)
00253 delete[] NumCols_;
00254 }
00255
00256 template<class T>
00257 void SparseRowMatrix<T>::deallocate()
00258 {
00259 if (Entries_ != (SparseRowEntry<T>*) NULL)
00260 delete[] Entries_;
00261
00262 if (NumCols_ != (int*) NULL)
00263 delete[] NumCols_;
00264
00265 Entries_ = (SparseRowEntry<T>*) NULL;
00266 NumCols_ = (int*) NULL;
00267 MaxRows_ = 0;
00268 EntriesPerRow_ = 0;
00269 }
00270
00271
00272 template<class T>
00273 inline T SparseRowMatrix<T>::val(int row, int col) const
00274 {
00275 int i;
00276
00277 for (i = 0; i < NumCols_[row]; i++)
00278 {
00279 if (Entries_[row*EntriesPerRow_ + i].column == col)
00280 return Entries_[row*EntriesPerRow_ + i].val;
00281 }
00282 return 0;
00283 }
00284
00285 template<class T>
00286 inline int SparseRowMatrix<T>::getEntriesPerRow() const
00287 {
00288 return EntriesPerRow_;
00289 }
00290
00291
00292 template<class T>
00293 inline SparseRowEntry<T>* SparseRowMatrix<T>::getRowEntry(int r) const
00294 {
00295 return (Entries_ + r*EntriesPerRow_);
00296 }
00297
00298
00299 template<class T>
00300 inline int SparseRowMatrix<T>::getCol(int row, int n) const
00301 {
00302 return (Entries_[row*EntriesPerRow_ + n].column);
00303 }
00304
00305
00306 template<class T>
00307 inline int SparseRowMatrix<T>::getCol(int row, int n, T& v) const
00308 {
00309 v = Entries_[row*EntriesPerRow_ + n].val;
00310 return (Entries_[row*EntriesPerRow_ + n].column);
00311 }
00312
00313
00314 template<class T>
00315 inline int SparseRowMatrix<T>::getNumCols(int row) const
00316 {
00317
00318 if (NumCols_ == (int*)NULL)
00319 return 0;
00320
00321 return NumCols_[row];
00322 }
00323
00324 template<class T>
00325 inline int SparseRowMatrix<T>::getNumCols() const
00326 {
00327 int i, j;
00328
00329 int col;
00330
00331
00332 int maxcol = 0;
00333
00334 for (i = 0; i < getNumRows(); i++)
00335 {
00336 for (j = 0; j < getNumCols(i); j++)
00337 {
00338 col = getCol(i, j);
00339 if (col > maxcol)
00340 maxcol = col;
00341 }
00342 }
00343
00344 return maxcol+1;
00345 }
00346
00347 template<class T>
00348 inline int SparseRowMatrix<T>::getNumRows() const
00349 {
00350 return MaxRows_;
00351 }
00352
00353
00354 template<class T>
00355 inline void SparseRowMatrix<T>::set(int row, int col, T val) throw(std::string)
00356 {
00357 int i;
00358 SparseRowEntry<T>* ep;
00359
00360
00361 if (row < 0 || col < 0)
00362 throw std::string("SRM::set: negative row or column parameter");
00363
00364 ep = getRowEntry(row);
00365 for (i = 0; i < NumCols_[row]; i++)
00366 {
00367 if (ep->column == col)
00368 break;
00369 ep++;
00370 }
00371 if (ep - getRowEntry(row) >= EntriesPerRow_)
00372 throw std::string("SRM::set: hit max number of entries per row");
00373 if (ep - getRowEntry(row) == NumCols_[row])
00374 (NumCols_[row])++;
00375
00376 ep->val = val;
00377 ep->column = col;
00378 }
00379
00380
00381 template<class T>
00382 template<class Vector>
00383 inline Vector SparseRowMatrix<T>::operator*(const Vector& m) const
00384 {
00385 int i;
00386 int j;
00387 T rv;
00388 int cols;
00389 SparseRowEntry<T>* ep;
00390
00391 Vector ret(MaxRows_);
00392 for (i = 0; i < MaxRows_; i++)
00393 {
00394 rv = (T) 0;
00395 cols = NumCols_[i];
00396 ep = getRowEntry(i);
00397 for (j = 0; j < cols; j++)
00398 {
00399 rv += m(ep->column) * (ep->val);
00400 ep++;
00401 }
00402 ret(i) = rv;
00403 }
00404
00405 return ret;
00406 }
00407
00408 template<class T>
00409 RealVector<T> SparseRowMatrix<T>::getRow(int row) const
00410 {
00411 int i;
00412 const int numcols = getNumCols();
00413 RealVector<T> ret(numcols);
00414
00415 for(i=0;i<numcols;i++)
00416 ret.set(i,val(row,i));
00417
00418 return ret;
00419 }
00420
00421 template<class T>
00422 RealVector<T> SparseRowMatrix<T>::getColumn(int col) const
00423 {
00424 int i;
00425 RealVector<T> ret(MaxRows_);
00426
00427 for(i=0;i<MaxRows_;i++)
00428 ret.set(i,val(i,col));
00429
00430 return ret;
00431 }
00432
00433 }
00434 #endif