CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
Matrix.h
Go to the documentation of this file.
1// -*- C++ -*-
2// CLASSDOC OFF
3// ---------------------------------------------------------------------------
4// CLASSDOC ON
5//
6// This file is a part of the CLHEP - a Class Library for High Energy Physics.
7//
8// This is the definition of the HepMatrix class.
9//
10// This software written by Nobu Katayama and Mike Smyth, Cornell University.
11//
12//
13// .SS Usage
14// The Matrix class does all the obvious things, in all the obvious ways.
15// You declare a Matrix by saying
16//
17// .ft B
18// HepMatrix hm1(n, m);
19//
20// To declare a Matrix as a copy of a Matrix hm2, say
21//
22// .ft B
23// HepMatrix hm1(hm2);
24// or
25// .ft B
26// HepMatrix hm1 = hm2;
27//
28// You can declare initilizations of a Matrix, by giving it a third
29// integer argument, either 0 or 1. 0 means initialize to 0, one means
30// the identity matrix. If you do not give a third argument the memory
31// is not initialized.
32//
33// .ft B
34// HepMatrix hm1(n, m, 1);
35//
36// ./"This code has been written by Mike Smyth, and the algorithms used are
37// ./"described in the thesis "A Tracking Library for a Silicon Vertex Detector"
38// ./"(Mike Smyth, Cornell University, June 1993).
39// ./"This is file contains C++ stuff for doing things with Matrices.
40// ./"To turn on bound checking, define MATRIX_BOUND_CHECK before including
41// ./"this file.
42//
43// To find the number of rows or number of columns, say
44//
45// .ft B
46// nr = hm1.num_row();
47//
48// or
49//
50// .ft B
51// nc = hm1.num_col();
52//
53// You can print a Matrix by
54//
55// .ft B
56// cout << hm1;
57//
58// You can add,
59// subtract, and multiply two Matrices. You can multiply a Matrix by a
60// scalar, on the left or the right. +=, *=, -= act in the obvious way.
61// hm1 *= hm2 is as hm1 = hm1*hm2. You can also divide by a scalar on the
62// right, or use /= to do the same thing.
63//
64// You can read or write a Matrix element by saying
65//
66// .ft B
67// m(row, col) = blah. (1 <= row <= num_row(), 1 <= col <= num_col())
68//
69// .ft B
70// blah = m(row, col) ...
71//
72// m(row, col) is inline, and by default does not do bound checking.
73// If bound checking is desired, say #define MATRIX_BOUND_CHECK before
74// including matrix.h.
75//
76// You can also access the element using C subscripting operator []
77//
78// .ft B
79// m[row][col] = blah. (0 <= row < num_row(), 0 <= col < num_col())
80//
81// .ft B
82// blah = m[row][col] ...
83//
84// m[row][col] is inline, and by default does not do bound checking.
85// If bound checking is desired, say #define MATRIX_BOUND_CHECK before
86// including matrix.h. (Notice the difference in bases in two access
87// methods.)
88//
89// .SS Comments on precision
90//
91// The user would normally use "Matrix" class whose precision is the same
92// as the other classes of CLHEP (ThreeVec, for example). However, he/she
93// can explicitly choose Matrix (double) or MatrixF (float) if he/she wishes.
94// In the former case, include "Matrix.h." In the latter case, include either
95// "Matrix.h," or "MatrixF.h," or both. The only operators that can talk
96// to each other are the copy constructor and assignment operator.
97//
98// .ft B
99// Matrix d(3,4,HEP_MATRIX_IDENTITY);
100//
101// .ft B
102// MatrixF f;
103//
104// .ft B
105// f = d;
106//
107// .ft B
108// MatrixF g(d);
109//
110// will convert from one to the other.
111//
112// .SS Other functions
113//
114// .ft B
115// mt = m.T();
116//
117// returns the transpose of m.
118//
119// .ft B
120// ms = hm2.sub(row_min, row_max, col_min, col_max);
121//
122// returns the subMatrix.
123// hm2(row_min:row_max, col_min:col_max) in matlab terminology.
124// If instead you say
125//
126// .ft B
127// hm2.sub(row, col, hm1);
128//
129// then the subMatrix
130// hm2(row:row+hm1.num_row()-1, col:col+hm1.num_col()-1) is replaced with hm1.
131//
132// .ft B
133// md = dsum(hm1,hm2);
134//
135// returns the direct sum of the two matrices.
136//
137// Operations that do not have to be member functions or friends are listed
138// towards the end of this man page.
139//
140//
141// To invert a matrix, say
142//
143// .ft B
144// minv = m.inverse(ierr);
145//
146// ierr will be non-zero if the matrix is singular.
147//
148// If you can overwrite the matrix, you can use the invert function to avoid
149// two extra copies. Use
150//
151// .ft B
152// m.invert(ierr);
153//
154// Many basic linear algebra functions such as QR decomposition are defined.
155// In order to keep the header file a reasonable size, the functions are
156// defined in MatrixLinear.h.
157//
158//
159// .ft B
160// Note that Matrices run from (1,1) to (n, m), and [0][0] to
161// [n-1][m-1]. The users of the latter form should be careful about sub
162// functions.
163//
164// ./" The program that this class was orginally used with lots of small
165// ./" Matrices. It was very costly to malloc and free array space every
166// ./" time a Matrix is needed. So, a number of previously freed arrays are
167// ./" kept around, and when needed again one of these array is used. Right
168// ./" now, a set of piles of arrays with row <= row_max and col <= col_max
169// ./" are kept around. The piles of kept Matrices can be easily changed.
170// ./" Array mallocing and freeing are done only in new_m() and delete_m(),
171// ./" so these are the only routines that need to be rewritten.
172//
173// You can do things thinking of a Matrix as a list of numbers.
174//
175// .ft B
176// m = hm1.apply(HEP_MATRIX_ELEMENT (*f)(HEP_MATRIX_ELEMENT, int r, int c));
177//
178// applies f to every element of hm1 and places it in m.
179//
180// .SS See Also:
181// SymMatrix[DF].h, GenMatrix[DF].h, DiagMatrix[DF].h Vector[DF].h
182// MatrixLinear[DF].h
183
184#ifndef _Matrix_H_
185#define _Matrix_H_
186
187#include <vector>
188
189#include "CLHEP/Matrix/defs.h"
190#include "CLHEP/Matrix/GenMatrix.h"
191
192namespace CLHEP {
193
194class HepRandom;
195
196class HepSymMatrix;
197class HepDiagMatrix;
198class HepVector;
199class HepRotation;
200
201/**
202 * @author
203 * @ingroup matrix
204 */
205class HepMatrix : public HepGenMatrix {
206public:
207 inline HepMatrix();
208 // Default constructor. Gives 0 x 0 matrix. Another Matrix can be
209 // assigned to it.
210
211 HepMatrix(int p, int q);
212 // Constructor. Gives an unitialized p x q matrix.
213 HepMatrix(int p, int q, int i);
214 // Constructor. Gives an initialized p x q matrix.
215 // If i=0, it is initialized to all 0. If i=1, the diagonal elements
216 // are set to 1.0.
217
218 HepMatrix(int p, int q, HepRandom &r);
219 // Constructor with a Random object.
220
221 HepMatrix(const HepMatrix &hm1);
222 // Copy constructor.
223
224 HepMatrix(const HepSymMatrix &);
225 HepMatrix(const HepDiagMatrix &);
226 HepMatrix(const HepVector &);
227 // Constructors from SymMatrix, DiagMatrix and Vector.
228
229 virtual ~HepMatrix();
230 // Destructor.
231
232 virtual int num_row() const;
233 // Returns the number of rows.
234
235 virtual int num_col() const;
236 // Returns the number of columns.
237
238 virtual const double & operator()(int row, int col) const;
239 virtual double & operator()(int row, int col);
240 // Read or write a matrix element.
241 // ** Note that the indexing starts from (1,1). **
242
243 HepMatrix & operator *= (double t);
244 // Multiply a Matrix by a floating number.
245
246 HepMatrix & operator /= (double t);
247 // Divide a Matrix by a floating number.
248
249 HepMatrix & operator += ( const HepMatrix &);
252 HepMatrix & operator += ( const HepVector &);
253 HepMatrix & operator -= ( const HepMatrix &);
256 HepMatrix & operator -= ( const HepVector &);
257 // Add or subtract a Matrix.
258 // When adding/subtracting Vector, Matrix must have num_col of one.
259
260 HepMatrix & operator = ( const HepMatrix &);
263 HepMatrix & operator = ( const HepVector &);
265 // Assignment operators.
266
267 HepMatrix operator- () const;
268 // unary minus, ie. flip the sign of each element.
269
270 HepMatrix apply(double (*f)(double, int, int)) const;
271 // Apply a function to all elements of the matrix.
272
273 HepMatrix T() const;
274 // Returns the transpose of a Matrix.
275
276 HepMatrix sub(int min_row, int max_row, int min_col, int max_col) const;
277 // Returns a sub matrix of a Matrix.
278 // WARNING: rows and columns are numbered from 1
279 void sub(int row, int col, const HepMatrix &hm1);
280 // Sub matrix of this Matrix is replaced with hm1.
281 // WARNING: rows and columns are numbered from 1
282
283 friend inline void swap(HepMatrix &hm1, HepMatrix &hm2);
284 // Swap hm1 with hm2.
285
286 inline HepMatrix inverse(int& ierr) const;
287 // Invert a Matrix. Matrix must be square and is not changed.
288 // Returns ierr = 0 (zero) when successful, otherwise non-zero.
289
290 virtual void invert(int& ierr);
291 // Invert a Matrix. Matrix must be square.
292 // N.B. the contents of the matrix are replaced by the inverse.
293 // Returns ierr = 0 (zero) when successful, otherwise non-zero.
294 // This method has less overhead then inverse().
295
296 inline void invert();
297 // Invert a matrix. Throw std::runtime_error on failure.
298
299 inline HepMatrix inverse() const;
300 // Invert a matrix. Throw std::runtime_error on failure.
301
302
303 double determinant() const;
304 // calculate the determinant of the matrix.
305
306 double trace() const;
307 // calculate the trace of the matrix (sum of diagonal elements).
308
310 public:
312 double & operator[](int);
313 private:
314 HepMatrix& _a;
315 int _r;
316 };
318 public:
319 inline HepMatrix_row_const (const HepMatrix&,int);
320 const double & operator[](int) const;
321 private:
322 const HepMatrix& _a;
323 int _r;
324 };
325 // helper classes for implementing m[i][j]
326
328 inline const HepMatrix_row_const operator[] (int) const;
329 // Read or write a matrix element.
330 // While it may not look like it, you simply do m[i][j] to get an
331 // element.
332 // ** Note that the indexing starts from [0][0]. **
333
334protected:
335 virtual int num_size() const;
336 virtual void invertHaywood4(int& ierr);
337 virtual void invertHaywood5(int& ierr);
338 virtual void invertHaywood6(int& ierr);
339
340private:
341 friend class HepMatrix_row;
343 friend class HepVector;
344 friend class HepSymMatrix;
345 friend class HepDiagMatrix;
346 // Friend classes.
347
348 friend HepMatrix operator+(const HepMatrix &hm1, const HepMatrix &hm2);
349 friend HepMatrix operator-(const HepMatrix &hm1, const HepMatrix &hm2);
350 friend HepMatrix operator*(const HepMatrix &hm1, const HepMatrix &hm2);
351 friend HepMatrix operator*(const HepMatrix &hm1, const HepSymMatrix &hm2);
352 friend HepMatrix operator*(const HepMatrix &hm1, const HepDiagMatrix &hm2);
353 friend HepMatrix operator*(const HepSymMatrix &hm1, const HepMatrix &hm2);
354 friend HepMatrix operator*(const HepDiagMatrix &hm1, const HepMatrix &hm2);
355 friend HepMatrix operator*(const HepVector &hm1, const HepMatrix &hm2);
356 friend HepVector operator*(const HepMatrix &hm1, const HepVector &hm2);
357 friend HepMatrix operator*(const HepSymMatrix &hm1, const HepSymMatrix &hm2);
358 // Multiply a Matrix by a Matrix or Vector.
359
360 friend HepVector solve(const HepMatrix &, const HepVector &);
361 // solve the system of linear eq
362 friend HepVector qr_solve(HepMatrix *, const HepVector &);
363 friend HepMatrix qr_solve(HepMatrix *, const HepMatrix &b);
364 friend void tridiagonal(HepSymMatrix *a,HepMatrix *hsm);
365 friend void row_house(HepMatrix *,const HepMatrix &, double,
366 int, int, int, int);
367 friend void row_house(HepMatrix *,const HepVector &, double,
368 int, int);
369 friend void back_solve(const HepMatrix &R, HepVector *b);
370 friend void back_solve(const HepMatrix &R, HepMatrix *b);
371 friend void col_givens(HepMatrix *A, double c,
372 double s, int k1, int k2,
373 int rowmin, int rowmax);
374 // Does a column Givens update.
375 friend void row_givens(HepMatrix *A, double c,
376 double s, int k1, int k2,
377 int colmin, int colmax);
378 friend void col_house(HepMatrix *,const HepMatrix &, double,
379 int, int, int, int);
380 friend HepVector house(const HepMatrix &a,int row,int col);
381 friend void house_with_update(HepMatrix *a,int row,int col);
382 friend void house_with_update(HepMatrix *a,HepMatrix *v,int row,int col);
383 friend void house_with_update2(HepSymMatrix *a,HepMatrix *v,
384 int row,int col);
385
386 int dfact_matrix(double &det, int *ir);
387 // factorize the matrix. If successful, the return code is 0. On
388 // return, det is the determinant and ir[] is row-interchange
389 // matrix. See CERNLIB's DFACT routine.
390
391 int dfinv_matrix(int *ir);
392 // invert the matrix. See CERNLIB DFINV.
393
394#ifdef DISABLE_ALLOC
395 std::vector<double > m;
396#else
397 std::vector<double,Alloc<double,25> > m;
398#endif
399 int nrow, ncol;
400 int size_;
401};
402
403// Operations other than member functions for Matrix
404// implemented in Matrix.cc and Matrix.icc (inline).
405
406HepMatrix operator*(const HepMatrix &, const HepMatrix &);
407HepMatrix operator*(double t, const HepMatrix &);
408HepMatrix operator*(const HepMatrix &, double );
409// Multiplication operators
410// Note that m *= hm1 is always faster than m = m * hm1.
411
412HepMatrix operator/(const HepMatrix &, double );
413// m = hm1 / t. (m /= t is faster if you can use it.)
414
415HepMatrix operator+(const HepMatrix &hm1, const HepMatrix &hm2);
416// m = hm1 + hm2;
417// Note that m += hm1 is always faster than m = m + hm1.
418
419HepMatrix operator-(const HepMatrix &hm1, const HepMatrix &hm2);
420// m = hm1 - hm2;
421// Note that m -= hm1 is always faster than m = m - hm1.
422
423HepMatrix dsum(const HepMatrix&, const HepMatrix&);
424// Direct sum of two matrices. The direct sum of A and B is the matrix
425// A 0
426// 0 B
427
428HepVector solve(const HepMatrix &, const HepVector &);
429// solve the system of linear equations using LU decomposition.
430
431std::ostream& operator<<(std::ostream &s, const HepMatrix &q);
432// Read in, write out Matrix into a stream.
433
434//
435// Specialized linear algebra functions
436//
437
438HepVector qr_solve(const HepMatrix &A, const HepVector &b);
440HepMatrix qr_solve(const HepMatrix &A, const HepMatrix &b);
442// Works like backsolve, except matrix does not need to be upper
443// triangular. For nonsquare matrix, it solves in the least square sense.
444
447// Finds the inverse of a matrix using QR decomposition. Note, often what
448// you really want is solve or backsolve, they can be much quicker than
449// inverse in many calculations.
450
451
452void qr_decomp(HepMatrix *A, HepMatrix *hsm);
454// Does a QR decomposition of a matrix.
455
456void back_solve(const HepMatrix &R, HepVector *b);
457void back_solve(const HepMatrix &R, HepMatrix *b);
458// Solves R*x = b where R is upper triangular. Also has a variation that
459// solves a number of equations of this form in one step, where b is a matrix
460// with each column a different vector. See also solve.
461
462void col_house(HepMatrix *a, const HepMatrix &v, double vnormsq,
463 int row, int col, int row_start, int col_start);
464void col_house(HepMatrix *a, const HepMatrix &v, int row, int col,
465 int row_start, int col_start);
466// Does a column Householder update.
467
468void col_givens(HepMatrix *A, double c, double s,
469 int k1, int k2, int row_min=1, int row_max=0);
470// do a column Givens update
471
472void row_givens(HepMatrix *A, double c, double s,
473 int k1, int k2, int col_min=1, int col_max=0);
474// do a row Givens update
475
476void givens(double a, double b, double *c, double *s);
477// algorithm 5.1.5 in Golub and Van Loan
478
479HepVector house(const HepMatrix &a, int row=1, int col=1);
480// Returns a Householder vector to zero elements.
481
482void house_with_update(HepMatrix *a, int row=1, int col=1);
483void house_with_update(HepMatrix *a, HepMatrix *v, int row=1, int col=1);
484// Finds and does Householder reflection on matrix.
485
486void row_house(HepMatrix *a, const HepVector &v, double vnormsq,
487 int row=1, int col=1);
488void row_house(HepMatrix *a, const HepMatrix &v, double vnormsq,
489 int row, int col, int row_start, int col_start);
490void row_house(HepMatrix *a, const HepMatrix &v, int row, int col,
491 int row_start, int col_start);
492// Does a row Householder update.
493
494} // namespace CLHEP
495
496#ifdef ENABLE_BACKWARDS_COMPATIBILITY
497// backwards compatibility will be enabled ONLY in CLHEP 1.9
498using namespace CLHEP;
499#endif
500
501#ifndef HEP_DEBUG_INLINE
502#include "CLHEP/Matrix/Matrix.icc"
503#endif
504
505#endif /*_Matrix_H*/
HepMatrix_row_const(const HepMatrix &, int)
const double & operator[](int) const
HepMatrix_row(HepMatrix &, int)
friend HepVector house(const HepMatrix &a, int row, int col)
friend void house_with_update2(HepSymMatrix *a, HepMatrix *v, int row, int col)
virtual ~HepMatrix()
Definition: Matrix.cc:106
friend HepMatrix operator+(const HepMatrix &hm1, const HepMatrix &hm2)
Definition: Matrix.cc:276
virtual void invertHaywood4(int &ierr)
HepMatrix sub(int min_row, int max_row, int min_col, int max_col) const
Definition: Matrix.cc:193
HepMatrix & operator=(const HepMatrix &)
Definition: Matrix.cc:415
friend void row_house(HepMatrix *, const HepMatrix &, double, int, int, int, int)
friend void tridiagonal(HepSymMatrix *a, HepMatrix *hsm)
friend HepVector solve(const HepMatrix &, const HepVector &)
Definition: Vector.cc:575
HepMatrix apply(double(*f)(double, int, int)) const
Definition: Matrix.cc:474
friend void col_givens(HepMatrix *A, double c, double s, int k1, int k2, int rowmin, int rowmax)
virtual int num_col() const
Definition: Matrix.cc:120
virtual const double & operator()(int row, int col) const
Definition: Matrix.cc:135
HepMatrix & operator/=(double t)
Definition: Matrix.cc:403
virtual int num_row() const
Definition: Matrix.cc:118
friend void row_givens(HepMatrix *A, double c, double s, int k1, int k2, int colmin, int colmax)
HepMatrix & operator+=(const HepMatrix &)
Definition: Matrix.cc:389
HepMatrix_row operator[](int)
friend void swap(HepMatrix &hm1, HepMatrix &hm2)
HepMatrix operator-() const
Definition: Matrix.cc:259
HepMatrix & operator*=(double t)
Definition: Matrix.cc:409
friend void house_with_update(HepMatrix *a, int row, int col)
HepMatrix & operator-=(const HepMatrix &)
Definition: Matrix.cc:396
friend void col_house(HepMatrix *, const HepMatrix &, double, int, int, int, int)
HepMatrix T() const
Definition: Matrix.cc:454
double determinant() const
Definition: Matrix.cc:813
friend HepMatrix operator*(const HepMatrix &hm1, const HepMatrix &hm2)
Definition: Matrix.cc:349
virtual void invertHaywood6(int &ierr)
friend HepVector qr_solve(HepMatrix *, const HepVector &)
virtual int num_size() const
Definition: Matrix.cc:122
HepMatrix inverse(int &ierr) const
HepMatrix inverse() const
virtual void invertHaywood5(int &ierr)
friend void back_solve(const HepMatrix &R, HepVector *b)
Definition: MatrixLinear.cc:63
double trace() const
Definition: Matrix.cc:830
void f(void g())
Definition: excDblThrow.cc:38
void col_house(HepMatrix *a, const HepMatrix &v, double vnormsq, int row, int col, int row_start, int col_start)
HepVector qr_solve(const HepMatrix &A, const HepVector &b)
HepMatrix qr_inverse(const HepMatrix &A)
void house_with_update(HepMatrix *a, int row=1, int col=1)
void back_solve(const HepMatrix &R, HepVector *b)
Definition: MatrixLinear.cc:63
void qr_decomp(HepMatrix *A, HepMatrix *hsm)
std::ostream & operator<<(std::ostream &s, const HepDiagMatrix &q)
Definition: DiagMatrix.cc:560
HepVector house(const HepMatrix &a, int row=1, int col=1)
void row_givens(HepMatrix *A, double c, double s, int k1, int k2, int col_min=1, int col_max=0)
HepMatrix operator+(const HepMatrix &hm1, const HepDiagMatrix &d2)
Definition: DiagMatrix.cc:193
HepMatrix operator-(const HepMatrix &hm1, const HepDiagMatrix &d2)
Definition: DiagMatrix.cc:264
void givens(double a, double b, double *c, double *s)
HepDiagMatrix operator/(const HepDiagMatrix &hm1, double t)
Definition: DiagMatrix.cc:335
HepMatrix operator*(const HepMatrix &hm1, const HepDiagMatrix &hm2)
Definition: DiagMatrix.cc:372
HepDiagMatrix dsum(const HepDiagMatrix &s1, const HepDiagMatrix &s2)
Definition: DiagMatrix.cc:161
void col_givens(HepMatrix *A, double c, double s, int k1, int k2, int row_min=1, int row_max=0)
void row_house(HepMatrix *a, const HepVector &v, double vnormsq, int row=1, int col=1)
HepVector solve(const HepMatrix &, const HepVector &)
Definition: Vector.cc:575