00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef TBCI_F_BANDMATRIX_H
00015 #define TBCI_F_BANDMATRIX_H
00016
00017
00018
00019 #include "matrix.h"
00020 #include "vector.h"
00021
00022
00023 #if !defined(NO_GD) && !defined(AUTO_DECL)
00024 # include "f_bandmatrix_gd.h"
00025 #endif
00026
00027 NAMESPACE_TBCI
00028
00029
00030 #ifndef TBCI_DISABLE_EXCEPT
00031
00032
00033 class F_BandMatErr : public NumErr
00034 {
00035 public:
00036 F_BandMatErr() : NumErr ("Error in F_BandMatrix library") {}
00037 F_BandMatErr(const char* t, const long i = 0) : NumErr (t, i) {}
00038 };
00039 #endif
00040
00041 #ifdef PRAGMA_I
00042 # pragma interface "f_bandmatrix.h"
00043 #endif
00044
00045
00046 template <typename T> class F_BandMatrix;
00047 template <typename T> class Matrix;
00048
00049
00050
00051
00052
00058 template <typename T>
00059 class F_BandMatrix : public Matrix_Sig<T>
00060 {
00061 public:
00062 typedef T value_type;
00063 typedef T element_type;
00064 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
00065
00066 F_BandMatrix() { allocate(1,0,0); }
00067
00068 F_BandMatrix(unsigned int dimension,
00069 unsigned int superDiags = 0,
00070 unsigned int subDiags = 0)
00071 { allocate(dimension, superDiags, subDiags); }
00072
00073 F_BandMatrix(const F_BandMatrix<T>& m) { copy(m); }
00074 F_BandMatrix(const Matrix<T>& m);
00075
00076 ~F_BandMatrix() { destroy(); }
00077 void clear();
00078
00079
00080 inline T operator() (unsigned int row, unsigned int column) const;
00081
00082 inline T& operator() (unsigned int row, unsigned int column);
00083
00084 inline void setval(const T z, unsigned int row, unsigned int column);
00085 T& setval (unsigned r, unsigned c) { return this->operator () (r, c); }
00086
00087
00088 TVector<T> get_col(unsigned int column) const;
00089 void set_col( const Vector<T>& v, unsigned int column);
00090 void set_col( const TVector<T>& tv, unsigned int column);
00091 void set_col( const TSVector<T>& tsv, unsigned int column);
00092
00093
00094 unsigned int rows() const { return dim; }
00095 unsigned int columns() const { return dim; }
00096 unsigned int size() const { return dim; }
00097 unsigned int numSuper() const { return super; }
00098 unsigned int numSub() const { return sub; }
00099 unsigned int ldab() const { return sub+super+1; }
00100
00101 inline void resize(unsigned int newDim, unsigned int newSuper, unsigned int newSub);
00102
00103
00104 F_BandMatrix<T>& operator= (const F_BandMatrix<T>& m);
00105
00106
00107 friend bool operator== FGD (const F_BandMatrix<T>&, const F_BandMatrix<T>&);
00108
00109 friend bool operator!= FGD (const F_BandMatrix<T>&, const F_BandMatrix<T>&);
00110
00111
00112 friend F_BandMatrix<T> operator- FGD (const F_BandMatrix<T>& m);
00113
00114
00115 friend TVector<T> do_fbdmat_vec_mul FGD (const F_BandMatrix<T>& m, const Vector<T>& v);
00116
00117 TVector<T> transMult(const Vector<T>& v) const;
00118 TVector<T> transMult(const TVector<T>& tv) const;
00119 TVector<T> transMult(const TSVector<T>& tsv) const;
00120
00121
00122 friend F_BandMatrix<T> do_fbdmat_scale FGD (const F_BandMatrix<T>&m, const T z);
00123 friend F_BandMatrix<T> do_fbdmat_scale FGD (const T z, const F_BandMatrix<T>&m);
00124
00125 F_BandMatrix<T>& operator*= (const T z);
00126
00127 friend F_BandMatrix<T> operator/ FGD (const F_BandMatrix<T>& m, T const z);
00128
00129 F_BandMatrix<T>& operator/= (const T z);
00130
00131 friend F_BandMatrix<T> operator+ FGD (const F_BandMatrix<T>&,const F_BandMatrix<T>&);
00132 friend F_BandMatrix<T> operator- FGD (const F_BandMatrix<T>&,const F_BandMatrix<T>&);
00133
00134 F_BandMatrix<T> transposed_copy() const;
00136 F_BandMatrix<T>& transpose();
00137
00138
00139 friend STD__ ostream& operator<< FGD (STD__ ostream& stream, const F_BandMatrix<T>& m);
00140
00141 T* const & get_fortran_matrix() const { return comp; }
00142
00143 F_BandMatrix<T>& swap(F_BandMatrix<T>& m);
00144
00145 protected:
00146 unsigned int dim, super, sub;
00147 T* comp;
00148 mutable T dummy;
00149
00150 void allocate(unsigned int dimension,
00151 unsigned int superDiags,
00152 unsigned int subDiags);
00153
00154 void destroy();
00155
00156 void copy(const F_BandMatrix<T>& m);
00157
00158 void find_super(const Matrix<T>& m);
00159 void find_sub(const Matrix<T>& m);
00160 };
00161
00162
00163
00164
00165
00166
00167 template <typename T>
00168 inline T F_BandMatrix<T>::operator() (unsigned int row, unsigned int column) const
00169 {
00170 BCHK(row >= dim || column >= dim, F_BandMatErr, Illegal index, (row<column ? row : column), 0);
00171 if (column < row)
00172 if (row-column > sub)
00173 return 0;
00174 if (column > row)
00175 if (column-row > super)
00176 return 0;
00177 return comp[(super+row-column) + column*(super+sub+1)];
00178 }
00179
00180
00181 template <typename T>
00182 inline T& F_BandMatrix<T>::operator() (unsigned int row, unsigned int column)
00183 {
00184 BCHK(row >= dim || column >= dim, F_BandMatErr, Illegal index, (row<column ? row : column), dummy=(T)0);
00185 BCHK(column < row && row-column > sub, F_BandMatErr, Illegal index, (row<column ? row : column), dummy=(T)0);
00186 BCHK(column > row && column-row > super, F_BandMatErr, Illegal index, (row<column ? row : column), dummy=(T)0);
00187 return comp[super+row-column + column*(super+sub+1)];
00188 }
00189
00190
00191
00192 template <typename T>
00193 inline void F_BandMatrix<T>::setval(const T z, unsigned int row, unsigned int column)
00194 {
00195 BCHKNR(row >= dim || column >= dim, F_BandMatErr, Illegal index, (row<column ? row : column));
00196 BCHKNR(column < row && row-column > sub, F_BandMatErr, Illegal index, (row<column ? row : column));
00197 BCHKNR(column > row && column-row > super, F_BandMatErr, Illegal index, (row<column ? row : column));
00198 comp[super+row-column + column*(super+sub+1)] = z;
00199 }
00200
00201
00202 template <typename T>
00203 inline void F_BandMatrix<T>::resize(unsigned int newDim, unsigned int newSuper,
00204 unsigned int newSub)
00205 {
00206 destroy();
00207 allocate(newDim, newSuper, newSub);
00208 }
00209
00210
00211 template <typename T>
00212 TVector<T> F_BandMatrix<T>::get_col(unsigned int column) const
00213 {
00214 TVector<T> ColVec(dim);
00215 BCHK(column >= dim, F_BandMatErr, Illegal index, column, ColVec);
00216 for (unsigned int i=0; i<dim; i++)
00217 ColVec.set((*this)(i,column),i);
00218 return ColVec;
00219 }
00220
00221
00222 template <typename T>
00223 void F_BandMatrix<T>::set_col( const Vector<T>& v, unsigned int column)
00224 {
00225 BCHKNR(column >= dim, F_BandMatErr, Illegal index, column);
00226 for (unsigned int i=0; i<dim; ++i) {
00227 if (column <= i)
00228 if (!(i-column > sub))
00229 (*this)(i,column) = v(i);
00230 if (column > i)
00231 if (!(column-i > super))
00232 (*this)(i,column) = v(i);
00233
00234 }
00235 }
00236
00237 template <typename T>
00238 inline void F_BandMatrix<T>::set_col( const TVector<T>& tv, unsigned int column)
00239 {
00240 Vector<T> v(tv);
00241 set_col(v,column);
00242 }
00243
00244 template <typename T>
00245 inline void F_BandMatrix<T>::set_col( const TSVector<T>& tsv, unsigned int column)
00246 {
00247 Vector<T> v(tsv);
00248 set_col(v,column);
00249 }
00250
00251
00252 template <typename T>
00253 F_BandMatrix<T>& F_BandMatrix<T>::operator= (const F_BandMatrix<T>& m)
00254 {
00255 BCHK(dim != m.dim, F_BandMatErr, Different sizes in assignment, m.dim, *this );
00256 if (this == &m) return *this;
00257 if (dim==m.dim && super==m.super && sub==m.sub)
00258 {
00259 CSTD__ memcpy(comp, m.comp, sizeof(T)*(dim*(super+sub+1)));
00260 return *this;
00261 }
00262 destroy();
00263 copy(m);
00264 return *this;
00265 }
00266
00267
00268
00269 template <typename T>
00270 bool operator== (const F_BandMatrix<T>& m1, const F_BandMatrix<T>& m2)
00271 {
00272 if (m1.dim != m2.dim) return false;
00273 for (unsigned int j=0; j<m1.dim; j++)
00274 for (unsigned int i=0; i<m1.dim; i++)
00275 if (m1(i,j) != m2(i,j)) return false;
00276 return true;
00277 }
00278
00279
00280
00281 template <typename T>
00282 bool operator!= (const F_BandMatrix<T>& m1, const F_BandMatrix<T>& m2)
00283 {
00284 if (m1.dim != m2.dim) return true;
00285 for (unsigned int j=0; j<m1.dim; j++)
00286 for (unsigned int i=0; i<m1.dim; i++)
00287 if (m1(i,j) != m2(i,j)) return true;
00288 return false;
00289 }
00290
00291
00292 template <typename T>
00293 F_BandMatrix<T> operator- (const F_BandMatrix<T>& m)
00294 {
00295 F_BandMatrix<T> res(m.dim, m.super, m.sub);
00296 for (unsigned int j=0; j<(m.dim*(m.sub+m.super+1)); ++j)
00297 res.comp[j] = -m.comp[j];
00298 return res;
00299 }
00300
00301
00302 template <typename T>
00303 TVector<T> do_fbdmat_vec_mul(const F_BandMatrix<T>&m, const Vector<T>& v)
00304
00305 {
00306 TVector<T> res(m.dim);
00307 BCHK(m.dim != v.size(), F_BandMatErr, Dimension conflict, v.size(), res);
00308 for (unsigned int i=0; i<m.dim; i++) {
00309
00310 unsigned int left = (i>m.sub ? i-m.sub : 0);
00311
00312 unsigned int right = MIN(i+m.super+1,m.dim);
00313 T sum(0.0);
00314 for (unsigned int j=left; j<right; j++)
00315 sum += m.comp[(m.super+i-j)+j*(m.super+m.sub+1)] * v(j);
00316 res.set(sum,i);
00317 }
00318 return res;
00319 }
00320
00321 template <typename T>
00322 inline TVector<T> operator* (const F_BandMatrix<T>& m, const Vector<T>& v)
00323 {
00324 return do_fbdmat_vec_mul(m, v);
00325 }
00326
00327
00328 template <typename T>
00329 inline TVector<T> operator* (const F_BandMatrix<T>& m, const TVector<T>& tv)
00330 {
00331 Vector<T> v(tv);
00332 return do_fbdmat_vec_mul(m, v);
00333 }
00334
00335
00336 template <typename T>
00337 inline TVector<T> operator* (const F_BandMatrix<T>& m, const TSVector<T>& tsv)
00338 {
00339 Vector<T> v(tsv);
00340 return do_fbdmat_vec_mul(m, v);
00341 }
00342
00343
00344 template <typename T>
00345 TVector<T> F_BandMatrix<T>::transMult(const Vector<T>& v) const
00346 {
00347 TVector<T> res(dim);
00348 BCHK(dim != v.size(), F_BandMatErr, Dimension conflict, v.size(), res);
00349 for (unsigned int j=0; j<dim; j++)
00350 {
00351
00352 unsigned int left = (j>super ? j-super : 0);
00353
00354 unsigned int right = MIN(j+sub+1,dim);
00355 T sum(0.0);
00356 for (unsigned int i=left; i<right; i++)
00357 sum += comp[(super+i-j)+j*(super+sub+1)] * v(i);
00358 res.set(sum,j);
00359 }
00360 return res;
00361 }
00362
00363 template <typename T>
00364 inline TVector<T> F_BandMatrix<T>::transMult(const TVector<T>& tv) const
00365 {
00366 Vector<T> v(tv);
00367 return(this->transMult(v));
00368 }
00369
00370
00371 template <typename T>
00372 inline TVector<T> F_BandMatrix<T>::transMult(const TSVector<T>& tsv) const
00373 {
00374 Vector<T> v(tsv);
00375 return(this->transMult(v));
00376 }
00377
00378
00379 template <typename T>
00380 F_BandMatrix<T> do_fbdmat_scale (const F_BandMatrix<T>& m, const T z)
00381 {
00382 F_BandMatrix<T> res(m.dim, m.super, m.sub);
00383 for (unsigned int j=0; j<(m.dim*(m.super+m.sub+1)); ++j)
00384 res.comp[j] = m.comp[j] * z;
00385 return res;
00386 }
00387
00388
00389
00390 template <typename T>
00391 F_BandMatrix<T> do_fbdmat_scale (const T z, const F_BandMatrix<T>& m)
00392 {
00393 F_BandMatrix<T> res(m.dim, m.super, m.sub);
00394 for (unsigned int j=0; j<(m.dim*(m.super+m.sub+1)); ++j)
00395 res.comp[j] = z * m.comp[j];
00396 return res;
00397 }
00398
00399 template <typename T>
00400 inline F_BandMatrix<T> operator* (const F_BandMatrix<T>& m, const T z)
00401 {
00402 return do_fbdmat_scale(m, z);
00403 }
00404
00405 template <typename T>
00406 inline F_BandMatrix<T> operator* (const T z, const F_BandMatrix<T>& m)
00407 {
00408 return do_fbdmat_scale(z, m);
00409 }
00410
00411
00412 template <typename T>
00413 F_BandMatrix<T>& F_BandMatrix<T>::operator*= (const T z)
00414 {
00415 for (unsigned int j=0; j<(dim*(super+sub+1)); ++j)
00416 comp[j] *= z;
00417 return *this;
00418 }
00419
00420
00421
00422 template <typename T>
00423 F_BandMatrix<T> operator/ (const F_BandMatrix<T>& m, const T z)
00424 {
00425 F_BandMatrix<T> res(m.dim, m.super, m.sub);
00426 for (unsigned int j=0; j<(m.dim*(m.super+m.sub+1)); ++j)
00427 res.comp[j] = m.comp[j] / z;
00428 return res;
00429 }
00430
00431
00432 template <typename T>
00433 F_BandMatrix<T>& F_BandMatrix<T>::operator/= (const T z)
00434 {
00435 for (unsigned int j=0; j<(dim*(super+sub+1)); ++j)
00436 comp[j] /= z;
00437 return *this;
00438 }
00439
00440
00442 template <typename T>
00443 inline void F_BandMatrix<T>::find_super(const Matrix<T>& m)
00444 {
00445 for (super = dim-1; super > 0; --super)
00446 for (unsigned r = 0; r < dim-super; ++r)
00447 if (m(r, r+super) != (T)0)
00448 return;
00449 }
00450
00452 template <typename T>
00453 inline void F_BandMatrix<T>::find_sub(const Matrix<T>& m)
00454 {
00455 for (sub = dim-1; sub > 0; --sub)
00456 for (unsigned c = 0; c < dim-sub; ++c)
00457 if (m(c+sub, c) != (T)0)
00458 return;
00459 }
00460
00461 template <typename T>
00462 F_BandMatrix<T>::F_BandMatrix(const Matrix<T>& m)
00463 {
00464 BCHKNR(m.rows() != m.columns(), F_BandMatErr, only square matrices possible, m.rows());
00465 dim = m.rows();
00466 this->find_super(m); this->find_sub(m);
00467
00468 this->allocate(dim, super, sub);
00469 for (unsigned r = 0; r < dim; ++r)
00470 for (unsigned c = MAX(0, (int)(r-sub));
00471 c < MIN(dim, r+super+1); ++c)
00472 (*this)(r,c) = m(r,c);
00473 }
00474
00475 #ifndef LAPACK_INLINE
00476 # define LAPACK_INLINE
00477 #endif
00478
00479
00480 template <typename T>
00481 LAPACK_INLINE void F_BandMatrix<T>::allocate(unsigned int dimension,
00482 unsigned int superDiags,
00483 unsigned int subDiags)
00484 {
00485 BCHKNR(dimension == 0, F_BandMatErr, Zero space allocating, 0);
00486 BCHKNR(superDiags >= dimension || subDiags >= dimension, F_BandMatErr, Dimension conflict, (subDiags<superDiags? subDiags : superDiags));
00487 dim = dimension;
00488 super = superDiags;
00489 sub = subDiags;
00490 unsigned int colSize = super + sub + 1;
00491 comp = new T[colSize*dim];
00492 BCHKNR(comp==NULL, F_BandMatErr, Out of memory, colSize*dim);
00493
00494 }
00495
00496
00497
00498 template <typename T>
00499 inline void F_BandMatrix<T>::destroy()
00500 {
00501 if (comp != NULL)
00502 delete[] comp;
00503 }
00504
00505
00506
00507 template <typename T>
00508 void F_BandMatrix<T>::copy(const F_BandMatrix<T>& m)
00509 {
00510 dim = m.dim;
00511 super = m.super;
00512 sub = m.sub;
00513 unsigned int colSize = super + sub + 1;
00514 comp = new T[colSize*dim];
00515 BCHKNR(comp==NULL, F_BandMatErr, Out of memory, colSize*dim);
00516 CSTD__ memcpy(comp, m.comp, sizeof(T)*(dim*colSize));
00517 }
00518
00519
00520
00521 template <typename T>
00522 F_BandMatrix<T> operator+ (const F_BandMatrix<T>& A,const F_BandMatrix<T>& B)
00523 {
00524 unsigned int numSub(0),numSuper(0),dim(0);
00525
00526 dim = MAX(A.size(), B.size());
00527 numSuper = MAX(A.numSuper(), B.numSuper());
00528 numSub = MAX(A.numSub(), B.numSub());
00529
00530
00531 F_BandMatrix<T> C(dim,numSuper,numSub);
00532
00533 BCHK(A.size()!=B.size(), F_BandMatErr, Dimension conflict, A.size(), C );
00534
00535 for(unsigned int i(0);i<C.size();i++)
00536 {
00537 for(int j(i-C.numSub());j<=(int)(i+C.numSuper());j++)
00538 {
00539 if((j>=0)&&(j<(int)C.size()))
00540 {
00541 if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper()))
00542 && (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
00543 C(i,j)=A(i,j)+B(i,j);
00544 else if( (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
00545 C(i,j)=B(i,j);
00546 else if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper())) )
00547 C(i,j)=A(i,j);
00548 }
00549 }
00550 }
00551 return C;
00552 }
00553
00554 template <typename T>
00555 F_BandMatrix<T> operator- (const F_BandMatrix<T>& A, const F_BandMatrix<T>& B)
00556 {
00557
00558 const unsigned dim = MAX(A.size(), B.size());
00559 const unsigned numSuper = MAX(A.numSuper(), B.numSuper());
00560 const unsigned numSub = MAX(A.numSub(), B.numSub());
00561
00562
00563 F_BandMatrix<T> C(dim, numSuper, numSub);
00564
00565 BCHK(A.size()!=B.size(), F_BandMatErr, Dimension conflict, A.size(), C );
00566
00567 for(unsigned int i(0);i<C.size();i++)
00568 {
00569 for(int j(i-C.numSub());j<=(int)(i+C.numSuper());j++)
00570 {
00571 if((j>=0)&&(j<(int)C.size()))
00572 {
00573 if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper()))
00574 && (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
00575 C(i,j)=A(i,j)-B(i,j);
00576 else if( (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
00577 C(i,j)=-B(i,j);
00578 else if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper())) )
00579 C(i,j)=A(i,j);
00580 }
00581 }
00582 }
00583 return C;
00584 }
00585
00586 template <typename T>
00587 STD__ ostream& operator<< (STD__ ostream& stream, const F_BandMatrix<T>& m)
00588 {
00589 for (unsigned int i = 0; i < m.rows(); i++)
00590 {
00591 for (unsigned int j = 0; j < m.columns(); j++)
00592 stream << m(i,j) << " ";
00593 stream << STD__ endl;
00594 }
00595 return stream;
00596 }
00597
00598
00599 template <typename T>
00600 LAPACK_INLINE void F_BandMatrix<T>::clear()
00601 {
00602 for (unsigned int j=0; j<(dim*(super+sub+1)); j++)
00603 comp[j] = (T) 0;
00604 }
00605
00606
00607 template <typename T>
00608 F_BandMatrix<T> F_BandMatrix<T>::transposed_copy() const
00609 {
00610 F_BandMatrix<T> f(dim, sub, super);
00611 for (unsigned int r = 0; r < dim; ++r)
00612 for (unsigned int c = MAX(0, (int)(r-super));
00613 c < MIN(dim, r+sub+1); ++c)
00614 f(r,c) = (*this)(c,r);
00615 return f;
00616 }
00617
00618 template <typename T>
00619 inline F_BandMatrix<T>& F_BandMatrix<T>::transpose()
00620 {
00621 F_BandMatrix<T> tr(this->transposed_copy());
00622 return swap(tr);
00623 }
00624
00625
00626 INST(template <typename T> class F_BandMatrix friend F_BandMatrix<T> transpose(const F_BandMatrix<T>& fbd);)
00627 template <typename T>
00628 inline F_BandMatrix<T> transpose(const F_BandMatrix<T>& fbd)
00629 {
00630 return fbd.transposed_copy();
00631 }
00632
00633 template <typename T>
00634 F_BandMatrix<T>& F_BandMatrix<T>::swap(F_BandMatrix<T>& m)
00635 {
00636 SWAP(dim, m.dim);
00637 SWAP(super, m.super); SWAP(sub, m.sub);
00638 SWAP(comp, m.comp);
00639 return *this;
00640 }
00641
00642 NAMESPACE_END
00643
00644 #endif