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
00032
00033
00034 #ifndef __DMATRIX_H
00035 #define __DMATRIX_H
00036
00037 #include "Matrix.h"
00038
00039
00040 namespace OFELI {
00041
00042 template<class T_> class DMatrix;
00043
00048 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00049 template<class T_>
00050 struct ErrorInDMatrix {
00051 void Message(const char *file, int line, int code, int p1=0, int p2=0, T_ p3=T_(0)) {
00052 cerr << "\n*** Fatal Error in OFELI ***\n";
00053 cerr << "File : " << file << ", line : " << line << "\nIn DMatrix<>::";
00054 switch (code) {
00055
00056 case 51:
00057 cerr << "Set(i,j,x) : Illegal pair of indices : " << p1 << "," << p2 << endl;
00058 break;
00059
00060 case 61:
00061 cerr << "Factor() : The " << p1 << "-th pivot = " << p3 << " is too small\n";
00062 break;
00063
00064 case 62:
00065 cerr << "Factor() : Can't factorize a rectangle matrix\n";
00066 break;
00067
00068 case 71:
00069 cerr << "Solve(b) : The " << p1 << "-th diagonal entry = " << p3 << " is too small\n";
00070 break;
00071
00072 case 72:
00073 cerr << "Solve(b) : Warning : Matrix has not been factorized\n";
00074 return;
00075
00076 case 73:
00077 cerr << "Solve(b) : Can't solve with a rectangle matrix\n";
00078 return;
00079 }
00080 cerr << "Program stops" << endl;
00081 exit(1);
00082 }
00083 };
00084 #endif
00085
00099 template<class T_>
00100 class DMatrix : public Matrix<T_>
00101 {
00102
00103 using Matrix<T_>::_rmin;
00104 using Matrix<T_>::_cmin;
00105 using Matrix<T_>::_rmax;
00106 using Matrix<T_>::_cmax;
00107 using Matrix<T_>::_nb_rows;
00108 using Matrix<T_>::_nb_cols;
00109 using Matrix<T_>::_size;
00110 using Matrix<T_>::_length;
00111 using Matrix<T_>::_a;
00112 using Matrix<T_>::_diag;
00113 using Matrix<T_>::_ch;
00114 using Matrix<T_>::_zero;
00115
00116
00117 public:
00118
00119
00120
00122 DMatrix();
00123
00126 DMatrix(size_t nr);
00127
00130 DMatrix(size_t nr, size_t nc);
00131
00136 DMatrix(Vect<T_> &v);
00137
00140 DMatrix(const DMatrix<T_> &m);
00141
00143 ~DMatrix();
00144
00145 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00146 virtual void setMesh(const class Mesh &mesh, size_t dof=0, size_t type=0);
00147 #endif
00148
00149 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00150 void setMesh(size_t dof, const class Mesh &mesh, int code=0);
00151 #endif
00152
00153 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00154 void setMesh(size_t dof, size_t nb_eq, const class Mesh &mesh);
00155 #endif
00156
00158 void setDiag();
00159
00162 void Resize(size_t size);
00163
00168 void Resize(size_t nr, size_t nc);
00169
00171 Vect<T_> getColumn(size_t j) const;
00172
00174 Vect<T_> getRow(size_t i) const;
00175
00181 void Set(size_t i, size_t j, const T_ &x);
00182
00188 void MultAdd(T_ a, const Vect<T_> &x, Vect<T_> &y) const;
00189
00194 void MultAdd(const Vect<T_> &x, Vect<T_> &y) const;
00195
00200 void Mult(const Vect<T_> &x, Vect<T_> &y) const;
00201
00206 void TMult(const Vect<T_> &x, Vect<T_> &y) const;
00207
00213 void Add(size_t i, size_t j, const T_ &x);
00214
00220 T_ operator()(size_t i, size_t j) const;
00221
00227 T_ & operator()(size_t i, size_t j);
00228
00235 const T_ operator()(size_t i) const;
00236
00244 int Factor();
00245
00255 int Solve(Vect<T_> &b);
00256
00267 int Solve(const Vect<T_> &b, Vect<T_> &x);
00268
00271 DMatrix & operator=(DMatrix<T_> &m);
00272
00275 DMatrix & operator+=(const DMatrix<T_> &m);
00276
00279 DMatrix & operator-=(const DMatrix<T_> &m);
00280
00283 DMatrix & operator=(const T_ &x);
00284
00287 DMatrix & operator*=(const T_ &x);
00288
00291 DMatrix & operator+=(const T_ &x);
00292
00295 DMatrix & operator-=(const T_ &x);
00296
00298 size_t getColInd(size_t i) const;
00299
00300 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00301 size_t getRowPtr(size_t i) const;
00302 #endif
00303
00306 T_ *getArray() const;
00307
00309 T_ getEntry(size_t i, size_t j) const;
00310
00317 void setPrintView(size_t rmin, size_t rmax, size_t cmin, size_t cmax);
00318
00319 private:
00320
00321 mutable ErrorInDMatrix<T_> _e;
00322 bool _fact;
00323 void set_(size_t i, size_t j, const T_ &x) { _a[_nb_cols*(i-1)+j-1] = x; }
00324 };
00325
00326
00328
00330
00331
00332 template<class T_>
00333 DMatrix<T_>::DMatrix() : _fact(false)
00334 {
00335 _length = _size = _nb_rows = _nb_cols = 0;
00336 #ifdef _OFELI_DEBUG
00337 std::clog << "An instance of class DMatrix is constructed.\n";
00338 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00339 #endif
00340 }
00341
00342
00343 template<class T_>
00344 DMatrix<T_>::DMatrix(size_t nr)
00345 {
00346 Resize(nr);
00347 _rmin = 1;
00348 _rmax = _nb_rows;
00349 _cmin = 1;
00350 _cmax = _nb_cols;
00351 #ifdef _OFELI_DEBUG
00352 std::clog << "An instance of class DMatrix is constructed.\n";
00353 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00354 #endif
00355 }
00356
00357
00358 template<class T_>
00359 DMatrix<T_>::DMatrix(size_t nr, size_t nc)
00360 {
00361 Resize(nr,nc);
00362 _rmin = 1;
00363 _rmax = _nb_rows;
00364 _cmin = 1;
00365 _cmax = _nb_cols;
00366 #ifdef _OFELI_DEBUG
00367 std::clog << "An instance of class DMatrix is constructed.\n";
00368 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00369 #endif
00370 }
00371
00372
00373 template<class T_>
00374 DMatrix<T_>::DMatrix(Vect<T_> &v)
00375 {
00376 _length = v.getSize();
00377 _nb_rows = _nb_cols = _size = sqrt(double(_length));
00378 _rmin = 1;
00379 _rmax = _nb_rows;
00380 _cmin = 1;
00381 _cmax = _nb_cols;
00382 _a = v;
00383 }
00384
00385
00386 template<class T_>
00387 DMatrix<T_>::DMatrix(const DMatrix<T_> &m)
00388 {
00389 Resize(m._nb_rows,m._nb_cols);
00390 _a = m._a;
00391 _diag = m._diag;
00392 _fact = m._fact;
00393 _rmin = m._rmin;
00394 _rmax = m._rmax;
00395 _cmin = m._cmin;
00396 _cmax = m._cmax;
00397 #ifdef _OFELI_DEBUG
00398 std::clog << "An instance of class DMatrix is constructed.\n";
00399 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00400 #endif
00401 }
00402
00403
00404 template<class T_>
00405 DMatrix<T_>::~DMatrix()
00406 {
00407 #ifdef _OFELI_DEBUG
00408 std::clog << "An instance of class DMatrix is destructed.\n";
00409 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00410 #endif
00411 }
00412
00413
00414 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00415 template<class T_>
00416 void DMatrix<T_>::setMesh(const class Mesh &mesh, size_t dof, size_t type)
00417 {
00418 Matrix<T_>::_init_set_mesh(mesh,dof,type);
00419 _length = lsize_t(_size*_size);
00420 _diag.resize(_size);
00421 _a.resize(_length);
00422 Clear(_a);
00423 _zero = T_(0);
00424 _fact = false;
00425 }
00426 #endif
00427
00428
00429 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00430 template<class T_>
00431 void DMatrix<T_>::setMesh(size_t dof, const class Mesh &mesh, int code)
00432 {
00433
00434 dof = 0;
00435 code = 0;
00436 if (mesh.getDim()==0) { }
00437 }
00438 #endif
00439
00440 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00441 template<class T_>
00442 void DMatrix<T_>::setMesh(size_t dof, size_t nb_eq, const class Mesh &mesh)
00443 {
00444
00445 dof = 0;
00446 nb_eq = 0;
00447 if (mesh.getDim()==0) { }
00448 }
00449 #endif
00450
00451
00452 template<class T_>
00453 void DMatrix<T_>::setDiag()
00454 {
00455 for (size_t i=0; i<_size; i++)
00456 _diag[i] = _a[_nb_cols*i+i];
00457 }
00458
00459
00460 template<class T_>
00461 void DMatrix<T_>::Resize(size_t size)
00462 {
00463 _nb_rows = _nb_cols = _size = size;
00464 _length = lsize_t(_nb_rows*_nb_cols);
00465 _a.resize(_length);
00466 Clear(_a);
00467 _rmin = 1;
00468 _rmax = _nb_rows;
00469 _cmin = 1;
00470 _cmax = _nb_cols;
00471 }
00472
00473
00474 template<class T_>
00475 void DMatrix<T_>::Resize(size_t nr, size_t nc)
00476 {
00477 _nb_rows = nr;
00478 _nb_cols = nc;
00479 _size = 0;
00480 if (_nb_rows==_nb_cols)
00481 _size = _nb_rows;
00482 _length = lsize_t(_nb_rows*_nb_cols);
00483 _a.resize(_length);
00484 Clear(_a);
00485 _rmin = 1;
00486 _rmax = _nb_rows;
00487 _cmin = 1;
00488 _cmax = _nb_cols;
00489 }
00490
00491
00492 template<class T_>
00493 Vect<T_>DMatrix<T_>::getColumn(size_t j) const
00494 {
00495 Vect<T_> v(_nb_rows);
00496 for (size_t i=0; i<_nb_rows; i++)
00497 v[i] = _a[_nb_cols*i+j-1];
00498 return v;
00499 }
00500
00501
00502 template<class T_>
00503 Vect<T_> DMatrix<T_>::getRow(size_t i) const
00504 {
00505 Vect<T_> v(_nb_cols);
00506 for (size_t j=0; j<_nb_cols; j++)
00507 v[j] = _a[_nb_cols*(i-1)+j];
00508 return v;
00509 }
00510
00511
00512 template<class T_>
00513 void DMatrix<T_>::Set(size_t i, size_t j, const T_ &x)
00514 {
00515 _a[_nb_cols*(i-1)+j-1] = x;
00516 }
00517
00518
00519 template<class T_>
00520 void DMatrix<T_>::MultAdd(T_ a, const Vect<T_> &x, Vect<T_> &y) const
00521 {
00522 for (size_t i=0; i<_nb_rows; i++)
00523 for (size_t j=0; j<_nb_cols; j++)
00524 y[i] += a * _a[_nb_cols*i+j] * x[j];
00525 }
00526
00527
00528 template<class T_>
00529 void DMatrix<T_>::MultAdd(const Vect<T_> &x, Vect<T_> &y) const
00530 {
00531 for (size_t i=0; i<_nb_rows; i++)
00532 for (size_t j=0; j<_nb_cols; j++)
00533 y[i] += _a[_nb_cols*i+j] * x[j];
00534 }
00535
00536
00537 template<class T_>
00538 void DMatrix<T_>::Mult(const Vect<T_> &x, Vect<T_> &y) const
00539 {
00540 Clear(y);
00541 MultAdd(x,y);
00542 }
00543
00544
00545 template<class T_>
00546 void DMatrix<T_>::TMult(const Vect<T_> &x, Vect<T_> &y) const
00547 {
00548 for (size_t i=0; i<_nb_rows; i++)
00549 for (size_t j=0; j<_nb_cols; j++)
00550 y[i] += _a[_nb_cols*(j-1)+i-1] * x[j];
00551 }
00552
00553
00554 template<class T_>
00555 void DMatrix<T_>::Add(size_t i, size_t j, const T_ &x)
00556 {
00557 _a[_nb_cols*(i-1)+j-1] += x;
00558 }
00559
00560
00561 template<class T_>
00562 T_ DMatrix<T_>::operator()(size_t i, size_t j) const
00563 {
00564 #ifdef _BOUNDS
00565 assert(i>0);
00566 assert(i<=_nb_rows);
00567 assert(j>0);
00568 assert(j<=_nb_cols);
00569 #endif
00570 return _a[_nb_cols*(i-1)+j-1];
00571 }
00572
00573
00574 template<class T_>
00575 T_ & DMatrix<T_>::operator()(size_t i, size_t j)
00576 {
00577 #ifdef _BOUNDS
00578 assert(i>0);
00579 assert(i<=_nb_rows);
00580 assert(j>0);
00581 assert(j<=_nb_cols);
00582 #endif
00583 return _a[_nb_cols*(i-1)+j-1];
00584 }
00585
00586
00587 template<class T_>
00588 const T_ DMatrix<T_>::operator()(size_t i) const
00589 {
00590 return _a[i-1];
00591 }
00592
00593
00594 template<class T_>
00595 int DMatrix<T_>::Factor()
00596 {
00597 register size_t j, k;
00598 if (_size==0)
00599 _e.Message(__FILE__,__LINE__,62);
00600 for (size_t i=1; i<_size; i++) {
00601 for (j=1; j<=i; j++) {
00602 if (Abs(_a[_nb_rows*(j-1)+j-1]) < OFELI_TOLERANCE)
00603 _e.Message(__FILE__,__LINE__,61,int(j),0,_a[_nb_rows*(j-1)+j-1]);
00604 _a[_nb_rows*i+j-1] /= _a[_nb_rows*(j-1)+j-1];
00605 for (k=0; k<j; k++)
00606 _a[_nb_rows*i+j] -= _a[_nb_rows*i+k]*_a[_nb_rows*k+j];
00607 }
00608 for (j=i+1; j<_size; j++)
00609 for (k=0; k<i; k++)
00610 _a[_nb_rows*i+j] -= _a[_nb_rows*i+k]*_a[_nb_rows*k+j];
00611 }
00612 _fact = true;
00613 return 0;
00614 }
00615
00616
00617 template<class T_>
00618 int DMatrix<T_>::Solve(Vect<T_> &b)
00619 {
00620 if (!_fact)
00621 _e.Message(__FILE__,__LINE__,72);
00622 if (_size==0)
00623 _e.Message(__FILE__,__LINE__,73);
00624 for (size_t i=0; i<_size; i++) {
00625 T_ s = 0;
00626 for (size_t j=0; j<i; j++)
00627 s += _a[_nb_cols*i+j] * b[j];
00628 b[i] -= s;
00629 }
00630 for (int ii=int(_size)-1; ii>-1; ii--) {
00631 if (Abs(_a[_nb_cols*ii+ii]) < OFELI_TOLERANCE)
00632 _e.Message(__FILE__,__LINE__,71,ii+1,0,_a[_nb_cols*ii+ii]);
00633 b[ii] /= _a[_nb_cols*ii+ii];
00634 for (size_t j=0; j<size_t(ii); j++)
00635 b[j] -= b[ii] * _a[_nb_cols*j+ii];
00636 }
00637 return 0;
00638 }
00639
00640
00641 template<class T_>
00642 int DMatrix<T_>::Solve(const Vect<T_> &b, Vect<T_> &x)
00643 {
00644 x = b;
00645 return Solve(x);
00646 }
00647
00648
00649 template<class T_>
00650 DMatrix<T_> & DMatrix<T_>::operator=(DMatrix<T_> &m)
00651 {
00652 _a = m._a;
00653 return *this;
00654 }
00655
00656
00657 template<class T_>
00658 DMatrix<T_> & DMatrix<T_>::operator+=(const DMatrix<T_> &m)
00659 {
00660 for (size_t i=0; i<_length; i++)
00661 _a[i] += m._a[i];
00662 return *this;
00663 }
00664
00665
00666 template<class T_>
00667 DMatrix<T_> & DMatrix<T_>::operator-=(const DMatrix<T_> &m)
00668 {
00669 for (size_t i=0; i<_length; i++)
00670 _a[i] -= m._a[i];
00671 return *this;
00672 }
00673
00674
00675 template<class T_>
00676 DMatrix<T_> & DMatrix<T_>::operator=(const T_ &x)
00677 {
00678 for (size_t i=0; i<_length; i++)
00679 _a[i] = x;
00680 return *this;
00681 }
00682
00683
00684 template<class T_>
00685 DMatrix<T_> & DMatrix<T_>::operator*=(const T_ &x)
00686 {
00687 for (size_t i=0; i<_length; i++)
00688 _a[i] *= x;
00689 return *this;
00690 }
00691
00692
00693 template<class T_>
00694 DMatrix<T_> & DMatrix<T_>::operator+=(const T_ &x)
00695 {
00696 for (size_t i=0; i<_length; i++)
00697 _a[i] += x;
00698 return *this;
00699 }
00700
00701
00702 template<class T_>
00703 DMatrix<T_> & DMatrix<T_>::operator-=(const T_ &x)
00704 {
00705 for (size_t i=0; i<_length; i++)
00706 _a[i] -= x;
00707 return *this;
00708 }
00709
00710
00711 template<class T_>
00712 size_t DMatrix<T_>::getColInd(size_t i) const
00713 {
00714 #ifdef _BOUNDS_DEBUG
00715 assert(i<=_length && i>0);
00716 #endif
00717 return _ch[i-1];
00718 }
00719
00720
00721 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00722 template<class T_>
00723 size_t DMatrix<T_>::getRowPtr(size_t i) const
00724 {
00725 #ifdef _BOUNDS_DEBUG
00726 assert(i<=_nb_rows+1 && i>0);
00727 #endif
00728 return _ch[i-1];
00729 }
00730 #endif
00731
00732
00733 template<class T_>
00734 T_ * DMatrix<T_>::getArray() const
00735 {
00736 return _a;
00737 }
00738
00739
00740 template<class T_>
00741 T_ DMatrix<T_>::getEntry(size_t i, size_t j) const
00742 {
00743 return _a[_nb_cols*(i-1)+j-1];
00744 }
00745
00746
00747 template<class T_>
00748 void DMatrix<T_>::setPrintView(size_t rmin, size_t rmax, size_t cmin, size_t cmax)
00749 {
00750 _rmin = rmin;
00751 _rmax = rmax;
00752 if (_rmin==0)
00753 _rmin = 1;
00754 if (_rmax>_nb_rows)
00755 _rmax = _nb_rows;
00756 _cmin = cmin;
00757 _cmax = cmax;
00758 if (_cmin==0)
00759 _cmin = 1;
00760 if (_cmax>_nb_cols)
00761 _cmax = _nb_cols;
00762 }
00763
00764
00766
00768
00769
00773 template<class T_>
00774 ostream& operator<<(ostream& s, const DMatrix<T_> &a)
00775 {
00776 size_t rmin, rmax, cmin, cmax;
00777 a.getPrintView(rmin,rmax,cmin,cmax);
00778 s.setf(ios::right|ios::scientific);
00779 s << endl;
00780 for (size_t i=rmin-1; i<rmax; i++) {
00781 s << "\nRow " << setw(6) << i+1 << endl;
00782 for (size_t j=cmin-1; j<cmax; j++)
00783 s << " " << setprecision(8) << std::setfill(' ') << setw(18) << a(i+1,j+1);
00784 s << endl;
00785 }
00786 return s;
00787 }
00788
00789 }
00790
00791 #endif