|
||||
File indexing completed on 2025-01-18 09:54:37
0001 // -*- C++ -*- 0002 // CLASSDOC OFF 0003 // --------------------------------------------------------------------------- 0004 // CLASSDOC ON 0005 // 0006 // This file is a part of the CLHEP - a Class Library for High Energy Physics. 0007 // 0008 // This is the definition of the HepMatrix class. 0009 // 0010 // This software written by Nobu Katayama and Mike Smyth, Cornell University. 0011 // 0012 // 0013 // .SS Usage 0014 // The Matrix class does all the obvious things, in all the obvious ways. 0015 // You declare a Matrix by saying 0016 // 0017 // .ft B 0018 // HepMatrix hm1(n, m); 0019 // 0020 // To declare a Matrix as a copy of a Matrix hm2, say 0021 // 0022 // .ft B 0023 // HepMatrix hm1(hm2); 0024 // or 0025 // .ft B 0026 // HepMatrix hm1 = hm2; 0027 // 0028 // You can declare initilizations of a Matrix, by giving it a third 0029 // integer argument, either 0 or 1. 0 means initialize to 0, one means 0030 // the identity matrix. If you do not give a third argument the memory 0031 // is not initialized. 0032 // 0033 // .ft B 0034 // HepMatrix hm1(n, m, 1); 0035 // 0036 // ./"This code has been written by Mike Smyth, and the algorithms used are 0037 // ./"described in the thesis "A Tracking Library for a Silicon Vertex Detector" 0038 // ./"(Mike Smyth, Cornell University, June 1993). 0039 // ./"This is file contains C++ stuff for doing things with Matrices. 0040 // ./"To turn on bound checking, define MATRIX_BOUND_CHECK before including 0041 // ./"this file. 0042 // 0043 // To find the number of rows or number of columns, say 0044 // 0045 // .ft B 0046 // nr = hm1.num_row(); 0047 // 0048 // or 0049 // 0050 // .ft B 0051 // nc = hm1.num_col(); 0052 // 0053 // You can print a Matrix by 0054 // 0055 // .ft B 0056 // cout << hm1; 0057 // 0058 // You can add, 0059 // subtract, and multiply two Matrices. You can multiply a Matrix by a 0060 // scalar, on the left or the right. +=, *=, -= act in the obvious way. 0061 // hm1 *= hm2 is as hm1 = hm1*hm2. You can also divide by a scalar on the 0062 // right, or use /= to do the same thing. 0063 // 0064 // You can read or write a Matrix element by saying 0065 // 0066 // .ft B 0067 // m(row, col) = blah. (1 <= row <= num_row(), 1 <= col <= num_col()) 0068 // 0069 // .ft B 0070 // blah = m(row, col) ... 0071 // 0072 // m(row, col) is inline, and by default does not do bound checking. 0073 // If bound checking is desired, say #define MATRIX_BOUND_CHECK before 0074 // including matrix.h. 0075 // 0076 // You can also access the element using C subscripting operator [] 0077 // 0078 // .ft B 0079 // m[row][col] = blah. (0 <= row < num_row(), 0 <= col < num_col()) 0080 // 0081 // .ft B 0082 // blah = m[row][col] ... 0083 // 0084 // m[row][col] is inline, and by default does not do bound checking. 0085 // If bound checking is desired, say #define MATRIX_BOUND_CHECK before 0086 // including matrix.h. (Notice the difference in bases in two access 0087 // methods.) 0088 // 0089 // .SS Comments on precision 0090 // 0091 // The user would normally use "Matrix" class whose precision is the same 0092 // as the other classes of CLHEP (ThreeVec, for example). However, he/she 0093 // can explicitly choose Matrix (double) or MatrixF (float) if he/she wishes. 0094 // In the former case, include "Matrix.h." In the latter case, include either 0095 // "Matrix.h," or "MatrixF.h," or both. The only operators that can talk 0096 // to each other are the copy constructor and assignment operator. 0097 // 0098 // .ft B 0099 // Matrix d(3,4,HEP_MATRIX_IDENTITY); 0100 // 0101 // .ft B 0102 // MatrixF f; 0103 // 0104 // .ft B 0105 // f = d; 0106 // 0107 // .ft B 0108 // MatrixF g(d); 0109 // 0110 // will convert from one to the other. 0111 // 0112 // .SS Other functions 0113 // 0114 // .ft B 0115 // mt = m.T(); 0116 // 0117 // returns the transpose of m. 0118 // 0119 // .ft B 0120 // ms = hm2.sub(row_min, row_max, col_min, col_max); 0121 // 0122 // returns the subMatrix. 0123 // hm2(row_min:row_max, col_min:col_max) in matlab terminology. 0124 // If instead you say 0125 // 0126 // .ft B 0127 // hm2.sub(row, col, hm1); 0128 // 0129 // then the subMatrix 0130 // hm2(row:row+hm1.num_row()-1, col:col+hm1.num_col()-1) is replaced with hm1. 0131 // 0132 // .ft B 0133 // md = dsum(hm1,hm2); 0134 // 0135 // returns the direct sum of the two matrices. 0136 // 0137 // Operations that do not have to be member functions or friends are listed 0138 // towards the end of this man page. 0139 // 0140 // 0141 // To invert a matrix, say 0142 // 0143 // .ft B 0144 // minv = m.inverse(ierr); 0145 // 0146 // ierr will be non-zero if the matrix is singular. 0147 // 0148 // If you can overwrite the matrix, you can use the invert function to avoid 0149 // two extra copies. Use 0150 // 0151 // .ft B 0152 // m.invert(ierr); 0153 // 0154 // Many basic linear algebra functions such as QR decomposition are defined. 0155 // In order to keep the header file a reasonable size, the functions are 0156 // defined in MatrixLinear.h. 0157 // 0158 // 0159 // .ft B 0160 // Note that Matrices run from (1,1) to (n, m), and [0][0] to 0161 // [n-1][m-1]. The users of the latter form should be careful about sub 0162 // functions. 0163 // 0164 // ./" The program that this class was orginally used with lots of small 0165 // ./" Matrices. It was very costly to malloc and free array space every 0166 // ./" time a Matrix is needed. So, a number of previously freed arrays are 0167 // ./" kept around, and when needed again one of these array is used. Right 0168 // ./" now, a set of piles of arrays with row <= row_max and col <= col_max 0169 // ./" are kept around. The piles of kept Matrices can be easily changed. 0170 // ./" Array mallocing and freeing are done only in new_m() and delete_m(), 0171 // ./" so these are the only routines that need to be rewritten. 0172 // 0173 // You can do things thinking of a Matrix as a list of numbers. 0174 // 0175 // .ft B 0176 // m = hm1.apply(HEP_MATRIX_ELEMENT (*f)(HEP_MATRIX_ELEMENT, int r, int c)); 0177 // 0178 // applies f to every element of hm1 and places it in m. 0179 // 0180 // .SS See Also: 0181 // SymMatrix[DF].h, GenMatrix[DF].h, DiagMatrix[DF].h Vector[DF].h 0182 // MatrixLinear[DF].h 0183 0184 #ifndef _Matrix_H_ 0185 #define _Matrix_H_ 0186 0187 #include <vector> 0188 0189 #include "CLHEP/Matrix/defs.h" 0190 #include "CLHEP/Matrix/GenMatrix.h" 0191 0192 namespace CLHEP { 0193 0194 class HepRandom; 0195 0196 class HepSymMatrix; 0197 class HepDiagMatrix; 0198 class HepVector; 0199 class HepRotation; 0200 0201 /** 0202 * @author 0203 * @ingroup matrix 0204 */ 0205 class HepMatrix : public HepGenMatrix { 0206 public: 0207 inline HepMatrix(); 0208 // Default constructor. Gives 0 x 0 matrix. Another Matrix can be 0209 // assigned to it. 0210 0211 HepMatrix(int p, int q); 0212 // Constructor. Gives an unitialized p x q matrix. 0213 HepMatrix(int p, int q, int i); 0214 // Constructor. Gives an initialized p x q matrix. 0215 // If i=0, it is initialized to all 0. If i=1, the diagonal elements 0216 // are set to 1.0. 0217 0218 HepMatrix(int p, int q, HepRandom &r); 0219 // Constructor with a Random object. 0220 0221 HepMatrix(const HepMatrix &hm1); 0222 // Copy constructor. 0223 0224 HepMatrix(const HepSymMatrix &); 0225 HepMatrix(const HepDiagMatrix &); 0226 HepMatrix(const HepVector &); 0227 // Constructors from SymMatrix, DiagMatrix and Vector. 0228 0229 virtual ~HepMatrix(); 0230 // Destructor. 0231 0232 virtual int num_row() const; 0233 // Returns the number of rows. 0234 0235 virtual int num_col() const; 0236 // Returns the number of columns. 0237 0238 virtual const double & operator()(int row, int col) const; 0239 virtual double & operator()(int row, int col); 0240 // Read or write a matrix element. 0241 // ** Note that the indexing starts from (1,1). ** 0242 0243 HepMatrix & operator *= (double t); 0244 // Multiply a Matrix by a floating number. 0245 0246 HepMatrix & operator /= (double t); 0247 // Divide a Matrix by a floating number. 0248 0249 HepMatrix & operator += ( const HepMatrix &); 0250 HepMatrix & operator += ( const HepSymMatrix &); 0251 HepMatrix & operator += ( const HepDiagMatrix &); 0252 HepMatrix & operator += ( const HepVector &); 0253 HepMatrix & operator -= ( const HepMatrix &); 0254 HepMatrix & operator -= ( const HepSymMatrix &); 0255 HepMatrix & operator -= ( const HepDiagMatrix &); 0256 HepMatrix & operator -= ( const HepVector &); 0257 // Add or subtract a Matrix. 0258 // When adding/subtracting Vector, Matrix must have num_col of one. 0259 0260 HepMatrix & operator = ( const HepMatrix &); 0261 HepMatrix & operator = ( const HepSymMatrix &); 0262 HepMatrix & operator = ( const HepDiagMatrix &); 0263 HepMatrix & operator = ( const HepVector &); 0264 HepMatrix & operator = ( const HepRotation &); 0265 // Assignment operators. 0266 0267 HepMatrix operator- () const; 0268 // unary minus, ie. flip the sign of each element. 0269 0270 HepMatrix apply(double (*f)(double, int, int)) const; 0271 // Apply a function to all elements of the matrix. 0272 0273 HepMatrix T() const; 0274 // Returns the transpose of a Matrix. 0275 0276 HepMatrix sub(int min_row, int max_row, int min_col, int max_col) const; 0277 // Returns a sub matrix of a Matrix. 0278 // WARNING: rows and columns are numbered from 1 0279 void sub(int row, int col, const HepMatrix &hm1); 0280 // Sub matrix of this Matrix is replaced with hm1. 0281 // WARNING: rows and columns are numbered from 1 0282 0283 friend inline void swap(HepMatrix &hm1, HepMatrix &hm2); 0284 // Swap hm1 with hm2. 0285 0286 inline HepMatrix inverse(int& ierr) const; 0287 // Invert a Matrix. Matrix must be square and is not changed. 0288 // Returns ierr = 0 (zero) when successful, otherwise non-zero. 0289 0290 virtual void invert(int& ierr); 0291 // Invert a Matrix. Matrix must be square. 0292 // N.B. the contents of the matrix are replaced by the inverse. 0293 // Returns ierr = 0 (zero) when successful, otherwise non-zero. 0294 // This method has less overhead then inverse(). 0295 0296 inline void invert(); 0297 // Invert a matrix. Throw std::runtime_error on failure. 0298 0299 inline HepMatrix inverse() const; 0300 // Invert a matrix. Throw std::runtime_error on failure. 0301 0302 0303 double determinant() const; 0304 // calculate the determinant of the matrix. 0305 0306 double trace() const; 0307 // calculate the trace of the matrix (sum of diagonal elements). 0308 0309 class HepMatrix_row { 0310 public: 0311 inline HepMatrix_row(HepMatrix&,int); 0312 double & operator[](int); 0313 private: 0314 HepMatrix& _a; 0315 int _r; 0316 }; 0317 class HepMatrix_row_const { 0318 public: 0319 inline HepMatrix_row_const (const HepMatrix&,int); 0320 const double & operator[](int) const; 0321 private: 0322 const HepMatrix& _a; 0323 int _r; 0324 }; 0325 // helper classes for implementing m[i][j] 0326 0327 inline HepMatrix_row operator[] (int); 0328 inline const HepMatrix_row_const operator[] (int) const; 0329 // Read or write a matrix element. 0330 // While it may not look like it, you simply do m[i][j] to get an 0331 // element. 0332 // ** Note that the indexing starts from [0][0]. ** 0333 0334 protected: 0335 virtual int num_size() const; 0336 virtual void invertHaywood4(int& ierr); 0337 virtual void invertHaywood5(int& ierr); 0338 virtual void invertHaywood6(int& ierr); 0339 0340 private: 0341 friend class HepMatrix_row; 0342 friend class HepMatrix_row_const; 0343 friend class HepVector; 0344 friend class HepSymMatrix; 0345 friend class HepDiagMatrix; 0346 // Friend classes. 0347 0348 friend HepMatrix operator+(const HepMatrix &hm1, const HepMatrix &hm2); 0349 friend HepMatrix operator-(const HepMatrix &hm1, const HepMatrix &hm2); 0350 friend HepMatrix operator*(const HepMatrix &hm1, const HepMatrix &hm2); 0351 friend HepMatrix operator*(const HepMatrix &hm1, const HepSymMatrix &hm2); 0352 friend HepMatrix operator*(const HepMatrix &hm1, const HepDiagMatrix &hm2); 0353 friend HepMatrix operator*(const HepSymMatrix &hm1, const HepMatrix &hm2); 0354 friend HepMatrix operator*(const HepDiagMatrix &hm1, const HepMatrix &hm2); 0355 friend HepMatrix operator*(const HepVector &hm1, const HepMatrix &hm2); 0356 friend HepVector operator*(const HepMatrix &hm1, const HepVector &hm2); 0357 friend HepMatrix operator*(const HepSymMatrix &hm1, const HepSymMatrix &hm2); 0358 // Multiply a Matrix by a Matrix or Vector. 0359 0360 friend HepVector solve(const HepMatrix &, const HepVector &); 0361 // solve the system of linear eq 0362 friend HepVector qr_solve(HepMatrix *, const HepVector &); 0363 friend HepMatrix qr_solve(HepMatrix *, const HepMatrix &b); 0364 friend void tridiagonal(HepSymMatrix *a,HepMatrix *hsm); 0365 friend void row_house(HepMatrix *,const HepMatrix &, double, 0366 int, int, int, int); 0367 friend void row_house(HepMatrix *,const HepVector &, double, 0368 int, int); 0369 friend void back_solve(const HepMatrix &R, HepVector *b); 0370 friend void back_solve(const HepMatrix &R, HepMatrix *b); 0371 friend void col_givens(HepMatrix *A, double c, 0372 double s, int k1, int k2, 0373 int rowmin, int rowmax); 0374 // Does a column Givens update. 0375 friend void row_givens(HepMatrix *A, double c, 0376 double s, int k1, int k2, 0377 int colmin, int colmax); 0378 friend void col_house(HepMatrix *,const HepMatrix &, double, 0379 int, int, int, int); 0380 friend HepVector house(const HepMatrix &a,int row,int col); 0381 friend void house_with_update(HepMatrix *a,int row,int col); 0382 friend void house_with_update(HepMatrix *a,HepMatrix *v,int row,int col); 0383 friend void house_with_update2(HepSymMatrix *a,HepMatrix *v, 0384 int row,int col); 0385 0386 int dfact_matrix(double &det, int *ir); 0387 // factorize the matrix. If successful, the return code is 0. On 0388 // return, det is the determinant and ir[] is row-interchange 0389 // matrix. See CERNLIB's DFACT routine. 0390 0391 int dfinv_matrix(int *ir); 0392 // invert the matrix. See CERNLIB DFINV. 0393 0394 #ifdef DISABLE_ALLOC 0395 std::vector<double > m; 0396 #else 0397 std::vector<double,Alloc<double,25> > m; 0398 #endif 0399 int nrow, ncol; 0400 int size_; 0401 }; 0402 0403 // Operations other than member functions for Matrix 0404 // implemented in Matrix.cc and Matrix.icc (inline). 0405 0406 HepMatrix operator*(const HepMatrix &, const HepMatrix &); 0407 HepMatrix operator*(double t, const HepMatrix &); 0408 HepMatrix operator*(const HepMatrix &, double ); 0409 // Multiplication operators 0410 // Note that m *= hm1 is always faster than m = m * hm1. 0411 0412 HepMatrix operator/(const HepMatrix &, double ); 0413 // m = hm1 / t. (m /= t is faster if you can use it.) 0414 0415 HepMatrix operator+(const HepMatrix &hm1, const HepMatrix &hm2); 0416 // m = hm1 + hm2; 0417 // Note that m += hm1 is always faster than m = m + hm1. 0418 0419 HepMatrix operator-(const HepMatrix &hm1, const HepMatrix &hm2); 0420 // m = hm1 - hm2; 0421 // Note that m -= hm1 is always faster than m = m - hm1. 0422 0423 HepMatrix dsum(const HepMatrix&, const HepMatrix&); 0424 // Direct sum of two matrices. The direct sum of A and B is the matrix 0425 // A 0 0426 // 0 B 0427 0428 HepVector solve(const HepMatrix &, const HepVector &); 0429 // solve the system of linear equations using LU decomposition. 0430 0431 std::ostream& operator<<(std::ostream &s, const HepMatrix &q); 0432 // Read in, write out Matrix into a stream. 0433 0434 // 0435 // Specialized linear algebra functions 0436 // 0437 0438 HepVector qr_solve(const HepMatrix &A, const HepVector &b); 0439 HepVector qr_solve(HepMatrix *A, const HepVector &b); 0440 HepMatrix qr_solve(const HepMatrix &A, const HepMatrix &b); 0441 HepMatrix qr_solve(HepMatrix *A, const HepMatrix &b); 0442 // Works like backsolve, except matrix does not need to be upper 0443 // triangular. For nonsquare matrix, it solves in the least square sense. 0444 0445 HepMatrix qr_inverse(const HepMatrix &A); 0446 HepMatrix qr_inverse(HepMatrix *A); 0447 // Finds the inverse of a matrix using QR decomposition. Note, often what 0448 // you really want is solve or backsolve, they can be much quicker than 0449 // inverse in many calculations. 0450 0451 0452 void qr_decomp(HepMatrix *A, HepMatrix *hsm); 0453 HepMatrix qr_decomp(HepMatrix *A); 0454 // Does a QR decomposition of a matrix. 0455 0456 void back_solve(const HepMatrix &R, HepVector *b); 0457 void back_solve(const HepMatrix &R, HepMatrix *b); 0458 // Solves R*x = b where R is upper triangular. Also has a variation that 0459 // solves a number of equations of this form in one step, where b is a matrix 0460 // with each column a different vector. See also solve. 0461 0462 void col_house(HepMatrix *a, const HepMatrix &v, double vnormsq, 0463 int row, int col, int row_start, int col_start); 0464 void col_house(HepMatrix *a, const HepMatrix &v, int row, int col, 0465 int row_start, int col_start); 0466 // Does a column Householder update. 0467 0468 void col_givens(HepMatrix *A, double c, double s, 0469 int k1, int k2, int row_min=1, int row_max=0); 0470 // do a column Givens update 0471 0472 void row_givens(HepMatrix *A, double c, double s, 0473 int k1, int k2, int col_min=1, int col_max=0); 0474 // do a row Givens update 0475 0476 void givens(double a, double b, double *c, double *s); 0477 // algorithm 5.1.5 in Golub and Van Loan 0478 0479 HepVector house(const HepMatrix &a, int row=1, int col=1); 0480 // Returns a Householder vector to zero elements. 0481 0482 void house_with_update(HepMatrix *a, int row=1, int col=1); 0483 void house_with_update(HepMatrix *a, HepMatrix *v, int row=1, int col=1); 0484 // Finds and does Householder reflection on matrix. 0485 0486 void row_house(HepMatrix *a, const HepVector &v, double vnormsq, 0487 int row=1, int col=1); 0488 void row_house(HepMatrix *a, const HepMatrix &v, double vnormsq, 0489 int row, int col, int row_start, int col_start); 0490 void row_house(HepMatrix *a, const HepMatrix &v, int row, int col, 0491 int row_start, int col_start); 0492 // Does a row Householder update. 0493 0494 } // namespace CLHEP 0495 0496 #ifdef ENABLE_BACKWARDS_COMPATIBILITY 0497 // backwards compatibility will be enabled ONLY in CLHEP 1.9 0498 using namespace CLHEP; 0499 #endif 0500 0501 #ifndef HEP_DEBUG_INLINE 0502 #include "CLHEP/Matrix/Matrix.icc" 0503 #endif 0504 0505 #endif /*_Matrix_H*/
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |