Back to home page

EIC code displayed by LXR

 
 

    


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*/