Toast++  1.0.2 (r.539)
Forward and inverse modelling in optical tomography
dnsmatrix.h
1 // -*-C++-*-
2 // ============================================================================
3 // General dense matrix class
4 // ============================================================================
5 
6 #ifndef __DNSMATRIX_H
7 #define __DNSMATRIX_H
8 
9 #include "toastdef.h"
10 #include <string.h>
11 #include "vector.h"
12 #include "matrix.h"
13 
14 // ==========================================================================
15 // Nonmember declarations
16 
17 template<class MT> class TSymMatrix;
18 template<class MT> class TDenseMatrix;
19 template<class MT> class TCompRowMatrix;
20 
21 template<class MT>
22 TDenseMatrix<MT> transpose (const TDenseMatrix<MT> &A);
23 
24 template<class MT>
26  const TDenseMatrix<MT> &B);
27 
28 template<class MT>
30  const TDenseMatrix<MT> &B);
31 
32 template<class MT>
34 
35 template<class MT>
36 TSymMatrix<MT> AAT (const TDenseMatrix<MT> &A);
37 
38 template<class MT>
39 TDenseMatrix<MT> kron (const TDenseMatrix<MT> &A, const TDenseMatrix<MT> &B);
40 
41 template<class MT>
42 MT det (const TDenseMatrix<MT> &A, TDenseMatrix<MT> *Ai = 0);
43 
44 template<class MT>
45 TDenseMatrix<MT> inverse (const TDenseMatrix<MT> &A);
46 
47 template<class MT>
48 int QRFactorize (TDenseMatrix<MT> &A, TVector<MT> &c, TVector<MT> &d);
49 
50 template<class MT>
51 void RSolve (const TDenseMatrix<MT> &A, const TVector<MT> &d,
52  TVector<MT> &b);
53 
54 template<class MT>
55 void QRSolve (const TDenseMatrix<MT> &A, const TVector<MT> &c,
56  const TVector<MT> &d, const TVector<MT> &b, TVector<MT> &x);
57 
58 template<class MT>
59 void LUFactorize (TDenseMatrix<MT> &a, IVector &indx, double &d);
60 
61 template<class MT>
62 void LUSolve (const TDenseMatrix<MT> &a, const IVector &indx, TVector<MT> &b);
63 
64 template<class MT>
65 std::istream &operator>> (std::istream &is, TDenseMatrix<MT> &m);
66 
67 template<class MT>
68 std::ostream &operator<< (std::ostream &os, const TDenseMatrix<MT> &m);
69 
70 // ==========================================================================
71 // class TDenseMatrix
72 // ==========================================================================
81 template<class MT> class TDenseMatrix: public TMatrix<MT> {
82 
83 public:
87  TDenseMatrix (): TMatrix<MT> ()
88  { rc = 0; }
89 
96  TDenseMatrix (int r, int c): TMatrix<MT> (r, c)
97  { Alloc (r,c); Zero(); }
98 
104  TDenseMatrix (int n): TMatrix<MT> (n, n)
105  { Alloc (n,n); Zero(); }
106 
112  { Alloc (m.rows, m.cols); memcpy (val, m.val, rc*sizeof(MT)); }
113 
128  TDenseMatrix (const TDenseMatrix<MT> &m, int i0, int j0, int i1, int j1);
129 
141  TDenseMatrix (int r, int c, MT *values): TMatrix<MT> (r, c)
142  { Alloc (r,c); memcpy (val, values, rc*sizeof(MT)); }
143 
153  TDenseMatrix (int r, int c, const char *valstr);
154 
162  TDenseMatrix (const TSymMatrix<MT> &A);
163 
168  TDenseMatrix (const TCompRowMatrix<MT> &A);
169 
173  ~TDenseMatrix () { Unlink(); }
174 
175  inline MatrixStorage StorageType () const { return MATRIX_DENSE; }
176  // Matrix element storage method
177 
178  inline void New (int r, int c) { New_dirty(r,c); Zero(); }
179  // Resize matrix and zero all elements
180  // obsolete, use Zero(r,c) instead
181 
182  inline void Zero () { memset (val, 0, rc*sizeof(MT)); }
183  // Zero all elements
184 
185  inline void Zero (int n) { New_dirty(n,n); Zero(); }
186  // Resize to n x n square matrix and zero all elements
187 
188  inline void Zero (int r, int c) { New_dirty(r,c); Zero(); }
189  // Resize to r x c matrix and zero all elements
190 
191  void Identity ();
192  // Set diagonal elements to 1, all others to 0
193  // only valid for template types which can cast (MT)1
194 
195  inline void Identity (int n) { New_dirty(n,n); Identity(); }
196  // Resize to n x n square matrix and set to identity
197 
198  inline void Identity (int r, int c) { New_dirty(r,c); Identity(); }
199  // Resize to r x c matrix and set to identity
200 
201  inline MT Get (int r, int c) const {
202  dASSERT (r >= 0 && r < this->rows && c >= 0 && c < this->cols,
203  "Index out of range");
204  return val[r*this->cols + c];
205  }
206  // Retrieve value of an element
207 
208  inline void Set (int r, int c, MT v) {
209  dASSERT (r >= 0 && r < this->rows && c >= 0 && c < this->cols,
210  "Index out of range");
211  val[r*this->cols + c] = v;
212  }
213  // Write value into element
214 
215  inline MT operator() (int r, int c) const {
216  return Get(r,c); }
217  // Retrieve value of an element (alternative syntax to 'Get')
218 
219  inline MT &operator() (int r, int c) {
220  dASSERT (r >= 0 && r < this->rows && c >= 0 && c < this->cols,
221  "Index out of range");
222  return val[r*this->cols + c];
223  }
224  // Retrieve reference to element
225 
226  inline MT *ValPtr() { return val; }
227  // Return pointer to data array
228 
229  inline TVector<MT> Row (int r) const {
230  dASSERT (r >= 0 && r < this->rows, "Index out of range");
231  return TVector<MT>(this->cols, val+r*this->cols);
232  }
233  // Retrieve a row
234 
235  TVector<MT> Col (int c) const;
236  // Retrieve a column
237 
238  int SparseRow (int r, idxtype *ci, MT *rv) const;
239 
240  void SetRow (int r, const TVector<MT> &rval);
241  // replace row 'r' of *this with 'rval'
242 
243  void ColScale (const TVector<MT> &scale);
244  // scales the columns with 'scale'
245 
246  void RowScale (const TVector<MT> &scale);
247  // scales the rows with 'scale'
248 
256  TVector<MT> RowSum() const;
257 
266  TVector<MT> RowSumSq() const;
267 
275  TVector<MT> ColSum() const;
276 
285  TVector<MT> ColSumSq() const;
286 
287  void Ax (const TVector<MT> &x, TVector<MT> &b) const;
288  // Matrix x Vector multiplication: b = Ax
289 
290  void ATx (const TVector<MT> &x, TVector<MT> &b) const;
291  // b = transpose(A) * x
292 
293  void AB (const TDenseMatrix<MT> &A, const TDenseMatrix<MT> &B);
294  // *this = AB
295 
296  MT colmult (int c1, int c2);
297  // inner product of columns c1 and c2
298 
299  TDenseMatrix<MT> &operator= (const TDenseMatrix<MT> &m);
300  // *this = m
301 
302  TDenseMatrix<MT> &operator= (MT v);
303  // *this = v
304 
305  TDenseMatrix<MT> operator+ (const TDenseMatrix<MT> &m) const;
306  // *this + m
307 
308  TDenseMatrix<MT> operator- (const TDenseMatrix<MT> &m) const;
309  // *this - m
310 
311  TDenseMatrix<MT> operator* (const TDenseMatrix<MT> &m) const
312  { TDenseMatrix<MT> tmp; tmp.AB(*this,m); return tmp; }
313  // *this * m
314 
315  inline TVector<MT> operator* (const TVector<MT> &x) const
316  { TVector<MT> b(this->rows); Ax (x, b); return b; }
317  // *this * x
318 
319  inline TDenseMatrix<MT> operator* (const MT &mt) const {
320  TDenseMatrix<MT> tmp(*this);
321  for (int i = 0; i < rc; i++) tmp.val[i] *= mt;
322  return tmp;
323  }
324  // scalar matrix multiplication
325 
326  inline TDenseMatrix<MT> operator/ (const MT &mt) const {
327  TDenseMatrix<MT> tmp(*this);
328  for (int i = 0; i < rc; i++) tmp.val[i] /= mt;
329  return tmp;
330  }
331  // scalar matrix division
332 
333  inline TDenseMatrix<MT> &operator*= (const MT &mt) {
334  for (int i = 0; i < rc; i++) val[i] *= mt;
335  return *this;
336  }
337  // scalar matrix multiplication on *this
338 
339  inline TDenseMatrix<MT> &operator/= (const MT &mt) {
340  return *this *= (MT)1 / mt;
341  }
342  // scalar matrix division on *this
343 
344  friend TDenseMatrix<MT> transpose<> (const TDenseMatrix<MT> &A);
345  // returns transpose(A)
346 
356  friend TDenseMatrix<MT> cath<> (const TDenseMatrix<MT> &A,
357  const TDenseMatrix<MT> &B);
358 
369  friend TDenseMatrix<MT> catv<> (const TDenseMatrix<MT> &A,
370  const TDenseMatrix<MT> &B);
371 
372  friend TSymMatrix<MT> ATA<> (const TDenseMatrix<MT> &A);
373  // returns transpose(A) * A
374 
375  friend TSymMatrix<MT> AAT<> (const TDenseMatrix<MT> &A);
376  // returns A * transpose(A)
377 
378  friend TDenseMatrix<MT> kron<> (const TDenseMatrix<MT> &A,
379  const TDenseMatrix<MT> &B);
380  // Kronecker matrix product
381 
382  friend MT det<> (const TDenseMatrix<MT> &A, TDenseMatrix<MT> *Ai);
383  // Returns the determinant of A. If Ai != 0 and order <= 3x3 then it
384  // is set to the inverse of A; this is more efficient than a separate
385  // call to 'inverse'
386 
387  friend TDenseMatrix<MT> inverse<> (const TDenseMatrix<MT> &A);
388  // uses LU decomposition for matrices > 3x3
389 
390  friend int QRFactorize<> (TDenseMatrix<MT> &A, TVector<MT> &c,
391  TVector<MT> &d);
392  // QR decomposition. Return value != 0 indicates singularity
393 
394  friend void RSolve<> (const TDenseMatrix<MT> &A, const TVector<MT> &d,
395  TVector<MT> &b);
396  // Solves set of linear equations Rx=b where R is upper triangular matrix
397  // stored in A and d. On return b is overwritten by the result x.
398 
399  friend void QRSolve<> (const TDenseMatrix<MT> &A, const TVector<MT> &c,
400  const TVector<MT> &d, const TVector<MT> &b, TVector<MT> &x);
401  // Solves set of linear equations Ax=b, where A, c and d are the result of
402  // a preceeding call to QRFactorize
403 
404  friend void LUFactorize<MT> (TDenseMatrix<MT> &a, IVector &indx,
405  double &d);
406  // Replaces a with its LU factorisation. On exit, indx contains the
407  // permutation vector from partial pivoting, and d = +/-1 depending on
408  // even/odd number of interchanges
409 
410  friend void LUSolve<MT> (const TDenseMatrix<MT> &a,
411  const IVector &indx, TVector<MT> &b);
412 
413  MT *data_buffer() { return val; }
414  const MT *data_buffer() const { return val; }
415 
416  friend std::istream &operator>> <> (std::istream &is, TDenseMatrix<MT> &m);
417  friend std::ostream &operator<< <> (std::ostream &os,
418  const TDenseMatrix<MT> &m);
419  // IO in generic format
420 
421 protected:
422  MT *val; // data array (row vectors)
423  int rc; // rows*cols = number of entries in data array
424 
425 private:
426  inline void Alloc (int r, int c) { if ((rc = r*c)) val = new MT[rc]; }
427  // allocate data array of length r*c
428 
429  inline void Unlink () { if (rc) delete []val, rc = 0; }
430  // deallocate data array
431 
432  void New_dirty (int r, int c);
433  // This version of New leaves the elements undefined and is slightly
434  // faster than 'New'. It should only be used where initialisation
435  // follows immediately
436 };
437 
438 // ==========================================================================
439 // typedefs for specific instances of `TDenseMatrix'
440 
441 typedef TDenseMatrix<double> RDenseMatrix; // 'double real'
442 typedef TDenseMatrix<float> FDenseMatrix; // 'single real'
443 typedef TDenseMatrix<std::complex<double> > CDenseMatrix; // 'complex'
444 typedef TDenseMatrix<std::complex<float> > SCDenseMatrix; // 'single complex'
445 typedef TDenseMatrix<int> IDenseMatrix; // 'integer'
446 
447 #ifndef MATHLIB_IMPLEMENTATION
448 //extern template class MATHLIB TDenseMatrix<double>;
449 //extern template class MATHLIB TDenseMatrix<float>;
450 //extern template class MATHLIB TDenseMatrix<toast::complex>;
451 //extern template class MATHLIB TDenseMatrix<scomplex>;
452 //extern template class MATHLIB TDenseMatrix<int>;
453 #endif // MATHLIB_IMPLEMENTATION
454 
455 #endif // !__DNSMATRIX_H
TDenseMatrix(int r, int c, MT *values)
Create a dense r x c matrix with a list of values.
Definition: dnsmatrix.h:141
MT Get(int r, int c) const
Retrieve a matrix element.
Definition: dnsmatrix.h:201
friend TSymMatrix< MT > ATA(const TMatrix< MT > &A)
Return transp(*this) * *this as a symmetric matrix.
Definition: matrix.h:516
Definition: dnsmatrix.h:17
TDenseMatrix(int n)
Create a dense square matrix of size n x n.
Definition: dnsmatrix.h:104
TDenseMatrix(int r, int c)
Create a dense matrix of size r x c.
Definition: dnsmatrix.h:96
TVector< MT > RowSumSq() const
Returns a vector of sum of squares for each row.
TDenseMatrix()
Create a dense matrix of size 0 x 0.
Definition: dnsmatrix.h:87
void SetRow(int r, const TVector< MT > &rval)
Substitute a row of the matrix.
MatrixStorage
Definition: matrix.h:20
friend TCompRowMatrix< MT > catv(const TCompRowMatrix< MT > &A, const TCompRowMatrix< MT > &B)
Concatenate two matrices vertically.
TVector< MT > ColSum() const
Returns a vector of column sums.
~TDenseMatrix()
Destructor. De-allocates the matrix.
Definition: dnsmatrix.h:173
TVector< MT > Col(int c) const
Returns a vector containing a copy of column 'c'.
Compressed-row sparse matrix class.
Definition: cdmatrix.h:27
TVector< MT > Row(int r) const
Returns a vector containing a copy of row `r'.
Definition: dnsmatrix.h:229
dense matrix storage
Definition: matrix.h:21
void New(int r, int c)
Resize and reset the matrix.
Definition: dnsmatrix.h:178
friend TCompRowMatrix< MT > cath(const TCompRowMatrix< MT > &A, const TCompRowMatrix< MT > &B)
Concatenate two matrices horizontally.
TVector< MT > ColSumSq() const
Returns a vector of sum of squares for each column.
Virtual base class for all matrix types (dense and sparse)
Definition: matrix.h:43
TDenseMatrix(const TDenseMatrix< MT > &m)
Create a dense matrix as a copy of another dense matrix.
Definition: dnsmatrix.h:111
Dense matrix class.
Definition: crmatrix.h:38
MatrixStorage StorageType() const
Matrix storage class.
Definition: dnsmatrix.h:175
TVector< MT > RowSum() const
Returns a vector of row sums.
int SparseRow(int r, idxtype *ci, MT *rv) const
Returns a row of the matrix in sparse format.