Toast++  1.0.2 (r.539)
Forward and inverse modelling in optical tomography
symatrix.h
1 // -*-C++-*-
2 // ==========================================================================
3 // Module mathlib Martin Schweiger - 23.5.96
4 // File symatrix.h
5 // Declaration of template class TSymMatrix ('template symmetric matrix')
6 //
7 // The following typedefs for specific template types have been defined
8 // for convenience:
9 // RSymMatrix = TSymMatrix<double> ('real')
10 // FSymMatrix = TSymMatrix<float> ('float')
11 // CSymMatrix = TSymMatrix<complex> ('complex')
12 // ISymMatrix = TSymMatrix<int> ('integer')
13 // SymMatrix = TSymMatrix<double> for backward compatibility
14 //
15 // Inheritance:
16 // ------------
17 // TMatrix ----> TSymMatrix
18 //
19 // Note:
20 // -----
21 // TSymMatrix is derived from TMatrix rather than TSquareMatrix because
22 // the data structure is different, so inheriting functionality from the
23 // TMatrix branch would be a problem.
24 // TSymMatrix only stores the lower left triangle of the matrix.
25 // ==========================================================================
26 
27 #ifndef __SYMATRIX_H
28 #define __SYMATRIX_H
29 
30 #include "matrix.h"
31 
32 // ==========================================================================
33 // Nonmember declarations
34 
35 template<class MT> class TSymMatrix;
36 
37 template<class MT>
38 bool CHdecomp (TSymMatrix<MT> &a, bool recover = false);
39 
40 template<class MT>
41 TVector<MT> CHsubst (const TSymMatrix<MT> &a, const TVector<MT> &b);
42 
43 // ==========================================================================
44 // class TSymMatrix
45 
46 template<class MT> class TSymMatrix: public TMatrix<MT> {
47 public:
48  TSymMatrix (): TMatrix<MT> ()
49  { nz = 0; }
50  // Create a 0 x 0 matrix
51 
52  TSymMatrix (int r, int c): TMatrix<MT> (r, c) {
53  dASSERT(r==c, "Symmetric matrix must be square");
54  Alloc(r); Zero();
55  }
56  // Create r x c matrix filled with 0's
57  // r == c is required
58 
59  TSymMatrix (int n): TMatrix<MT> (n, n)
60  { Alloc(n); Zero(); }
61  // Create n x n matrix filled with 0's
62 
63  TSymMatrix (const TSymMatrix<MT> &m): TMatrix<MT> (m)
64  { Alloc (m.rows); memcpy (val, m.val, nz*sizeof(MT)); }
65  // Create a copy of m
66 
67  TSymMatrix (int n, const char *valstr);
68  // Create n x n symmetric matrix and initialise from string which contains
69  // values for lower triangle in row order
70 
71  ~TSymMatrix () { Unlink (); }
72  // Destructor
73 
74  MatrixStorage StorageType() const { return MATRIX_SYM; }
75  // Matrix element storage method
76 
77  inline void New (int r, int c) {
78  dASSERT(r==c, "Symmetric matrix must be square");
79  New_dirty(r); Zero();
80  }
81  // Resize matrix and zero all elements
82  // obsolete, use Zero(r,c) instead
83 
84  inline void Zero () { memset (val, 0, nz*sizeof(MT)); }
85  // Zero all elements
86 
87  inline void Zero (int n) { New_dirty(n); Zero(); }
88  // Resize to n x n square matrix and zero all elements
89 
90  inline void Zero (int r, int c) {
91  dASSERT(r==c, "Symmetric matrix must be square");
92  New_dirty(r); Zero();
93  }
94  // Resize to r x c matrix and zero all elements. r==c is required
95 
96  void Identity ();
97  // Set diagonal elements to 1, all others to 0
98  // only valid for template types which can cast (MT)1
99 
100  inline void Identity (int n) { New_dirty(n); Identity(); }
101  // Resize to n x n square matrix and set to identity
102 
103  inline void Identity (int r, int c) {
104  dASSERT(r==c, "Symmetric matrix must be square");
105  New_dirty(r); Identity();
106  }
107  // Resize to r x c matrix and set to identity. r==c is required
108 
109  inline MT Get (int r, int c) const {
110  dASSERT (r >= 0 && r < this->rows && c >= 0 && c < this->cols,
111  "Index out of range");
112  return val[Idx(r,c)];
113  }
114  // Retrieve value of an element
115 
116  inline const MT operator() (int r, int c) const {
117  dASSERT (r >= 0 && r < this->rows && c >= 0 && c < this->cols,
118  "Index out of range");
119  return val[Idx(r,c)];
120  }
121  // Retrieve value of an element (alternative syntax to 'Get')
122 
123  inline MT &operator() (int r, int c) {
124  dASSERT (r >= 0 && r < this->rows && c >= 0 && c < this->cols,
125  "Index out of range");
126  return val[Idx(r,c)];
127  }
128  // Retrieve reference to element
129 
130  inline TSymMatrix<MT> &operator*= (MT f)
131  { for (int i = 0; i < nz; i++) val[i] *= f; return *this; }
132 
133  inline TSymMatrix<MT> &operator/= (MT f)
134  { for (int i = 0; i < nz; i++) val[i] /= f; return *this; }
135 
136  TVector<MT> Row (int r) const;
137  // Retrieve a row
138 
139  inline TVector<MT> Col (int c) const { return Row(c); }
140  // Retrieve a column. Identical to Row(c) since symmetric
141 
142  int SparseRow (int r, idxtype *ci, MT *rv) const;
143  // See TMatrix
144 
145  void ColScale (const TVector<MT> &scale);
146  // scales the columns with 'scale'
147 
148  void RowScale (const TVector<MT> &scale);
149  // scales the rows with 'scale'
150 
151  void AddDiag (const TVector<MT> &d);
152  // adds vector d to diagonal of *this
153 
154  void AddDiag (const MT &d);
155  // adds 'd' to all diagonal elements
156 
157  void Ax (const TVector<MT> &x, TVector<MT> &b) const;
158  // Matrix x Vector multiplication: b = Ax
159 
160  inline void ATx (const TVector<MT> &x, TVector<MT> &b) const
161  { return Ax(x,b); }
162  // b = transpose(A) * x = Ax (since symmetric)
163 
164  TSymMatrix<MT> &operator= (const TSymMatrix<MT> &m);
165  // *this = m
166 
167  TSymMatrix<MT> &operator= (const MT &mt);
168  // *this[i] = mt for all i
169 
170  TSymMatrix<MT> operator+ (const TSymMatrix<MT> &m) const;
171  // *this + m
172 
173  TSymMatrix<MT> operator- (const TSymMatrix<MT> &m) const;
174  // *this - m
175 
176  TSymMatrix<MT> &operator+= (const TSymMatrix<MT> &m) {
177  dASSERT(this->rows == m.rows, "Matrices have different size");
178  for (int i = 0; i < nz; i++) val[i] += m.val[i];
179  return *this;
180  }
181  // *this = *this + m
182 
183  TSymMatrix<MT> &operator-= (const TSymMatrix<MT> &m) {
184  dASSERT(this->rows == m.rows, "Matrices have different size");
185  for (int i = 0; i < nz; i++) val[i] -= m.val[i];
186  return *this;
187  }
188  // *this = *this - m
189 
190  TSymMatrix<MT> operator* (const MT &mt) const;
191  // *this * mt
192 
193  TVector<MT> operator* (const TVector<MT> &x) const;
194  // matrix * vector operation
195 
196  // **** friends ****
197 
198  friend bool CHdecomp<> (TSymMatrix<MT> &a, bool recover);
199  // replaces `a' with its Choleski decomposition
200 
201  friend TVector<MT> CHsubst<> (const TSymMatrix<MT> &a,
202  const TVector<MT> &b);
203 
204  MT *data_buffer() { return val; }
205  const MT *data_buffer() const { return val; }
206 
207 protected:
208  MT *val; // data array (row vectors for lower triangle)
209  int nz; // length of data vector: nz = n*(n+1)/2
210 
211  inline int Idx (int r, int c) const
212  { return (r >= c ? c + ((r*(r+1)) >> 1) : r + ((c*(c+1)) >> 1)); }
213  // data array index for element (r,c)
214 
215 private:
216  inline void Alloc (int n) { if (n) val = new MT[nz = (n*(n+1))/2]; }
217  // allocate data array
218 
219  inline void Unlink () { if (nz) delete[]val, nz = 0; }
220  // deallocate data array
221 
222  void New_dirty (int n);
223  // This version of new leaves the elements undefined and is slightly
224  // faster than 'New'. It should only be used where initialisation
225  // follows immediately
226 };
227 
228 
229 // ==========================================================================
230 // typedefs for specific instances of `TSymMatrix'
231 
232 typedef TSymMatrix<double> RSymMatrix; // 'real'
233 typedef TSymMatrix<float> FSymMatrix; // 'float'
234 typedef TSymMatrix<std::complex<double> > CSymMatrix; // 'complex'
235 typedef TSymMatrix<std::complex<float> > SCSymMatrix; // 'single complex'
236 typedef TSymMatrix<int> ISymMatrix; // 'integer'
237 
238 // ==========================================================================
239 // extern declarations of TSymMatrix (only required for VS)
240 
241 #ifndef __SYMATRIX_CC
242 //extern template class MATHLIB TSymMatrix<double>;
243 //extern template class MATHLIB TSymMatrix<float>;
244 //extern template class MATHLIB TSymMatrix<toast::complex>;
245 //extern template class MATHLIB TSymMatrix<scomplex>;
246 //extern template class MATHLIB TSymMatrix<int>;
247 #endif // !__SYMATRIX_CC
248 
249 #endif // !__SYMATRIX_H
Definition: dnsmatrix.h:17
TVector< MT > Row(int r) const
Returns a vector containing a copy of row `r'.
int SparseRow(int r, idxtype *ci, MT *rv) const
Returns a row of the matrix in sparse format.
MatrixStorage StorageType() const
Matrix storage class.
Definition: symatrix.h:74
MT Get(int r, int c) const
Retrieve a matrix element.
Definition: symatrix.h:109
TVector< MT > Col(int c) const
Returns a vector containing a copy of column 'c'.
Definition: symatrix.h:139
MatrixStorage
Definition: matrix.h:20
void New(int r, int c)
Resize and reset the matrix.
Definition: symatrix.h:77
Virtual base class for all matrix types (dense and sparse)
Definition: matrix.h:43
store lower triangle + diagonal of symmetric matrix
Definition: matrix.h:22