TBCI Numerical high perf. C++ Library 2.8.0
f_bandmatrix.h
Go to the documentation of this file.
1
5//----------------------------------------------------------
6// version 1.1, june 1998
7//
8// Marco Wiedenhaus
9// based on tbandmatrixcomplex.h by Jens Lenge
10//
11// $Id: f_bandmatrix.h,v 1.11.2.19 2019/05/28 11:13:02 garloff Exp $
12//----------------------------------------------------------
13
14#ifndef TBCI_F_BANDMATRIX_H
15#define TBCI_F_BANDMATRIX_H
16
17//#include <stdlib.h> // for use of null macro
18
19#include "tbci/matrix.h"
20#include "tbci/vector.h"
21
22// Avoid -fguiding-decls
23#if !defined(NO_GD) && !defined(AUTO_DECL)
24# include "f_bandmatrix_gd.h"
25#endif
26
28
29// exception class
30#ifndef TBCI_DISABLE_EXCEPT
31//# include "except.h" is in basics.h
32
33class F_BandMatErr : public NumErr
34{
35 public:
36 F_BandMatErr() : NumErr ("Error in F_BandMatrix library") {}
37 F_BandMatErr(const char* t, const long i = 0) : NumErr (t, i) {}
38};
39#endif
40
41#ifdef PRAGMA_I
42# pragma interface "f_bandmatrix.h"
43#endif
44
45
46template <typename T> class F_BandMatrix;
47template <typename T> class Matrix;
48
49//-----------------
50// F_BandMatrix<T>
51//-----------------
52
58template <typename T>
59class F_BandMatrix : public Matrix_Sig<T>
60{
61 public:
62 typedef T value_type;
63 typedef T element_type;
64 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
65 // default constructor
66 F_BandMatrix() { allocate(1,0,0); }
67 // constructor
68 F_BandMatrix(unsigned int dimension,
69 unsigned int superDiags = 0,
70 unsigned int subDiags = 0)
71 { allocate(dimension, superDiags, subDiags); }
72 // copy constructor
74 F_BandMatrix(const Matrix<T>& m);
75 // destructor
77 void clear();
78
79 // element access (read)
80 inline T operator() (unsigned int row, unsigned int column) const;
81 // element access (write)
82 inline T& operator() (unsigned int row, unsigned int column);
83 // element access (write)
84 inline void setval(const T z, unsigned int row, unsigned int column);
85 T& setval (unsigned r, unsigned c) { return this->operator () (r, c); }
86
87 // columnwise access
88 TVector<T> get_col(unsigned int column) const;
89 void set_col( const Vector<T>& v, unsigned int column);
90 void set_col( const TVector<T>& tv, unsigned int column);
91 void set_col( const TSVector<T>& tsv, unsigned int column);
92
93 // query matrix dimensions
94 unsigned int rows() const { return dim; }
95 unsigned int columns() const { return dim; }
96 unsigned int size() const { return dim; }
97 unsigned int numSuper() const { return super; }
98 unsigned int numSub() const { return sub; }
99 unsigned int ldab() const { return sub+super+1; }
100 // change matrix dimensions
101 inline void resize(unsigned int newDim, unsigned int newSuper, unsigned int newSub);
102
103 // matrix-matrix assignment
105
106 // matrix-matrix comparison (==)
107 friend bool operator== FGD (const F_BandMatrix<T>&, const F_BandMatrix<T>&);
108 // matrix-matrix comparison (!=)
109 friend bool operator!= FGD (const F_BandMatrix<T>&, const F_BandMatrix<T>&);
110
111 // matrix negation
112 friend F_BandMatrix<T> operator- FGD (const F_BandMatrix<T>& m);
113
114 // matrix-vector multiplication
116 // transpose-vector multiplication
117 TVector<T> transMult(const Vector<T>& v) const;
118 TVector<T> transMult(const TVector<T>& tv) const;
119 TVector<T> transMult(const TSVector<T>& tsv) const;
120
121 // matrix-scalar multiplication
124 // fast in-place matrix-scalar multiplication
125 F_BandMatrix<T>& operator*= (const T z);
126 // matrix-scalar division
127 friend F_BandMatrix<T> operator/ FGD (const F_BandMatrix<T>& m, T const z);
128 // fast in-place matrix-scalar division
129 F_BandMatrix<T>& operator/= (const T z);
130 // matrix addition and subtraction
131 friend F_BandMatrix<T> operator+ FGD (const F_BandMatrix<T>&,const F_BandMatrix<T>&);
132 friend F_BandMatrix<T> operator- FGD (const F_BandMatrix<T>&,const F_BandMatrix<T>&);
133
137
138 // Output operations
139 friend STD__ ostream& operator<< FGD (STD__ ostream& stream, const F_BandMatrix<T>& m);
140
141 T* const & get_fortran_matrix() const { return comp; }
142
144
145 protected:
146 unsigned int dim, super, sub;
148 mutable T dummy;
149 // used by constructor and redim()
150 void allocate(unsigned int dimension,
151 unsigned int superDiags,
152 unsigned int subDiags);
153 // used by destructor and "=" operator
154 void destroy();
155 // used by copy constr. and "="
156 void copy(const F_BandMatrix<T>& m);
157 // helpers
158 void find_super(const Matrix<T>& m);
159 void find_sub(const Matrix<T>& m);
160};
161
162//------------------------------------------------
163// F_BandMatrix<T> inline function definitions
164//------------------------------------------------
165
166// element access (read)
167template <typename T>
168inline T F_BandMatrix<T>::operator() (unsigned int row, unsigned int column) const
169{
170 BCHK(row >= dim || column >= dim, F_BandMatErr, Illegal index, (row<column ? row : column), 0);
171 if (column < row)
172 if (row-column > sub)
173 return 0;
174 if (column > row)
175 if (column-row > super)
176 return 0;
177 return comp[(super+row-column) + column*(super+sub+1)];
178}
179
180// element access (write)
181template <typename T>
182inline T& F_BandMatrix<T>::operator() (unsigned int row, unsigned int column)
183{
184 BCHK(row >= dim || column >= dim, F_BandMatErr, Illegal index, (row<column ? row : column), dummy=(T)0);
185 BCHK(column < row && row-column > sub, F_BandMatErr, Illegal index, (row<column ? row : column), dummy=(T)0);
186 BCHK(column > row && column-row > super, F_BandMatErr, Illegal index, (row<column ? row : column), dummy=(T)0);
187 return comp[super+row-column + column*(super+sub+1)];
188}
189
190// element access (write)
191// compatible with sparse matrix classes
192template <typename T>
193inline void F_BandMatrix<T>::setval(const T z, unsigned int row, unsigned int column)
194{
195 BCHKNR(row >= dim || column >= dim, F_BandMatErr, Illegal index, (row<column ? row : column));
196 BCHKNR(column < row && row-column > sub, F_BandMatErr, Illegal index, (row<column ? row : column));
197 BCHKNR(column > row && column-row > super, F_BandMatErr, Illegal index, (row<column ? row : column));
198 comp[super+row-column + column*(super+sub+1)] = z;
199}
200
201// change matrix dimensions
202template <typename T>
203inline void F_BandMatrix<T>::resize(unsigned int newDim, unsigned int newSuper,
204 unsigned int newSub)
205{
206 destroy();
207 allocate(newDim, newSuper, newSub);
208}
209
210// extract a certain column
211template <typename T>
212TVector<T> F_BandMatrix<T>::get_col(unsigned int column) const
213{
214 TVector<T> ColVec(dim);
215 BCHK(column >= dim, F_BandMatErr, Illegal index, column, ColVec);
216 for (unsigned int i=0; i<dim; i++)
217 ColVec.set((*this)(i,column),i);
218 return ColVec;
219}
220
221// replace a certain column
222template <typename T>
223void F_BandMatrix<T>::set_col( const Vector<T>& v, unsigned int column)
224{
225 BCHKNR(column >= dim, F_BandMatErr, Illegal index, column);
226 for (unsigned int i=0; i<dim; ++i) {
227 if (column <= i)
228 if (!(i-column > sub))
229 (*this)(i,column) = v(i);
230 if (column > i)
231 if (!(column-i > super))
232 (*this)(i,column) = v(i);
233
234 }
235}
236
237template <typename T>
238inline void F_BandMatrix<T>::set_col( const TVector<T>& tv, unsigned int column)
239{
240 Vector<T> v(tv);
241 set_col(v,column);
242}
243
244template <typename T>
245inline void F_BandMatrix<T>::set_col( const TSVector<T>& tsv, unsigned int column)
246{
247 Vector<T> v(tsv);
248 set_col(v,column);
249}
250
251// matrix-matrix assignment
252template <typename T>
254{
255 BCHK(dim != m.dim, F_BandMatErr, Different sizes in assignment, m.dim, *this );
256 if (this == &m) return *this;
257 if (dim==m.dim && super==m.super && sub==m.sub) // perform fast in-place copy
258 {
259 CSTD__ memcpy(comp, m.comp, sizeof(T)*(dim*(super+sub+1)));
260 return *this;
261 }
262 destroy();
263 copy(m);
264 return *this;
265}
266
267// matrix-matrix comparison (==)
268// also works for matrices with different super/sub
269template <typename T>
271{
272 if (m1.dim != m2.dim) return false;
273 for (unsigned int j=0; j<m1.dim; j++)
274 for (unsigned int i=0; i<m1.dim; i++)
275 if (m1(i,j) != m2(i,j)) return false;
276 return true;
277}
278
279// matrix-matrix comparison (!=)
280// also works for matrices with different super/sub
281template <typename T>
283{
284 if (m1.dim != m2.dim) return true;
285 for (unsigned int j=0; j<m1.dim; j++)
286 for (unsigned int i=0; i<m1.dim; i++)
287 if (m1(i,j) != m2(i,j)) return true;
288 return false;
289}
290
291// matrix negation
292template <typename T>
294{
296 for (unsigned int j=0; j<(m.dim*(m.sub+m.super+1)); ++j)
297 res.comp[j] = -m.comp[j];
298 return res; // JENS: avoid copy constructor soon
299}
300
301// matrix-vector multiplication
302template <typename T>
304// matrix-vector multiplication
305{
306 TVector<T> res(m.dim);
307 BCHK(m.dim != v.size(), F_BandMatErr, Dimension conflict, v.size(), res);
308 for (unsigned int i=0; i<m.dim; i++) {
309 // left band limit:
310 unsigned int left = (i>m.sub ? i-m.sub : 0);
311 // right band limit:
312 unsigned int right = MIN(i+m.super+1,m.dim);
313 T sum(0.0);
314 for (unsigned int j=left; j<right; j++)
315 sum += m.comp[(m.super+i-j)+j*(m.super+m.sub+1)] * v(j);
316 res.set(sum,i);
317 }
318 return res; // JENS: avoid copy constructor soon!
319}
320
321template <typename T>
323{
324 return do_fbdmat_vec_mul(m, v);
325}
326
327
328template <typename T>
330{
331 Vector<T> v(tv);
332 return do_fbdmat_vec_mul(m, v);
333}
334
335// could be optimized ...
336template <typename T>
338{
339 Vector<T> v(tsv);
340 return do_fbdmat_vec_mul(m, v);
341}
342
343// transpose-vector multiplication
344template <typename T>
346{
348 BCHK(dim != v.size(), F_BandMatErr, Dimension conflict, v.size(), res);
349 for (unsigned int j=0; j<dim; j++)
350 {
351 // transpose left band limit:
352 unsigned int left = (j>super ? j-super : 0);
353 // transpose right band limit:
354 unsigned int right = MIN(j+sub+1,dim);
355 T sum(0.0);
356 for (unsigned int i=left; i<right; i++)
357 sum += comp[(super+i-j)+j*(super+sub+1)] * v(i);
358 res.set(sum,j);
359 }
360 return res; // JENS: avoid copy constructor soon!
361}
362
363template <typename T>
365{
366 Vector<T> v(tv);
367 return(this->transMult(v));
368}
369
370// Could be optimized ...
371template <typename T>
373{
374 Vector<T> v(tsv);
375 return(this->transMult(v));
376}
377
378// matrix-scalar multiplication
379template <typename T>
381{
383 for (unsigned int j=0; j<(m.dim*(m.super+m.sub+1)); ++j)
384 res.comp[j] = m.comp[j] * z;
385 return res; // JENS: avoid copy constructor soon!
386}
387
388
389// matrix-scalar multiplication
390template <typename T>
392{
394 for (unsigned int j=0; j<(m.dim*(m.super+m.sub+1)); ++j)
395 res.comp[j] = z * m.comp[j];
396 return res; // JENS: avoid copy constructor soon!
397}
398
399template <typename T>
401{
402 return do_fbdmat_scale(m, z);
403}
404
405template <typename T>
407{
408 return do_fbdmat_scale(z, m);
409}
410
411// fast in-place matrix-scalar multiplication
412template <typename T>
414{
415 for (unsigned int j=0; j<(dim*(super+sub+1)); ++j)
416 comp[j] *= z;
417 return *this;
418}
419
420
421// matrix-scalar division
422template <typename T>
424{
426 for (unsigned int j=0; j<(m.dim*(m.super+m.sub+1)); ++j)
427 res.comp[j] = m.comp[j] / z;
428 return res; // JENS: avoid copy constructor soon!
429}
430
431// fast in-place matrix-scalar division
432template <typename T>
434{
435 for (unsigned int j=0; j<(dim*(super+sub+1)); ++j)
436 comp[j] /= z;
437 return *this;
438}
439
440
442template <typename T>
444{
445 for (super = dim-1; super > 0; --super)
446 for (unsigned r = 0; r < dim-super; ++r)
447 if (m(r, r+super) != (T)0)
448 return;
449}
450
452template <typename T>
454{
455 for (sub = dim-1; sub > 0; --sub)
456 for (unsigned c = 0; c < dim-sub; ++c)
457 if (m(c+sub, c) != (T)0)
458 return;
459}
460
461template <typename T>
463{
464 BCHKNR(m.rows() != m.columns(), F_BandMatErr, only square matrices possible, m.rows());
465 dim = m.rows();
466 this->find_super(m); this->find_sub(m);
467 // Allocate and copy
468 this->allocate(dim, super, sub);
469 for (unsigned r = 0; r < dim; ++r)
470 for (unsigned c = MAX(0, (int)(r-sub));
471 c < MIN(dim, r+super+1); ++c)
472 (*this)(r,c) = m(r,c);
473}
474
475#ifndef LAPACK_INLINE
476# define LAPACK_INLINE
477#endif
478// allocate memory space
479// used by constructor and redim()
480template <typename T>
481LAPACK_INLINE void F_BandMatrix<T>::allocate(unsigned int dimension,
482 unsigned int superDiags,
483 unsigned int subDiags)
484{
485 BCHKNR(dimension == 0, F_BandMatErr, Zero space allocating, 0);
486 BCHKNR(superDiags >= dimension || subDiags >= dimension, F_BandMatErr, Dimension conflict, (subDiags<superDiags? subDiags : superDiags));
487 dim = dimension;
488 super = superDiags;
489 sub = subDiags;
490 unsigned int colSize = super + sub + 1;
491 comp = new T[colSize*dim];
492 BCHKNR(comp==NULL, F_BandMatErr, Out of memory, colSize*dim);
493// for(int i=0; i<(colSize*dim); i++) comp[i] = NULL;
494}
495
496// delete memory space
497// used by "=" operator and destructor
498template <typename T>
500{
501 if (comp != NULL)
502 delete[] comp;
503}
504
505// copy to new memory space
506// used by "=" operator and copy constructor
507template <typename T>
509{
510 dim = m.dim;
511 super = m.super;
512 sub = m.sub;
513 unsigned int colSize = super + sub + 1;
514 comp = new T[colSize*dim];
515 BCHKNR(comp==NULL, F_BandMatErr, Out of memory, colSize*dim);
516 CSTD__ memcpy(comp, m.comp, sizeof(T)*(dim*colSize));
517}
518
519
520// matrix addition and subtraction
521template <typename T>
523{
524 unsigned int numSub(0),numSuper(0),dim(0);
525 // calculate the dimations of C
526 dim = MAX(A.size(), B.size());
527 numSuper = MAX(A.numSuper(), B.numSuper());
528 numSub = MAX(A.numSub(), B.numSub());
529
530 // create C and full C
531 F_BandMatrix<T> C(dim,numSuper,numSub);
532
533 BCHK(A.size()!=B.size(), F_BandMatErr, Dimension conflict, A.size(), C );
534
535 for(unsigned int i(0);i<C.size();i++)
536 {
537 for(int j(i-C.numSub());j<=(int)(i+C.numSuper());j++)
538 {
539 if((j>=0)&&(j<(int)C.size()))
540 {
541 if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper()))
542 && (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
543 C(i,j)=A(i,j)+B(i,j);
544 else if( (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
545 C(i,j)=B(i,j);
546 else if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper())) )
547 C(i,j)=A(i,j);
548 }
549 }
550 }
551 return C;
552}
553
554template <typename T>
556{
557 // calculate the dimensions of C
558 const unsigned dim = MAX(A.size(), B.size());
559 const unsigned numSuper = MAX(A.numSuper(), B.numSuper());
560 const unsigned numSub = MAX(A.numSub(), B.numSub());
561
562 // create C and fill C
563 F_BandMatrix<T> C(dim, numSuper, numSub);
564
565 BCHK(A.size()!=B.size(), F_BandMatErr, Dimension conflict, A.size(), C );
566
567 for(unsigned int i(0);i<C.size();i++)
568 {
569 for(int j(i-C.numSub());j<=(int)(i+C.numSuper());j++)
570 {
571 if((j>=0)&&(j<(int)C.size()))
572 {
573 if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper()))
574 && (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
575 C(i,j)=A(i,j)-B(i,j);
576 else if( (j>=(int)(i-B.numSub())) && (j<=(int)(i+B.numSuper())) )
577 C(i,j)=-B(i,j);
578 else if( (j>=(int)(i-A.numSub())) && (j<=(int)(i+A.numSuper())) )
579 C(i,j)=A(i,j);
580 }
581 }
582 }
583 return C;
584}
585
586template <typename T>
587STD__ ostream& operator<< (STD__ ostream& stream, const F_BandMatrix<T>& m)
588{
589 for (unsigned int i = 0; i < m.rows(); i++)
590 {
591 for (unsigned int j = 0; j < m.columns(); j++)
592 stream << m(i,j) << " ";
593 stream << STD__ endl;
594 }
595 return stream;
596}
597
598
599template <typename T>
601{
602 for (unsigned int j=0; j<(dim*(super+sub+1)); j++)
603 comp[j] = (T) 0;
604}
605
606
607template <typename T>
609{
611 for (unsigned int r = 0; r < dim; ++r)
612 for (unsigned int c = MAX(0, (int)(r-super));
613 c < MIN(dim, r+sub+1); ++c)
614 f(r,c) = (*this)(c,r);
615 return f;
616}
617
618template <typename T>
620{
622 return swap(tr);
623}
624
625
626INST(template <typename T> class F_BandMatrix friend F_BandMatrix<T> transpose(const F_BandMatrix<T>& fbd);)
627template <typename T>
629{
630 return fbd.transposed_copy();
631}
632
633template <typename T>
635{
636 SWAP(dim, m.dim);
637 SWAP(super, m.super); SWAP(sub, m.sub);
638 SWAP(comp, m.comp);
639 return *this;
640}
641
643
644#endif /* TBCI_F_BANDMATRIX_H */
long int Vector< T > & index
Definition LM_fit.h:69
int i
Definition LM_fit.h:71
#define NULL
Definition basics.h:250
#define CSTD__
Definition basics.h:340
#define STD__
Definition basics.h:338
#define BCHK(cond, exc, txt, ind, rtval)
Definition basics.h:575
#define MIN(a, b)
Definition basics.h:655
#define MIN_ALIGN2
Definition basics.h:424
#define NAMESPACE_END
Definition basics.h:323
#define INST(x)
Definition basics.h:238
#define NAMESPACE_TBCI
Definition basics.h:317
#define BCHKNR(cond, exc, txt, ind)
Definition basics.h:586
#define MAX(a, b)
Definition basics.h:656
#define FGD
Definition basics.h:144
#define T
Definition bdmatlib.cc:20
F_BandMatErr(const char *t, const long i=0)
C++ class for banded matrices using band storage in a one-dimensional array.
void allocate(unsigned int dimension, unsigned int superDiags, unsigned int subDiags)
TVector< T > transMult(const Vector< T > &v) const
F_BandMatrix< T > & transpose()
transpose() does change the object!
F_BandMatrix< T > & operator=(const F_BandMatrix< T > &m)
unsigned int sub
T aligned_value_type TALIGN(MIN_ALIGN2)
unsigned int dim
T & setval(unsigned r, unsigned c)
F_BandMatrix< T > transposed_copy() const
friend TVector< T > do_fbdmat_vec_mul FGD(const F_BandMatrix< T > &m, const Vector< T > &v)
unsigned int columns() const
unsigned int super
F_BandMatrix< T > & swap(F_BandMatrix< T > &m)
unsigned int ldab() const
friend F_BandMatrix< T > do_fbdmat_scale FGD(const F_BandMatrix< T > &m, const T z)
T operator()(unsigned int row, unsigned int column) const
void copy(const F_BandMatrix< T > &m)
F_BandMatrix< T > & operator*=(const T z)
T *const & get_fortran_matrix() const
F_BandMatrix(const F_BandMatrix< T > &m)
F_BandMatrix< T > & operator/=(const T z)
unsigned int numSub() const
F_BandMatrix(unsigned int dimension, unsigned int superDiags=0, unsigned int subDiags=0)
void find_sub(const Matrix< T > &m)
Find number of sub diagonals.
void set_col(const Vector< T > &v, unsigned int column)
unsigned int rows() const
void find_super(const Matrix< T > &m)
Find number of super diagonals.
void resize(unsigned int newDim, unsigned int newSuper, unsigned int newSub)
friend F_BandMatrix< T > do_fbdmat_scale FGD(const T z, const F_BandMatrix< T > &m)
unsigned int numSuper() const
unsigned int size() const
void setval(const T z, unsigned int row, unsigned int column)
TVector< T > get_col(unsigned int column) const
NumErr()
Definition except.h:65
unsigned int rows() const
number of rows
Definition matrix.h:317
unsigned int columns() const
number of columns
Definition matrix.h:315
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition vector.h:73
unsigned long size() const
Definition vector.h:104
T & set(const T &val, const unsigned long i) const
Definition vector.h:194
TVector< T > operator*(const F_BandMatrix< T > &m, const Vector< T > &v)
TVector< T > do_fbdmat_vec_mul(const F_BandMatrix< T > &m, const Vector< T > &v)
F_BandMatrix< T > do_fbdmat_scale(const F_BandMatrix< T > &m, const T z)
F_BandMatrix< T > operator-(const F_BandMatrix< T > &m)
bool operator==(const F_BandMatrix< T > &m1, const F_BandMatrix< T > &m2)
F_BandMatrix< T > transpose(const F_BandMatrix< T > &fbd)
bool operator!=(const F_BandMatrix< T > &m1, const F_BandMatrix< T > &m2)
STD__ ostream & operator<<(STD__ ostream &stream, const F_BandMatrix< T > &m)
#define LAPACK_INLINE
F_BandMatrix< T > operator+(const F_BandMatrix< T > &A, const F_BandMatrix< T > &B)
F_BandMatrix< T > operator/(const F_BandMatrix< T > &m, const T z)
return c
Definition f_matrix.h:760
T sum(const FS_Vector< dims, T > &fv)
Definition fs_vector.h:599
const unsigned TMatrix< T > * res
#define right