00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _SYMM_BAND_MATRIX
00019 #define _SYMM_BAND_MATRIX
00020
00021 #include "vector.h"
00022 #include "matrix_sig.h"
00023
00024
00025 template <typename T> class Symm_BdMatrix;
00026
00027 #if !defined(NO_GD) && !defined(AUTO_DECL)
00028 # include "symm_bdmatrix_gd.h"
00029 #endif
00030
00031 NAMESPACE_TBCI
00032
00033
00034 template <typename T> class Symm_BdMatrix;
00035
00036 template <typename T> class ILU0_Symm_BdMatrixPreconditioner;
00037
00038
00039
00040
00045 template<typename T>
00046 class Symm_BdMatrix : public Matrix_Sig<T>
00047 {
00048 friend class ILU0_Symm_BdMatrixPreconditioner<T>;
00049
00050 protected:
00051 T zero;
00052 T* elementPtr;
00053 unsigned int dimension;
00054 BVector<T*> rowPtr;
00055 BVector<unsigned int> rowOccupation;
00056 BVector<unsigned int> conf;
00057
00058 void construct (const unsigned int N, const T&, T*&,
00059 const BVector<unsigned int>&, BVector<T*>&,
00060 BVector<unsigned int>&);
00061 inline void create (const T& val, const unsigned int N);
00062 inline void create (const T& val, const unsigned int N,
00063 const BVector<unsigned int>&);
00064 inline void destroy ();
00065 public:
00066
00067 Symm_BdMatrix () { create(T(0),1); }
00068 Symm_BdMatrix (const unsigned int N) { create(T(0),N); }
00069 Symm_BdMatrix (const T& val, const unsigned int N) { create(val,N); }
00070 Symm_BdMatrix (const T& val, const unsigned int N,
00071 const BVector<unsigned int>& diagConf) { create(val,N,diagConf); }
00072
00073
00074 inline void resize (const T&, const unsigned int);
00075 inline void resize (const unsigned int newDim) { resize (0, newDim); }
00076 inline void resize (const T&, const unsigned int N, const BVector<unsigned int>&);
00077
00078 ~Symm_BdMatrix () { destroy(); }
00079
00080
00081 const char* mat_info () const { return ("Symm_BdMatrix"); }
00082
00083
00084 const T& operator() (const unsigned int i, const unsigned int k) const;
00085 const T& get (const unsigned int i, const unsigned int k) const
00086 { return (*this) (i, k); }
00087 friend STD__ ostream& operator<< FGD (STD__ ostream&, const Symm_BdMatrix<T>&);
00088 T& setval (const unsigned int i, const unsigned int k);
00089 void setval (const T& wert, const unsigned int i, const unsigned int k)
00090 { setval (i,k) = wert; }
00091 void autoinsert (const T& wert, const unsigned int i, const unsigned int k)
00092 { setval (i,k) = wert; }
00093
00094
00095 TVector<T> operator * (const Vector<T>&) const;
00096
00097
00098 unsigned int rows () const { return dimension; }
00099 unsigned int columns () const { return dimension; }
00100 void clear ();
00101
00102 typedef T value_type;
00103 typedef T element_type;
00104 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
00105
00106 };
00107
00108
00109
00110
00111
00112
00113
00114 template<typename T>
00115 inline void Symm_BdMatrix<T>::resize (const T& val, const unsigned int N)
00116 {
00117 destroy ();
00118 create (val, N);
00119 }
00120
00121 template<typename T>
00122 inline void Symm_BdMatrix<T>::resize (const T& val, const unsigned int N,
00123 const BVector<unsigned int>& Diagconf)
00124 {
00125 destroy ();
00126 create (val, N, Diagconf);
00127 }
00128
00129
00130
00131
00132
00133
00134 template<typename T>
00135 inline void Symm_BdMatrix<T>::create (const T& wert, const unsigned int dim)
00136 {
00137 dimension = dim;
00138 zero = T(0);
00139 conf.resize (0);
00140 rowPtr.resize (dim);
00141 rowOccupation.resize (dim);
00142
00143
00144 if(dim==0)
00145 STD__ cerr << "void Symm_BdMatrix<T>::Symm_BdMatrix(const T&, const unsigned int)" << STD__ endl
00146 << "Invalid constructor parameters: Matrix can not have dimension == 0" << STD__ endl;
00147
00148
00149 construct (dim, wert, elementPtr, conf, rowPtr, rowOccupation);
00150
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160 template<typename T>
00161 inline void Symm_BdMatrix<T>::create(const T& wert, const unsigned int dim,
00162 const BVector<unsigned int>& configVector)
00163 {
00164 dimension=dim;
00165 zero=T(0);
00166 conf.resize(configVector.size());
00167 rowPtr.resize(dim);
00168 rowOccupation.resize(dim);
00169
00170
00171 if(dim==0)
00172 STD__ cerr << "void Symm_BdMatrix<T>::Symm_BdMatrix(const T&, const unsigned int, const BVector<unsigned int>&)" << STD__ endl
00173 << "Invalid constructor parameters: Matrix can not have dimension == 0" << STD__ endl;
00174 if(configVector.size()>=dim)
00175 STD__ cerr << "void Symm_BdMatrix<T>::Symm_BdMatrix(const T&, const unsigned int, const BVector<unsigned int>&)" << STD__ endl
00176 << "Invalid constructor parameters: Number of off-diagonals larger than matrix dimension" << STD__ endl;
00177 for(unsigned i=0; i<configVector.size(); i++)
00178 if(configVector(i)>=dim)
00179 STD__ cerr << "void Symm_BdMatrix<T>::Symm_BdMatrix(const T&, const unsigned int, const BVector<unsigned int>&)" << STD__ endl
00180 << "Invalid constructor parameters: Off-diagonal is out of range" << STD__ endl;
00181
00182
00183 construct(dim,wert,elementPtr,configVector,rowPtr,rowOccupation);
00184 conf = configVector;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 template<typename T>
00194 inline void Symm_BdMatrix<T>::construct (const unsigned int dim, const T& value,
00195 T*& elemPtr, const BVector<unsigned int>& ConfVector,
00196 BVector<T*>& rPtr, BVector<unsigned int>& rowOccup)
00197 {
00198
00199 unsigned int i, j, length = dim;
00200 for (i=0; i<ConfVector.size(); i++)
00201 length += dim - ConfVector(i);
00202
00203
00204 elemPtr = new T [length];
00205 for (i=0; i<length; i++)
00206 elemPtr[i] = value;
00207
00208
00209 if (ConfVector.size()) {
00210 unsigned int next = 0;
00211 for (i=0; i<dim; i++) {
00212 rPtr(i) = &(elemPtr[next]);
00213 next += ConfVector.size()+1;
00214
00215
00216 for (j = ConfVector.size(); j >= 1; j--)
00217 if(ConfVector(j-1) +i >=dim) next--;
00218 else break;
00219 }
00220 }
00221 else
00222 for (i=0; i<dim; i++) rPtr(i) = &(elemPtr[i]);
00223
00224
00225
00226
00227 for (i=0; i<dim; i++)
00228 rowOccup(i) = 0;
00229
00230 for (i=0; i<ConfVector.size(); i++)
00231 rowOccup(ConfVector(i)) = i+1;
00232
00233 }
00234
00235
00236 #if 0
00237 template <typename T>
00238 Symm_BdMatrix<T>::Symm_BdMatrix(const Matrix_Sig<T>& m)
00239 {
00240 create(T(0),1);
00241 for (unsigned i = 0; i < m.rows(); i++)
00242 for (unsigned j = 0; j < m.columns(); j++)
00243 if (MATH__ fabs(m(i,j)) > 1e-15)
00244 this->setval(i, j) = m (i,j);
00245 }
00246 #endif
00247
00248
00249
00250 template<typename T>
00251 inline void Symm_BdMatrix<T>::destroy()
00252 {
00253 delete[] elementPtr;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 template<typename T>
00265 inline T& Symm_BdMatrix<T>::setval (const unsigned int i, const unsigned int k)
00266 {
00267
00268 if((i>=dimension) || (k>=dimension))
00269 STD__ cerr << "T& Symm_BdMatrix<T>::setval (const unsigned int, const unsigned int)" << STD__ endl
00270 << "Invalid Index: Index out of range" << STD__ endl;
00271
00272
00273 unsigned int l,m;
00274 if (i > k) {
00275 l=k; m=i;
00276 } else {
00277 l=i; m=k;
00278 }
00279
00280
00281
00282 if (m == l)
00283 return *rowPtr(l);
00284
00285
00286 if(rowOccupation(m-l) != 0) {
00287 return *(rowPtr(l) + rowOccupation(m-l));
00288 }
00289 else {
00290
00291
00292
00293 T* newmem;
00294 BVector<unsigned int> newConfVector(conf.size() + 1);
00295
00296
00297
00298 unsigned int j,g,h;
00299 int found(-1);
00300 for(g=j=0; j<conf.size(); j++,g++) {
00301
00302 if( conf(j) > (m-l)) {newConfVector(g++)= m-l; found=j;break;}
00303 newConfVector(g) = conf(j);
00304 }
00305
00306 for(; j<conf.size(); j++,g++) {
00307 newConfVector(g) = conf(j);
00308 }
00309
00310 if(found == -1) {newConfVector(conf.size()) = m-l; found=conf.size();}
00311
00312 Vector<T*> newrowPtr(dimension);
00313 Vector<unsigned int> neuerowOccupation(dimension);
00314
00315
00316 construct(dimension,T(0),newmem,newConfVector,newrowPtr,neuerowOccupation);
00317
00318 T* newPtr;
00319 T* oldPtr;
00320 oldPtr = elementPtr;
00321 newPtr = newmem;
00322
00323
00324 for(h=1; h<dimension; h++){
00325 j=0;
00326 while(newPtr != newrowPtr(h)) {
00327 *(newPtr++) = *(oldPtr++);
00328 if( ((int)j == found)&& (int(found+1) < int(newrowPtr(h) - newrowPtr(h-1))) )
00329 newPtr++;
00330 j++;
00331 }
00332 }
00333 *(newPtr) = *(oldPtr);
00334
00335
00336 delete[] elementPtr;
00337
00338
00339 rowPtr = newrowPtr;
00340 rowOccupation = neuerowOccupation;
00341 conf.resize(newConfVector.size()) = newConfVector;
00342 elementPtr = newmem;
00343
00344
00345 return *(rowPtr(l) + rowOccupation(m-l));
00346 }
00347
00348
00349 }
00350
00351
00352
00353
00354
00355
00356
00357 template<typename T>
00358 inline const T& Symm_BdMatrix<T>::operator() (const unsigned int i, const unsigned int k) const
00359 {
00360
00361 if((i>=dimension) || (k>=dimension))
00362 STD__ cerr << "const T& Symm_BdMatrix<T>::operator() (const unsigned int, const unsigned int)const" << STD__ endl
00363 << "Invalid Index: Index out of range" << STD__ endl;
00364
00365
00366 unsigned int l,m;
00367 if(i>k) {l=k; m=i;}
00368 else {l=i; m=k;}
00369
00370
00371
00372 if(m==l) return *rowPtr(l);
00373
00374
00375 if(rowOccupation(m-l) != 0) return *(rowPtr(l) + rowOccupation(m-l));
00376 else return zero;
00377
00378 }
00379
00380
00381
00382
00383
00384
00385 template<typename T>
00386 inline STD__ ostream& operator<< (STD__ ostream& out, const Symm_BdMatrix<T>& matrix)
00387 {
00388 unsigned int i,k;
00389 for(i=0; i< matrix.dimension; i++){
00390
00391 for(k=0; k< matrix.dimension; k++) out << matrix(i,k) << " ";
00392 out << STD__ endl;
00393 }
00394 return out;
00395 }
00396
00397
00398
00399
00400
00401 template<typename T>
00402 inline TVector<T> Symm_BdMatrix<T>::operator* (const Vector<T>& Vector) const
00403 {
00404
00405 if (Vector.size() != dimension)
00406 STD__ cerr << "TVector<T> Symm_BdMatrix<T>::operator* (const Vector<T>&)const" << STD__ endl
00407 << "Matrix and Vector have different dimensions" << STD__ endl;
00408
00409 TVector<T> result (Vector.size());
00410
00411
00412 unsigned int i;
00413 if (conf.size() == 0) {
00414 for (i=0; i<dimension; i++)
00415 result.setval(i) = ((*(rowPtr(i))) * Vector(i));
00416 return result;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 unsigned int j, diagonal, confsize;
00470 confsize=conf.size();
00471
00472 T temp;
00473 unsigned max_off=conf(confsize-1);
00474 for(i=0; i<max_off; i++)
00475 {
00476
00477 temp = ((*(rowPtr(i))) * Vector(i));
00478
00479 for(j=0; ((diagonal=conf(j))<=i) && (j<confsize); j++)
00480 temp += *(rowPtr(i-diagonal) + j +1) * Vector(i-diagonal);
00481
00482 for(j=0; j<confsize; j++)
00483 temp += *(rowPtr(i) + j +1) * Vector(i + conf(j));
00484 result.setval(i)=temp;
00485 }
00486 for(i=max_off; i<dimension-max_off; i++)
00487 {
00488
00489 temp = ((*(rowPtr(i))) * Vector(i));
00490 for(j=0; j<confsize; j++)
00491 {
00492
00493 temp += *(rowPtr(i-conf(j)) + j +1) * Vector(i-conf(j));
00494
00495 temp += *(rowPtr(i) + j +1) * Vector(i + conf(j));
00496 }
00497 result.setval(i)=temp;
00498 }
00499 for(i=dimension-max_off; i<dimension; i++)
00500 {
00501
00502 temp = ((*(rowPtr(i))) * Vector(i));
00503
00504 for(j=0; j<confsize; j++)
00505 temp += *(rowPtr(i-conf(j)) + j +1) * Vector(i-conf(j));
00506
00507 for(j=0; (conf(j)<dimension-i) && (j<confsize); j++)
00508 temp += *(rowPtr(i) + j +1) * Vector(i + conf(j));
00509 result.setval(i)=temp;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 return result;
00616 }
00617
00618
00619
00620
00621
00622 template<typename T>
00623 inline void Symm_BdMatrix<T>::clear()
00624 {
00625 T* Ptr = elementPtr;
00626 while(Ptr != rowPtr(dimension-1)) (*Ptr++) = T(0);
00627 *Ptr = T(0);
00628
00629 }
00630
00631
00632 NAMESPACE_END
00633
00634 #endif // !defined(_Symm_BdMatrix)