00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef SPARSE_MATRIX_HPP
00024 #define SPARSE_MATRIX_HPP
00025
00026 #include <StreamCenter.hpp>
00027 #include <Vector.hpp>
00028
00029 #include <BaseMatrix.hpp>
00030 #include <DoubleHashedMatrix.hpp>
00031
00032 #include <Stringify.hpp>
00033 #include <ErrorHandler.hpp>
00034
00042 class SparseElem
00043 {
00044 private:
00046 int __column;
00048 real_t __value;
00049 public:
00050
00052 inline real_t& value()
00053 {
00054 return __value;
00055 }
00056
00058 inline const real_t& value() const
00059 {
00060 return __value;
00061 }
00062
00064 inline int& column()
00065 {
00066 return __column;
00067 }
00068
00070 inline const int& column() const
00071 {
00072 return __column;
00073 }
00074
00076 inline const SparseElem& operator=(const SparseElem& SE)
00077 {
00078 __column = SE.__column;
00079 __value = SE.__value;
00080 return (*this);
00081 }
00082
00084 SparseElem()
00085 : __column(-1),
00086 __value(0)
00087 {
00088 ;
00089 }
00090
00092 SparseElem(const SparseElem& SE)
00093 : __column(SE.__column),
00094 __value(SE.__value)
00095 {
00096 ;
00097 }
00098
00100 ~SparseElem()
00101 {
00102 ;
00103 }
00104 };
00105
00112 class SparseLine
00113 {
00114 private:
00116 size_t s;
00117
00119 SparseElem* element;
00120 public:
00124 inline SparseElem& operator[](const size_t& i)
00125 {
00126 ASSERT (i<s);
00127 return element[i];
00128 }
00129
00133 inline const SparseElem& operator[](const size_t& i) const
00134 {
00135 ASSERT (i<s);
00136 return element[i];
00137 }
00138
00140 inline const size_t& size() const
00141 {
00142 return s;
00143 }
00144
00146 inline void resize(const size_t& newSize)
00147 {
00148 if (s!=0)
00149 delete [] element;
00150 s = newSize;
00151 element = new SparseElem[s];
00152 }
00153
00155 SparseLine(const size_t& n )
00156 : s(n)
00157 {
00158 element = new SparseElem[s];
00159 }
00160
00162 SparseLine()
00163 : s(0)
00164 {
00165 ;
00166 }
00167
00169 ~SparseLine()
00170 {
00171 if (s>0)
00172 delete[] element;
00173 }
00174 };
00175
00186 class SparseMatrix
00187 : public BaseMatrix
00188 {
00189 private:
00191 SparseLine* __line;
00192
00193 const real_t __zero;
00194
00198 mutable Vector<real_t> __Au;
00199
00200 public:
00201 void reset()
00202 {
00203 for (size_t i=0; i<__size; ++i) {
00204 SparseLine& SL = __line[i];
00205 for (size_t j=0; j<SL.size(); ++j) {
00206 SL[j].value() = 0;
00207 }
00208 }
00209 }
00210
00211 void getDiagonal(BaseVector& X) const
00212 {
00213 Vector<real_t>& x = dynamic_cast<Vector<real_t>&>(X);
00214 for (size_t i=0; i<this->size();++i)
00215 x[i] = (*this)(i,i);
00216 }
00217
00218 void timesX(const BaseVector& X,
00219 BaseVector& Z) const
00220 {
00221 const Vector<real_t>& x = dynamic_cast<const Vector<real_t>&>(X);
00222 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00223 z = (*this)*x;
00224 }
00225
00227 const real_t& operator()(const size_t& i,
00228 const size_t& j) const
00229 {
00230 SparseLine& SL = __line[i];
00231 size_t icol;
00232
00233 for (icol=0; icol<__line[i].size(); ++icol) {
00234 const int& column = SL[icol].column();
00235 if (column == (int)j)
00236 break;
00237 else
00238 if (column == -1) {
00239 break;
00240 }
00241 }
00242 if (icol == __line[i].size()) {
00243 return __zero;
00244 }
00245 return (SL[icol].value());
00246 }
00247
00249 const SparseLine& line(const size_t i) const
00250 {
00251 ASSERT(i<__size);
00252 return __line[i];
00253 }
00254
00256 real_t& operator()(const size_t& i,
00257 const size_t& j)
00258 {
00259 SparseLine& SL = __line[i];
00260 size_t icol;
00261
00262 for (icol=0; icol<__line[i].size(); ++icol) {
00263 const int& column = SL[icol].column();
00264 if (column == (int)j)
00265 break;
00266 else
00267 if (column == -1) {
00268 SL[icol].column() = j;
00269 break;
00270 }
00271 }
00272 if (icol == __line[i].size()) {
00273 std::string errorMsg
00274 = "cannot access element ("+stringify(i)+","+stringify(j)+")\n";
00275
00276 throw ErrorHandler(__FILE__,__LINE__,
00277 errorMsg,
00278 ErrorHandler::unexpected);
00279 }
00280 return (SL[icol].value());
00281 }
00282
00284 const Vector<real_t>& operator*(const Vector<real_t>& V) const
00285 {
00286 __Au = 0;
00287
00288 for (size_t i=0; i<__size; ++i) {
00289 const SparseLine& SL = __line[i];
00290 for (size_t j=0; j<SL.size(); ++j) {
00291 const int& k = SL[j].column();
00292 if (k!=-1)
00293 __Au[i] += SL[j].value()*V[k];
00294 else
00295 break;
00296 }
00297 }
00298 return __Au;
00299 }
00300
00302 void transposedTimesX(const BaseVector& X, BaseVector& Z) const
00303 {
00304 const Vector<real_t>& x = dynamic_cast<const Vector<real_t>&>(X);
00305 Vector<real_t>& z = dynamic_cast<Vector<real_t>&>(Z);
00306 ASSERT(x.size()==z.size());
00307 ASSERT(this->size()==x.size());
00308 z = 0;
00309
00310 for (size_t i=0; i<__size; ++i) {
00311 const SparseLine& SL = __line[i];
00312 for (size_t j=0; j<SL.size(); ++j) {
00313 const int& k = SL[j].column();
00314 if (k!=-1)
00315 z[k] += SL[j].value()*x[i];
00316 else
00317 break;
00318 }
00319 }
00320 }
00321
00322 void copyProfile(const SparseMatrix& A)
00323 {
00324 __size = A.size();
00325 __Au.resize(__size);
00326
00327 __line = new SparseLine[__size];
00328 for (size_t i=0; i<__size; ++i) {
00329 const SparseLine& Aline = A.line(i);
00330 const size_t s = Aline.size();
00331 __line[i].resize(s);
00332 }
00333 }
00334
00335 SparseMatrix(const DoubleHashedMatrix& A)
00336 : BaseMatrix(BaseMatrix::sparseMatrix, A.numberOfLines()),
00337 __zero(0),
00338 __Au(A.numberOfLines())
00339 {
00340 __line = new SparseLine[__size];
00341 for (size_t i=0; i<__size; ++i) {
00342 __line[i].resize(A.numberOfLineNonNull(i));
00343
00344 for (DoubleHashedMatrix::const_iterator browsLine = A.beginOfLine(i);
00345 browsLine != A.endOfLine(i); ++browsLine) {
00346 (*this)(i,browsLine.first()) = browsLine.second();
00347 }
00348 }
00349 };
00350
00351 SparseMatrix()
00352 : BaseMatrix(BaseMatrix::sparseMatrix),
00353 __zero(0)
00354 {
00355 ;
00356 };
00357
00359 ~SparseMatrix()
00360 {
00361 delete[] __line;
00362 }
00363 };
00364
00365 #endif // SPARSE_MATRIX_HPP