|
||||
File indexing completed on 2025-01-30 10:22:09
0001 // @(#)root/smatrix:$Id$ 0002 // Author: T. Glebe, L. Moneta, J. Palacios 2005 0003 0004 #ifndef ROOT_Math_SMatrix 0005 #define ROOT_Math_SMatrix 0006 0007 /********************************************************************************* 0008 // 0009 // source: 0010 // 0011 // type: source code 0012 // 0013 // created: 20. Mar 2001 0014 // 0015 // author: Thorsten Glebe 0016 // HERA-B Collaboration 0017 // Max-Planck-Institut fuer Kernphysik 0018 // Saupfercheckweg 1 0019 // 69117 Heidelberg 0020 // Germany 0021 // E-mail: T.Glebe@mpi-hd.mpg.de 0022 // 0023 // Description: A fixed size two dimensional Matrix class 0024 // 0025 // changes: 0026 // 20 Mar 2001 (TG) creation 0027 // 21 Mar 2001 (TG) added operators +=, -=, *=, /= 0028 // 26 Mar 2001 (TG) place_in_row(), place_in_col() added 0029 // 02 Apr 2001 (TG) non-const Array() added 0030 // 03 Apr 2001 (TG) invert() added 0031 // 07 Apr 2001 (TG) CTOR from SVertex (dyadic product) added 0032 // 09 Apr 2001 (TG) CTOR from array added 0033 // 11 Apr 2001 (TG) rows(), cols(), size() replaced by rows, cols, size 0034 // 25 Mai 2001 (TG) row(), col() added 0035 // 04 Sep 2001 (TG) moved inlined functions to .icc file 0036 // 11 Jan 2002 (TG) added operator==(), operator!=() 0037 // 14 Jan 2002 (TG) added more operator==(), operator!=(), operator>(), operator<() 0038 // 0039 ***************************************************************************/ 0040 // for platform specific configurations 0041 0042 #include "Math/MConfig.h" 0043 0044 #include <iosfwd> 0045 0046 0047 /** 0048 \defgroup SMatrixSVector Matrix and Vector classes 0049 \ingroup SMatrixGroup 0050 0051 Classes representing Matrices and Vectors of arbitrary type and dimension. 0052 For a detailed description and usage examples see: 0053 0054 - \ref SVectorDoc 0055 - \ref SMatrixDoc 0056 - \ref MatVecFunctions 0057 0058 */ 0059 0060 0061 #include "Math/Expression.h" 0062 #include "Math/MatrixRepresentationsStatic.h" 0063 0064 0065 namespace ROOT { 0066 0067 namespace Math { 0068 0069 0070 template <class T, unsigned int D> class SVector; 0071 0072 struct SMatrixIdentity { }; 0073 struct SMatrixNoInit { }; 0074 0075 //__________________________________________________________________________ 0076 /** 0077 SMatrix: a generic fixed size D1 x D2 Matrix class. 0078 The class is template on the scalar type, on the matrix sizes: 0079 D1 = number of rows and D2 = number of columns 0080 amd on the representation storage type. 0081 By default the representation is MatRepStd<T,D1,D2> (standard D1xD2 of type T), 0082 but it can be of type MatRepSym<T,D> for symmetric matrices DxD, where the storage is only 0083 D*(D+1)/2. 0084 0085 See \ref SMatrixDoc. 0086 0087 Original author is Thorsten Glebe 0088 HERA-B Collaboration, MPI Heidelberg (Germany) 0089 0090 @ingroup SMatrixSVector 0091 0092 @authors T. Glebe, L. Moneta and J. Palacios 0093 */ 0094 //============================================================================== 0095 // SMatrix: column-wise storage 0096 //============================================================================== 0097 template <class T, 0098 unsigned int D1, 0099 unsigned int D2 = D1, 0100 class R=MatRepStd<T, D1, D2> > 0101 class SMatrix { 0102 public: 0103 /** @name --- Typedefs --- */ 0104 0105 /** contained scalar type */ 0106 typedef T value_type; 0107 0108 /** storage representation type */ 0109 typedef R rep_type; 0110 0111 /** STL iterator interface. */ 0112 typedef T* iterator; 0113 0114 /** STL const_iterator interface. */ 0115 typedef const T* const_iterator; 0116 0117 0118 0119 /** @name --- Constructors and Assignment --- */ 0120 0121 /** 0122 Default constructor: 0123 */ 0124 SMatrix(); 0125 /// 0126 /** 0127 construct from without initialization 0128 */ 0129 inline SMatrix( SMatrixNoInit ){} 0130 0131 /** 0132 construct from an identity matrix 0133 */ 0134 SMatrix( SMatrixIdentity ); 0135 /** 0136 copy constructor (from a matrix of the same representation 0137 */ 0138 SMatrix(const SMatrix<T,D1,D2,R>& rhs); 0139 /** 0140 construct from a matrix with different representation. 0141 Works only from symmetric to general and not viceversa. 0142 */ 0143 template <class R2> 0144 SMatrix(const SMatrix<T,D1,D2,R2>& rhs); 0145 0146 /** 0147 Construct from an expression. 0148 In case of symmetric matrices does not work if expression is of type general 0149 matrices. In case one needs to force the assignment from general to symmetric, one can use the 0150 ROOT::Math::AssignSym::Evaluate function. 0151 */ 0152 template <class A, class R2> 0153 SMatrix(const Expr<A,T,D1,D2,R2>& rhs); 0154 0155 0156 /** 0157 Constructor with STL iterator interface. The data will be copied into the matrix 0158 \param begin start iterator position 0159 \param end end iterator position 0160 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 0161 \param lower if true the lower triangular part is filled 0162 0163 Size of the matrix must match size of the iterators, if triang is false, otherwise the size of the 0164 triangular block. In the case of symmetric matrices triang is considered always to be true 0165 (what-ever the user specifies) and the size of the iterators must be equal to the size of the 0166 triangular block, which is the number of independent elements of a symmetric matrix: N*(N+1)/2 0167 0168 */ 0169 template<class InputIterator> 0170 SMatrix(InputIterator begin, InputIterator end, bool triang = false, bool lower = true); 0171 0172 /** 0173 Constructor with STL iterator interface. The data will be copied into the matrix 0174 \param begin start iterator position 0175 \param size iterator size 0176 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 0177 \param lower if true the lower triangular part is filled 0178 0179 Size of the iterators must not be larger than the size of the matrix representation. 0180 In the case of symmetric matrices the size is N*(N+1)/2. 0181 0182 */ 0183 template<class InputIterator> 0184 SMatrix(InputIterator begin, unsigned int size, bool triang = false, bool lower = true); 0185 0186 /** 0187 constructor of a symmetrix a matrix from a SVector containing the lower (upper) 0188 triangular part. 0189 */ 0190 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION 0191 SMatrix(const SVector<T, D1*(D2+1)/2> & v, bool lower = true ); 0192 #else 0193 template<unsigned int N> 0194 SMatrix(const SVector<T,N> & v, bool lower = true ); 0195 #endif 0196 0197 0198 /** 0199 Construct from a scalar value (only for size 1 matrices) 0200 */ 0201 explicit SMatrix(const T& rhs); 0202 0203 /** 0204 Assign from another compatible matrix. 0205 Possible Symmetirc to general but NOT vice-versa 0206 */ 0207 template <class M> 0208 SMatrix<T,D1,D2,R>& operator=(const M& rhs); 0209 0210 SMatrix<T,D1,D2,R>& operator=(const SMatrix<T,D1,D2,R>& rhs); 0211 0212 /** 0213 Assign from a matrix expression 0214 */ 0215 template <class A, class R2> 0216 SMatrix<T,D1,D2,R>& operator=(const Expr<A,T,D1,D2,R2>& rhs); 0217 0218 /** 0219 Assign from an identity matrix 0220 */ 0221 SMatrix<T,D1,D2,R> & operator=(SMatrixIdentity ); 0222 0223 /** 0224 Assign from a scalar value (only for size 1 matrices) 0225 */ 0226 SMatrix<T,D1,D2,R>& operator=(const T& rhs); 0227 0228 /** @name --- Matrix dimension --- */ 0229 0230 /** 0231 Enumeration defining the matrix dimension, 0232 number of rows, columns and size = rows*columns) 0233 */ 0234 enum { 0235 /// return no. of matrix rows 0236 kRows = D1, 0237 /// return no. of matrix columns 0238 kCols = D2, 0239 /// return no of elements: rows*columns 0240 kSize = D1*D2 0241 }; 0242 0243 /** @name --- Access functions --- */ 0244 0245 /** access the parse tree with the index starting from zero and 0246 following the C convention for the order in accessing 0247 the matrix elements. 0248 Same convention for general and symmetric matrices. 0249 */ 0250 T apply(unsigned int i) const; 0251 0252 /// return read-only pointer to internal array 0253 const T* Array() const; 0254 /// return pointer to internal array 0255 T* Array(); 0256 0257 /** @name --- STL-like interface --- 0258 The iterators access the matrix element in the order how they are 0259 stored in memory. The C (row-major) convention is used, and in the 0260 case of symmetric matrices the iterator spans only the lower diagonal 0261 block. For example for a symmetric 3x3 matrices the order of the 6 0262 elements \f${a_0,...a_5}\f$ is: 0263 \f[ 0264 M = \left( \begin{array}{ccc} 0265 a_0 & a_1 & a_3 \\ 0266 a_1 & a_2 & a_4 \\ 0267 a_3 & a_4 & a_5 \end{array} \right) 0268 \f] 0269 */ 0270 0271 /** STL iterator interface. */ 0272 iterator begin(); 0273 0274 /** STL iterator interface. */ 0275 iterator end(); 0276 0277 /** STL const_iterator interface. */ 0278 const_iterator begin() const; 0279 0280 /** STL const_iterator interface. */ 0281 const_iterator end() const; 0282 0283 /** 0284 Set matrix elements with STL iterator interface. The data will be copied into the matrix 0285 \param begin start iterator position 0286 \param end end iterator position 0287 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 0288 \param lower if true the lower triangular part is filled 0289 0290 Size of the matrix must match size of the iterators, if triang is false, otherwise the size of the 0291 triangular block. In the case of symmetric matrices triang is considered always to be true 0292 (what-ever the user specifies) and the size of the iterators must be equal to the size of the 0293 triangular block, which is the number of independent elements of a symmetric matrix: N*(N+1)/2 0294 0295 */ 0296 template<class InputIterator> 0297 void SetElements(InputIterator begin, InputIterator end, bool triang = false, bool lower = true); 0298 0299 /** 0300 Constructor with STL iterator interface. The data will be copied into the matrix 0301 \param begin start iterator position 0302 \param size iterator size 0303 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 0304 \param lower if true the lower triangular part is filled 0305 0306 Size of the iterators must not be larger than the size of the matrix representation. 0307 In the case of symmetric matrices the size is N*(N+1)/2. 0308 0309 */ 0310 template<class InputIterator> 0311 void SetElements(InputIterator begin, unsigned int size, bool triang = false, bool lower = true); 0312 0313 0314 /** @name --- Operators --- */ 0315 /// element wise comparison 0316 bool operator==(const T& rhs) const; 0317 /// element wise comparison 0318 bool operator!=(const T& rhs) const; 0319 /// element wise comparison 0320 template <class R2> 0321 bool operator==(const SMatrix<T,D1,D2,R2>& rhs) const; 0322 /// element wise comparison 0323 bool operator!=(const SMatrix<T,D1,D2,R>& rhs) const; 0324 /// element wise comparison 0325 template <class A, class R2> 0326 bool operator==(const Expr<A,T,D1,D2,R2>& rhs) const; 0327 /// element wise comparison 0328 template <class A, class R2> 0329 bool operator!=(const Expr<A,T,D1,D2,R2>& rhs) const; 0330 0331 /// element wise comparison 0332 bool operator>(const T& rhs) const; 0333 /// element wise comparison 0334 bool operator<(const T& rhs) const; 0335 /// element wise comparison 0336 template <class R2> 0337 bool operator>(const SMatrix<T,D1,D2,R2>& rhs) const; 0338 /// element wise comparison 0339 template <class R2> 0340 bool operator<(const SMatrix<T,D1,D2,R2>& rhs) const; 0341 /// element wise comparison 0342 template <class A, class R2> 0343 bool operator>(const Expr<A,T,D1,D2,R2>& rhs) const; 0344 /// element wise comparison 0345 template <class A, class R2> 0346 bool operator<(const Expr<A,T,D1,D2,R2>& rhs) const; 0347 0348 /** 0349 read only access to matrix element, with indices starting from 0 0350 */ 0351 const T& operator()(unsigned int i, unsigned int j) const; 0352 /** 0353 read/write access to matrix element with indices starting from 0 0354 */ 0355 T& operator()(unsigned int i, unsigned int j); 0356 0357 /** 0358 read only access to matrix element, with indices starting from 0. 0359 Function will check index values and it will assert if they are wrong 0360 */ 0361 const T& At(unsigned int i, unsigned int j) const; 0362 /** 0363 read/write access to matrix element with indices starting from 0. 0364 Function will check index values and it will assert if they are wrong 0365 */ 0366 T& At(unsigned int i, unsigned int j); 0367 0368 0369 // helper class for implementing the m[i][j] operator 0370 0371 class SMatrixRow { 0372 public: 0373 SMatrixRow ( SMatrix<T,D1,D2,R> & rhs, unsigned int i ) : 0374 fMat(&rhs), fRow(i) 0375 {} 0376 T & operator[](int j) { return (*fMat)(fRow,j); } 0377 private: 0378 SMatrix<T,D1,D2,R> * fMat; 0379 unsigned int fRow; 0380 }; 0381 0382 class SMatrixRow_const { 0383 public: 0384 SMatrixRow_const ( const SMatrix<T,D1,D2,R> & rhs, unsigned int i ) : 0385 fMat(&rhs), fRow(i) 0386 {} 0387 0388 const T & operator[](int j) const { return (*fMat)(fRow, j); } 0389 0390 private: 0391 const SMatrix<T,D1,D2,R> * fMat; 0392 unsigned int fRow; 0393 }; 0394 0395 /** 0396 read only access to matrix element, with indices starting from 0 : m[i][j] 0397 */ 0398 SMatrixRow_const operator[](unsigned int i) const { return SMatrixRow_const(*this, i); } 0399 /** 0400 read/write access to matrix element with indices starting from 0 : m[i][j] 0401 */ 0402 SMatrixRow operator[](unsigned int i) { return SMatrixRow(*this, i); } 0403 0404 0405 /** 0406 addition with a scalar 0407 */ 0408 SMatrix<T,D1,D2,R>&operator+=(const T& rhs); 0409 0410 /** 0411 addition with another matrix of any compatible representation 0412 */ 0413 template <class R2> 0414 SMatrix<T,D1,D2,R>&operator+=(const SMatrix<T,D1,D2,R2>& rhs); 0415 0416 /** 0417 addition with a compatible matrix expression 0418 */ 0419 template <class A, class R2> 0420 SMatrix<T,D1,D2,R>& operator+=(const Expr<A,T,D1,D2,R2>& rhs); 0421 0422 /** 0423 subtraction with a scalar 0424 */ 0425 SMatrix<T,D1,D2,R>& operator-=(const T& rhs); 0426 0427 /** 0428 subtraction with another matrix of any compatible representation 0429 */ 0430 template <class R2> 0431 SMatrix<T,D1,D2,R>&operator-=(const SMatrix<T,D1,D2,R2>& rhs); 0432 0433 /** 0434 subtraction with a compatible matrix expression 0435 */ 0436 template <class A, class R2> 0437 SMatrix<T,D1,D2,R>& operator-=(const Expr<A,T,D1,D2,R2>& rhs); 0438 0439 /** 0440 multiplication with a scalar 0441 */ 0442 SMatrix<T,D1,D2,R>& operator*=(const T& rhs); 0443 0444 0445 /** 0446 multiplication with another compatible matrix (it is a real matrix multiplication) 0447 Note that this operation does not avid to create a temporary to store intermediate result 0448 */ 0449 template <class R2> 0450 SMatrix<T,D1,D2,R>& operator*=(const SMatrix<T,D1,D2,R2>& rhs); 0451 0452 /** 0453 multiplication with a compatible matrix expression (it is a real matrix multiplication) 0454 */ 0455 template <class A, class R2> 0456 SMatrix<T,D1,D2,R>& operator*=(const Expr<A,T,D1,D2,R2>& rhs); 0457 0458 0459 /** 0460 division with a scalar 0461 */ 0462 SMatrix<T,D1,D2,R>& operator/=(const T& rhs); 0463 0464 0465 0466 /** @name --- Linear Algebra Functions --- */ 0467 0468 /** 0469 Invert a square Matrix ( this method changes the current matrix). 0470 Return true if inversion is successful. 0471 The method used for general square matrices is the LU factorization taken from Dinv routine 0472 from the CERNLIB (written in C++ from CLHEP authors) 0473 In case of symmetric matrices Bunch-Kaufman diagonal pivoting method is used 0474 (The implementation is the one written by the CLHEP authors) 0475 */ 0476 bool Invert(); 0477 0478 /** 0479 Invert a square Matrix and returns a new matrix. In case the inversion fails 0480 the current matrix is returned. 0481 \param ifail . ifail will be set to 0 when inversion is successful. 0482 See ROOT::Math::SMatrix::Invert for the inversion algorithm 0483 */ 0484 SMatrix<T,D1,D2,R> Inverse(int & ifail ) const; 0485 0486 /** 0487 Fast inversion of a square Matrix ( this method changes the current matrix). 0488 Return true if inversion is successful. 0489 The method used is based on direct inversion using the Cramer rule for 0490 matrices upto 5x5. Afterwards the same default algorithm of Invert() is used. 0491 Note that this method is faster but can suffer from much larger numerical accuracy 0492 when the condition of the matrix is large 0493 */ 0494 bool InvertFast(); 0495 0496 /** 0497 Invert a square Matrix and returns a new matrix. In case the inversion fails 0498 the current matrix is returned. 0499 \param ifail . ifail will be set to 0 when inversion is successful. 0500 See ROOT::Math::SMatrix::InvertFast for the inversion algorithm 0501 */ 0502 SMatrix<T,D1,D2,R> InverseFast(int & ifail ) const; 0503 0504 /** 0505 Inversion of a symmetric positive defined Matrix using Choleski decomposition. 0506 ( this method changes the current matrix). 0507 Return true if inversion is successful. 0508 The method used is based on Choleski decomposition 0509 A compile error is given if the matrix is not of type symmetric and a run-time failure if the 0510 matrix is not positive defined. 0511 For solving a linear system, it is possible to use also the function 0512 ROOT::Math::SolveChol(matrix, vector) which will be faster than performing the inversion 0513 */ 0514 bool InvertChol(); 0515 0516 /** 0517 Invert of a symmetric positive defined Matrix using Choleski decomposition. 0518 A compile error is given if the matrix is not of type symmetric and a run-time failure if the 0519 matrix is not positive defined. 0520 In case the inversion fails the current matrix is returned. 0521 \param ifail . ifail will be set to 0 when inversion is successful. 0522 See ROOT::Math::SMatrix::InvertChol for the inversion algorithm 0523 */ 0524 SMatrix<T,D1,D2,R> InverseChol(int & ifail ) const; 0525 0526 /** 0527 determinant of square Matrix via Dfact. 0528 Return true when the calculation is successful. 0529 \param det will contain the calculated determinant value 0530 \b Note: this will destroy the contents of the Matrix! 0531 */ 0532 bool Det(T& det); 0533 0534 /** 0535 determinant of square Matrix via Dfact. 0536 Return true when the calculation is successful. 0537 \param det will contain the calculated determinant value 0538 \b Note: this will preserve the content of the Matrix! 0539 */ 0540 bool Det2(T& det) const; 0541 0542 0543 /** @name --- Matrix Slice Functions --- */ 0544 0545 /// place a vector in a Matrix row 0546 template <unsigned int D> 0547 SMatrix<T,D1,D2,R>& Place_in_row(const SVector<T,D>& rhs, 0548 unsigned int row, 0549 unsigned int col); 0550 /// place a vector expression in a Matrix row 0551 template <class A, unsigned int D> 0552 SMatrix<T,D1,D2,R>& Place_in_row(const VecExpr<A,T,D>& rhs, 0553 unsigned int row, 0554 unsigned int col); 0555 /// place a vector in a Matrix column 0556 template <unsigned int D> 0557 SMatrix<T,D1,D2,R>& Place_in_col(const SVector<T,D>& rhs, 0558 unsigned int row, 0559 unsigned int col); 0560 /// place a vector expression in a Matrix column 0561 template <class A, unsigned int D> 0562 SMatrix<T,D1,D2,R>& Place_in_col(const VecExpr<A,T,D>& rhs, 0563 unsigned int row, 0564 unsigned int col); 0565 /// place a matrix in this matrix 0566 template <unsigned int D3, unsigned int D4, class R2> 0567 SMatrix<T,D1,D2,R>& Place_at(const SMatrix<T,D3,D4,R2>& rhs, 0568 unsigned int row, 0569 unsigned int col); 0570 /// place a matrix expression in this matrix 0571 template <class A, unsigned int D3, unsigned int D4, class R2> 0572 SMatrix<T,D1,D2,R>& Place_at(const Expr<A,T,D3,D4,R2>& rhs, 0573 unsigned int row, 0574 unsigned int col); 0575 0576 /** 0577 return a full Matrix row as a vector (copy the content in a new vector) 0578 */ 0579 SVector<T,D2> Row(unsigned int therow) const; 0580 0581 /** 0582 return a full Matrix column as a vector (copy the content in a new vector) 0583 */ 0584 SVector<T,D1> Col(unsigned int thecol) const; 0585 0586 /** 0587 return a slice of therow as a vector starting at the column value col0 until col0+N, 0588 where N is the size of the vector (SVector::kSize ) 0589 Condition col0+N <= D2 0590 */ 0591 template <class SubVector> 0592 SubVector SubRow(unsigned int therow, unsigned int col0 = 0 ) const; 0593 0594 /** 0595 return a slice of the column as a vector starting at the row value row0 until row0+Dsub. 0596 where N is the size of the vector (SVector::kSize ) 0597 Condition row0+N <= D1 0598 */ 0599 template <class SubVector> 0600 SubVector SubCol(unsigned int thecol, unsigned int row0 = 0) const; 0601 0602 /** 0603 return a submatrix with the upper left corner at the values (row0, col0) and with sizes N1, N2 0604 where N1 and N2 are the dimension of the sub-matrix (SubMatrix::kRows and SubMatrix::kCols ) 0605 Condition row0+N1 <= D1 && col0+N2 <=D2 0606 */ 0607 template <class SubMatrix > 0608 SubMatrix Sub(unsigned int row0, unsigned int col0) const; 0609 0610 /** 0611 return diagonal elements of a matrix as a Vector. 0612 It works only for squared matrices D1 == D2, otherwise it will produce a compile error 0613 */ 0614 SVector<T,D1> Diagonal() const; 0615 0616 /** 0617 Set the diagonal elements from a Vector 0618 Require that vector implements SVector::kSize since a check (statically) is done on 0619 diagonal size == vector size 0620 */ 0621 template <class Vector> 0622 void SetDiagonal(const Vector & v); 0623 0624 /** 0625 return the trace of a matrix 0626 Sum of the diagonal elements 0627 */ 0628 T Trace() const; 0629 0630 0631 /** 0632 return the upper Triangular block of the matrices (including the diagonal) as 0633 a vector of sizes N = D1 * (D1 + 1)/2. 0634 It works only for square matrices with D1==D2, otherwise it will produce a compile error 0635 */ 0636 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION 0637 SVector<T, D1 * (D2 +1)/2> UpperBlock() const; 0638 #else 0639 template<class SubVector> 0640 SubVector UpperBlock() const; 0641 #endif 0642 0643 /** 0644 return the lower Triangular block of the matrices (including the diagonal) as 0645 a vector of sizes N = D1 * (D1 + 1)/2. 0646 It works only for square matrices with D1==D2, otherwise it will produce a compile error 0647 */ 0648 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION 0649 SVector<T, D1 * (D2 +1)/2> LowerBlock() const; 0650 #else 0651 template<class SubVector> 0652 SubVector LowerBlock() const; 0653 #endif 0654 0655 0656 /** @name --- Other Functions --- */ 0657 0658 /** 0659 Function to check if a matrix is sharing same memory location of the passed pointer 0660 This function is used by the expression templates to avoid the alias problem during 0661 expression evaluation. When the matrix is in use, for example in operations 0662 like A = B * A, a temporary object storing the intermediate result is automatically 0663 created when evaluating the expression. 0664 0665 */ 0666 bool IsInUse(const T* p) const; 0667 0668 // submatrices 0669 0670 /// Print: used by operator<<() 0671 std::ostream& Print(std::ostream& os) const; 0672 0673 0674 0675 0676 public: 0677 0678 /** @name --- Data Member --- */ 0679 0680 /** 0681 Matrix Storage Object containing matrix data 0682 */ 0683 R fRep; 0684 0685 }; // end of class SMatrix 0686 0687 0688 0689 0690 //============================================================================== 0691 // operator<< 0692 //============================================================================== 0693 template <class T, unsigned int D1, unsigned int D2, class R> 0694 inline std::ostream& operator<<(std::ostream& os, const ROOT::Math::SMatrix<T,D1,D2,R>& rhs) { 0695 return rhs.Print(os); 0696 } 0697 0698 0699 } // namespace Math 0700 0701 } // namespace ROOT 0702 0703 0704 0705 #include "Math/SMatrix.icc" 0706 0707 #include "Math/MatrixFunctions.h" 0708 0709 #endif /* ROOT_Math_SMatrix */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |