00001 // @(#)root/smatrix:$Id: SMatrix.h 30749 2009-10-15 16:33:04Z brun $ 00002 // Author: T. Glebe, L. Moneta, J. Palacios 2005 00003 00004 #ifndef ROOT_Math_SMatrix 00005 #define ROOT_Math_SMatrix 00006 00007 /********************************************************************************* 00008 // 00009 // source: 00010 // 00011 // type: source code 00012 // 00013 // created: 20. Mar 2001 00014 // 00015 // author: Thorsten Glebe 00016 // HERA-B Collaboration 00017 // Max-Planck-Institut fuer Kernphysik 00018 // Saupfercheckweg 1 00019 // 69117 Heidelberg 00020 // Germany 00021 // E-mail: T.Glebe@mpi-hd.mpg.de 00022 // 00023 // Description: A fixed size two dimensional Matrix class 00024 // 00025 // changes: 00026 // 20 Mar 2001 (TG) creation 00027 // 21 Mar 2001 (TG) added operators +=, -=, *=, /= 00028 // 26 Mar 2001 (TG) place_in_row(), place_in_col() added 00029 // 02 Apr 2001 (TG) non-const Array() added 00030 // 03 Apr 2001 (TG) invert() added 00031 // 07 Apr 2001 (TG) CTOR from SVertex (dyadic product) added 00032 // 09 Apr 2001 (TG) CTOR from array added 00033 // 11 Apr 2001 (TG) rows(), cols(), size() replaced by rows, cols, size 00034 // 25 Mai 2001 (TG) row(), col() added 00035 // 04 Sep 2001 (TG) moved inlined functions to .icc file 00036 // 11 Jan 2002 (TG) added operator==(), operator!=() 00037 // 14 Jan 2002 (TG) added more operator==(), operator!=(), operator>(), operator<() 00038 // 00039 ***************************************************************************/ 00040 // for platform specific configurations 00041 00042 #ifndef ROOT_Math_MnConfig 00043 #include "Math/MConfig.h" 00044 #endif 00045 00046 #include <iosfwd> 00047 00048 00049 00050 00051 //doxygen tag 00052 00053 /** 00054 @defgroup SMatrixGroup SMatrix 00055 00056 \ref SMatrix for high performance vector and matrix computations. 00057 Classes representing Matrices and Vectors of arbitrary type and dimension and related functions. 00058 For a detailed description and usage examples see: 00059 <ul> 00060 <li>\ref SMatrix home page 00061 <li>\ref SVectorDoc 00062 <li>\ref SMatrixDoc 00063 <li>\ref MatVecFunctions 00064 </ul> 00065 00066 */ 00067 00068 /** 00069 @defgroup SMatrixSVector Matrix and Vector classes 00070 00071 @ingroup SMatrixGroup 00072 00073 Classes representing Matrices and Vectors of arbitrary type and dimension. 00074 For a detailed description and usage examples see: 00075 <ul> 00076 <li>\ref SVectorDoc 00077 <li>\ref SMatrixDoc 00078 <li>\ref MatVecFunctions 00079 </ul> 00080 00081 */ 00082 00083 00084 #ifndef ROOT_Math_Expression 00085 #include "Math/Expression.h" 00086 #endif 00087 #ifndef ROOT_Math_MatrixRepresentationsStatic 00088 #include "Math/MatrixRepresentationsStatic.h" 00089 #endif 00090 00091 00092 namespace ROOT { 00093 00094 namespace Math { 00095 00096 00097 template <class T, unsigned int D> class SVector; 00098 00099 struct SMatrixIdentity { }; 00100 00101 //__________________________________________________________________________ 00102 /** 00103 SMatrix: a generic fixed size D1 x D2 Matrix class. 00104 The class is template on the scalar type, on the matrix sizes: 00105 D1 = number of rows and D2 = number of columns 00106 amd on the representation storage type. 00107 By default the representation is MatRepStd<T,D1,D2> (standard D1xD2 of type T), 00108 but it can be of type MatRepSym<T,D> for symmetric matrices DxD, where the storage is only 00109 D*(D+1)/2. 00110 00111 See \ref SMatrixDoc. 00112 00113 Original author is Thorsten Glebe 00114 HERA-B Collaboration, MPI Heidelberg (Germany) 00115 00116 @ingroup SMatrixSVector 00117 00118 @authors T. Glebe, L. Moneta and J. Palacios 00119 */ 00120 //============================================================================== 00121 // SMatrix: column-wise storage 00122 //============================================================================== 00123 template <class T, 00124 unsigned int D1, 00125 unsigned int D2 = D1, 00126 class R=MatRepStd<T, D1, D2> > 00127 class SMatrix { 00128 public: 00129 /** @name --- Typedefs --- */ 00130 00131 /** contained scalar type */ 00132 typedef T value_type; 00133 00134 /** storage representation type */ 00135 typedef R rep_type; 00136 00137 /** STL iterator interface. */ 00138 typedef T* iterator; 00139 00140 /** STL const_iterator interface. */ 00141 typedef const T* const_iterator; 00142 00143 00144 00145 /** @name --- Constructors and Assignment --- */ 00146 00147 /** 00148 Default constructor: 00149 */ 00150 SMatrix(); 00151 /// 00152 /** 00153 construct from an identity matrix 00154 */ 00155 SMatrix( SMatrixIdentity ); 00156 /** 00157 copy constructor (from a matrix of the same representation 00158 */ 00159 SMatrix(const SMatrix<T,D1,D2,R>& rhs); 00160 /** 00161 construct from a matrix with different representation. 00162 Works only from symmetric to general and not viceversa. 00163 */ 00164 template <class R2> 00165 SMatrix(const SMatrix<T,D1,D2,R2>& rhs); 00166 00167 /** 00168 Construct from an expression. 00169 In case of symmetric matrices does not work if expression is of type general 00170 matrices. In case one needs to force the assignment from general to symmetric, one can use the 00171 ROOT::Math::AssignSym::Evaluate function. 00172 */ 00173 template <class A, class R2> 00174 SMatrix(const Expr<A,T,D1,D2,R2>& rhs); 00175 00176 00177 /** 00178 Constructor with STL iterator interface. The data will be copied into the matrix 00179 \param begin start iterator position 00180 \param end end iterator position 00181 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 00182 \param lower if true the lower triangular part is filled 00183 00184 Size of the matrix must match size of the iterators, if triang is false, otherwise the size of the 00185 triangular block. In the case of symmetric matrices triang is considered always to be true 00186 (what-ever the user specifies) and the size of the iterators must be equal to the size of the 00187 triangular block, which is the number of independent elements of a symmetric matrix: N*(N+1)/2 00188 00189 */ 00190 template<class InputIterator> 00191 SMatrix(InputIterator begin, InputIterator end, bool triang = false, bool lower = true); 00192 00193 /** 00194 Constructor with STL iterator interface. The data will be copied into the matrix 00195 \param begin start iterator position 00196 \param size iterator size 00197 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 00198 \param lower if true the lower triangular part is filled 00199 00200 Size of the iterators must not be larger than the size of the matrix representation. 00201 In the case of symmetric matrices the size is N*(N+1)/2. 00202 00203 */ 00204 template<class InputIterator> 00205 SMatrix(InputIterator begin, unsigned int size, bool triang = false, bool lower = true); 00206 00207 /** 00208 constructor of a symmetrix a matrix from a SVector containing the lower (upper) 00209 triangular part. 00210 */ 00211 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION 00212 SMatrix(const SVector<T, D1*(D2+1)/2> & v, bool lower = true ); 00213 #else 00214 template<unsigned int N> 00215 SMatrix(const SVector<T,N> & v, bool lower = true ); 00216 #endif 00217 00218 00219 /** 00220 Construct from a scalar value (only for size 1 matrices) 00221 */ 00222 explicit SMatrix(const T& rhs); 00223 00224 /** 00225 Assign from another compatible matrix. 00226 Possible Symmetirc to general but NOT vice-versa 00227 */ 00228 template <class M> 00229 SMatrix<T,D1,D2,R>& operator=(const M& rhs); 00230 00231 /** 00232 Assign from a matrix expression 00233 */ 00234 template <class A, class R2> 00235 SMatrix<T,D1,D2,R>& operator=(const Expr<A,T,D1,D2,R2>& rhs); 00236 00237 /** 00238 Assign from an identity matrix 00239 */ 00240 SMatrix<T,D1,D2,R> & operator=(SMatrixIdentity ); 00241 00242 /** 00243 Assign from a scalar value (only for size 1 matrices) 00244 */ 00245 SMatrix<T,D1,D2,R>& operator=(const T& rhs); 00246 00247 /** @name --- Matrix dimension --- */ 00248 00249 /** 00250 Enumeration defining the matrix dimension, 00251 number of rows, columns and size = rows*columns) 00252 */ 00253 enum { 00254 /// return no. of matrix rows 00255 kRows = D1, 00256 /// return no. of matrix columns 00257 kCols = D2, 00258 /// return no of elements: rows*columns 00259 kSize = D1*D2 00260 }; 00261 00262 /** @name --- Access functions --- */ 00263 00264 /** access the parse tree with the index starting from zero and 00265 following the C convention for the order in accessing 00266 the matrix elements. 00267 Same convention for general and symmetric matrices. 00268 */ 00269 T apply(unsigned int i) const; 00270 00271 /// return read-only pointer to internal array 00272 const T* Array() const; 00273 /// return pointer to internal array 00274 T* Array(); 00275 00276 /** @name --- STL-like interface --- 00277 The iterators access the matrix element in the order how they are 00278 stored in memory. The C (row-major) convention is used, and in the 00279 case of symmetric matrices the iterator spans only the lower diagonal 00280 block. For example for a symmetric 3x3 matrices the order of the 6 00281 elements \f${a_0,...a_5}\f$ is: 00282 \f[ 00283 M = \left( \begin{array}{ccc} 00284 a_0 & a_1 & a_3 \\ 00285 a_1 & a_2 & a_4 \\ 00286 a_3 & a_4 & a_5 \end{array} \right) 00287 \f] 00288 */ 00289 00290 /** STL iterator interface. */ 00291 iterator begin(); 00292 00293 /** STL iterator interface. */ 00294 iterator end(); 00295 00296 /** STL const_iterator interface. */ 00297 const_iterator begin() const; 00298 00299 /** STL const_iterator interface. */ 00300 const_iterator end() const; 00301 00302 /** 00303 Set matrix elements with STL iterator interface. The data will be copied into the matrix 00304 \param begin start iterator position 00305 \param end end iterator position 00306 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 00307 \param lower if true the lower triangular part is filled 00308 00309 Size of the matrix must match size of the iterators, if triang is false, otherwise the size of the 00310 triangular block. In the case of symmetric matrices triang is considered always to be true 00311 (what-ever the user specifies) and the size of the iterators must be equal to the size of the 00312 triangular block, which is the number of independent elements of a symmetric matrix: N*(N+1)/2 00313 00314 */ 00315 template<class InputIterator> 00316 void SetElements(InputIterator begin, InputIterator end, bool triang = false, bool lower = true); 00317 00318 /** 00319 Constructor with STL iterator interface. The data will be copied into the matrix 00320 \param begin start iterator position 00321 \param size iterator size 00322 \param triang if true only the triangular lower/upper part of the matrix is filled from the iterators 00323 \param lower if true the lower triangular part is filled 00324 00325 Size of the iterators must not be larger than the size of the matrix representation. 00326 In the case of symmetric matrices the size is N*(N+1)/2. 00327 00328 */ 00329 template<class InputIterator> 00330 void SetElements(InputIterator begin, unsigned int size, bool triang = false, bool lower = true); 00331 00332 00333 /** @name --- Operators --- */ 00334 /// element wise comparison 00335 bool operator==(const T& rhs) const; 00336 /// element wise comparison 00337 bool operator!=(const T& rhs) const; 00338 /// element wise comparison 00339 template <class R2> 00340 bool operator==(const SMatrix<T,D1,D2,R2>& rhs) const; 00341 /// element wise comparison 00342 bool operator!=(const SMatrix<T,D1,D2,R>& rhs) const; 00343 /// element wise comparison 00344 template <class A, class R2> 00345 bool operator==(const Expr<A,T,D1,D2,R2>& rhs) const; 00346 /// element wise comparison 00347 template <class A, class R2> 00348 bool operator!=(const Expr<A,T,D1,D2,R2>& rhs) const; 00349 00350 /// element wise comparison 00351 bool operator>(const T& rhs) const; 00352 /// element wise comparison 00353 bool operator<(const T& rhs) const; 00354 /// element wise comparison 00355 template <class R2> 00356 bool operator>(const SMatrix<T,D1,D2,R2>& rhs) const; 00357 /// element wise comparison 00358 template <class R2> 00359 bool operator<(const SMatrix<T,D1,D2,R2>& rhs) const; 00360 /// element wise comparison 00361 template <class A, class R2> 00362 bool operator>(const Expr<A,T,D1,D2,R2>& rhs) const; 00363 /// element wise comparison 00364 template <class A, class R2> 00365 bool operator<(const Expr<A,T,D1,D2,R2>& rhs) const; 00366 00367 /** 00368 read only access to matrix element, with indices starting from 0 00369 */ 00370 const T& operator()(unsigned int i, unsigned int j) const; 00371 /** 00372 read/write access to matrix element with indices starting from 0 00373 */ 00374 T& operator()(unsigned int i, unsigned int j); 00375 00376 /** 00377 read only access to matrix element, with indices starting from 0. 00378 Function will check index values and it will assert if they are wrong 00379 */ 00380 const T& At(unsigned int i, unsigned int j) const; 00381 /** 00382 read/write access to matrix element with indices starting from 0. 00383 Function will check index values and it will assert if they are wrong 00384 */ 00385 T& At(unsigned int i, unsigned int j); 00386 00387 00388 // helper class for implementing the m[i][j] operator 00389 00390 class SMatrixRow { 00391 public: 00392 SMatrixRow ( SMatrix<T,D1,D2,R> & rhs, unsigned int i ) : 00393 fMat(&rhs), fRow(i) 00394 {} 00395 T & operator[](int j) { return (*fMat)(fRow,j); } 00396 private: 00397 SMatrix<T,D1,D2,R> * fMat; 00398 unsigned int fRow; 00399 }; 00400 00401 class SMatrixRow_const { 00402 public: 00403 SMatrixRow_const ( const SMatrix<T,D1,D2,R> & rhs, unsigned int i ) : 00404 fMat(&rhs), fRow(i) 00405 {} 00406 00407 const T & operator[](int j) const { return (*fMat)(fRow, j); } 00408 00409 private: 00410 const SMatrix<T,D1,D2,R> * fMat; 00411 unsigned int fRow; 00412 }; 00413 00414 /** 00415 read only access to matrix element, with indices starting from 0 : m[i][j] 00416 */ 00417 SMatrixRow_const operator[](unsigned int i) const { return SMatrixRow_const(*this, i); } 00418 /** 00419 read/write access to matrix element with indices starting from 0 : m[i][j] 00420 */ 00421 SMatrixRow operator[](unsigned int i) { return SMatrixRow(*this, i); } 00422 00423 00424 /** 00425 addition with a scalar 00426 */ 00427 SMatrix<T,D1,D2,R>&operator+=(const T& rhs); 00428 00429 /** 00430 addition with another matrix of any compatible representation 00431 */ 00432 template <class R2> 00433 SMatrix<T,D1,D2,R>&operator+=(const SMatrix<T,D1,D2,R2>& rhs); 00434 00435 /** 00436 addition with a compatible matrix expression 00437 */ 00438 template <class A, class R2> 00439 SMatrix<T,D1,D2,R>& operator+=(const Expr<A,T,D1,D2,R2>& rhs); 00440 00441 /** 00442 subtraction with a scalar 00443 */ 00444 SMatrix<T,D1,D2,R>& operator-=(const T& rhs); 00445 00446 /** 00447 subtraction with another matrix of any compatible representation 00448 */ 00449 template <class R2> 00450 SMatrix<T,D1,D2,R>&operator-=(const SMatrix<T,D1,D2,R2>& rhs); 00451 00452 /** 00453 subtraction with a compatible matrix expression 00454 */ 00455 template <class A, class R2> 00456 SMatrix<T,D1,D2,R>& operator-=(const Expr<A,T,D1,D2,R2>& rhs); 00457 00458 /** 00459 multiplication with a scalar 00460 */ 00461 SMatrix<T,D1,D2,R>& operator*=(const T& rhs); 00462 00463 #ifndef __CINT__ 00464 00465 00466 /** 00467 multiplication with another compatible matrix (it is a real matrix multiplication) 00468 Note that this operation does not avid to create a temporary to store intermidiate result 00469 */ 00470 template <class R2> 00471 SMatrix<T,D1,D2,R>& operator*=(const SMatrix<T,D1,D2,R2>& rhs); 00472 00473 /** 00474 multiplication with a compatible matrix expression (it is a real matrix multiplication) 00475 */ 00476 template <class A, class R2> 00477 SMatrix<T,D1,D2,R>& operator*=(const Expr<A,T,D1,D2,R2>& rhs); 00478 00479 #endif 00480 00481 /** 00482 division with a scalar 00483 */ 00484 SMatrix<T,D1,D2,R>& operator/=(const T& rhs); 00485 00486 00487 00488 /** @name --- Linear Algebra Functions --- */ 00489 00490 /** 00491 Invert a square Matrix ( this method changes the current matrix). 00492 Return true if inversion is successfull. 00493 The method used for general square matrices is the LU factorization taken from Dinv routine 00494 from the CERNLIB (written in C++ from CLHEP authors) 00495 In case of symmetric matrices Bunch-Kaufman diagonal pivoting method is used 00496 (The implementation is the one written by the CLHEP authors) 00497 */ 00498 bool Invert(); 00499 00500 /** 00501 Invert a square Matrix and returns a new matrix. In case the inversion fails 00502 the current matrix is returned. 00503 \param ifail . ifail will be set to 0 when inversion is successfull. 00504 See ROOT::Math::SMatrix::Invert for the inversion algorithm 00505 */ 00506 SMatrix<T,D1,D2,R> Inverse(int & ifail ) const; 00507 00508 /** 00509 Fast Invertion of a square Matrix ( this method changes the current matrix). 00510 Return true if inversion is successfull. 00511 The method used is based on direct inversion using the Cramer rule for 00512 matrices upto 5x5. Afterwards the same defult algorithm of Invert() is used. 00513 Note that this method is faster but can suffer from much larger numerical accuracy 00514 when the condition of the matrix is large 00515 */ 00516 bool InvertFast(); 00517 00518 /** 00519 Invert a square Matrix and returns a new matrix. In case the inversion fails 00520 the current matrix is returned. 00521 \param ifail . ifail will be set to 0 when inversion is successfull. 00522 See ROOT::Math::SMatrix::InvertFast for the inversion algorithm 00523 */ 00524 SMatrix<T,D1,D2,R> InverseFast(int & ifail ) const; 00525 00526 /** 00527 Invertion of a symmetric positive defined Matrix using Choleski decomposition. 00528 ( this method changes the current matrix). 00529 Return true if inversion is successfull. 00530 The method used is based on Choleski decomposition 00531 A compile error is given if the matrix is not of type symmetric and a run-time failure if the 00532 matrix is not positive defined. 00533 For solving a linear system, it is possible to use also the function 00534 ROOT::Math::SolveChol(matrix, vector) which will be faster than performing the inversion 00535 */ 00536 bool InvertChol(); 00537 00538 /** 00539 Invert of a symmetric positive defined Matrix using Choleski decomposition. 00540 A compile error is given if the matrix is not of type symmetric and a run-time failure if the 00541 matrix is not positive defined. 00542 In case the inversion fails the current matrix is returned. 00543 \param ifail . ifail will be set to 0 when inversion is successfull. 00544 See ROOT::Math::SMatrix::InvertChol for the inversion algorithm 00545 */ 00546 SMatrix<T,D1,D2,R> InverseChol(int & ifail ) const; 00547 00548 /** 00549 determinant of square Matrix via Dfact. 00550 Return true when the calculation is successfull. 00551 \param det will contain the calculated determinant value 00552 \b Note: this will destroy the contents of the Matrix! 00553 */ 00554 bool Det(T& det); 00555 00556 /** 00557 determinant of square Matrix via Dfact. 00558 Return true when the calculation is successfull. 00559 \param det will contain the calculated determinant value 00560 \b Note: this will preserve the content of the Matrix! 00561 */ 00562 bool Det2(T& det) const; 00563 00564 00565 /** @name --- Matrix Slice Functions --- */ 00566 00567 /// place a vector in a Matrix row 00568 template <unsigned int D> 00569 SMatrix<T,D1,D2,R>& Place_in_row(const SVector<T,D>& rhs, 00570 unsigned int row, 00571 unsigned int col); 00572 /// place a vector expression in a Matrix row 00573 template <class A, unsigned int D> 00574 SMatrix<T,D1,D2,R>& Place_in_row(const VecExpr<A,T,D>& rhs, 00575 unsigned int row, 00576 unsigned int col); 00577 /// place a vector in a Matrix column 00578 template <unsigned int D> 00579 SMatrix<T,D1,D2,R>& Place_in_col(const SVector<T,D>& rhs, 00580 unsigned int row, 00581 unsigned int col); 00582 /// place a vector expression in a Matrix column 00583 template <class A, unsigned int D> 00584 SMatrix<T,D1,D2,R>& Place_in_col(const VecExpr<A,T,D>& rhs, 00585 unsigned int row, 00586 unsigned int col); 00587 /// place a matrix in this matrix 00588 template <unsigned int D3, unsigned int D4, class R2> 00589 SMatrix<T,D1,D2,R>& Place_at(const SMatrix<T,D3,D4,R2>& rhs, 00590 unsigned int row, 00591 unsigned int col); 00592 /// place a matrix expression in this matrix 00593 template <class A, unsigned int D3, unsigned int D4, class R2> 00594 SMatrix<T,D1,D2,R>& Place_at(const Expr<A,T,D3,D4,R2>& rhs, 00595 unsigned int row, 00596 unsigned int col); 00597 00598 /** 00599 return a full Matrix row as a vector (copy the content in a new vector) 00600 */ 00601 SVector<T,D2> Row(unsigned int therow) const; 00602 00603 /** 00604 return a full Matrix column as a vector (copy the content in a new vector) 00605 */ 00606 SVector<T,D1> Col(unsigned int thecol) const; 00607 00608 /** 00609 return a slice of therow as a vector starting at the colum value col0 until col0+N, 00610 where N is the size of the vector (SubVector::kSize ) 00611 Condition col0+N <= D2 00612 */ 00613 template <class SubVector> 00614 SubVector SubRow(unsigned int therow, unsigned int col0 = 0 ) const; 00615 00616 /** 00617 return a slice of the column as a vector starting at the row value row0 until row0+Dsub. 00618 where N is the size of the vector (SubVector::kSize ) 00619 Condition row0+N <= D1 00620 */ 00621 template <class SubVector> 00622 SubVector SubCol(unsigned int thecol, unsigned int row0 = 0) const; 00623 00624 /** 00625 return a submatrix with the upper left corner at the values (row0, col0) and with sizes N1, N2 00626 where N1 and N2 are the dimension of the sub-matrix (SubMatrix::kRows and SubMatrix::kCols ) 00627 Condition row0+N1 <= D1 && col0+N2 <=D2 00628 */ 00629 template <class SubMatrix > 00630 SubMatrix Sub(unsigned int row0, unsigned int col0) const; 00631 00632 /** 00633 return diagonal elements of a matrix as a Vector. 00634 It works only for squared matrices D1 == D2, otherwise it will produce a compile error 00635 */ 00636 SVector<T,D1> Diagonal() const; 00637 00638 /** 00639 Set the diagonal elements from a Vector 00640 Require that vector implements ::kSize since a check (statically) is done on 00641 diagonal size == vector size 00642 */ 00643 template <class Vector> 00644 void SetDiagonal(const Vector & v); 00645 00646 /** 00647 return the trace of a matrix 00648 Sum of the diagonal elements 00649 */ 00650 T Trace() const; 00651 00652 00653 /** 00654 return the upper Triangular block of the matrices (including the diagonal) as 00655 a vector of sizes N = D1 * (D1 + 1)/2. 00656 It works only for square matrices with D1==D2, otherwise it will produce a compile error 00657 */ 00658 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION 00659 SVector<T, D1 * (D2 +1)/2> UpperBlock() const; 00660 #else 00661 template<class SubVector> 00662 SubVector UpperBlock() const; 00663 #endif 00664 00665 /** 00666 return the lower Triangular block of the matrices (including the diagonal) as 00667 a vector of sizes N = D1 * (D1 + 1)/2. 00668 It works only for square matrices with D1==D2, otherwise it will produce a compile error 00669 */ 00670 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION 00671 SVector<T, D1 * (D2 +1)/2> LowerBlock() const; 00672 #else 00673 template<class SubVector> 00674 SubVector LowerBlock() const; 00675 #endif 00676 00677 00678 /** @name --- Other Functions --- */ 00679 00680 /** 00681 Function to check if a matrix is sharing same memory location of the passed pointer 00682 This function is used by the expression templates to avoid the alias problem during 00683 expression evaluation. When the matrix is in use, for example in operations 00684 like A = B * A, a temporary object storing the intermediate result is automatically 00685 created when evaluating the expression. 00686 00687 */ 00688 bool IsInUse(const T* p) const; 00689 00690 // submatrices 00691 00692 /// Print: used by operator<<() 00693 std::ostream& Print(std::ostream& os) const; 00694 00695 00696 00697 00698 public: 00699 00700 /** @name --- Data Member --- */ 00701 00702 /** 00703 Matrix Storage Object containing matrix data 00704 */ 00705 R fRep; 00706 00707 }; // end of class SMatrix 00708 00709 00710 00711 00712 //============================================================================== 00713 // operator<< 00714 //============================================================================== 00715 template <class T, unsigned int D1, unsigned int D2, class R> 00716 inline std::ostream& operator<<(std::ostream& os, const ROOT::Math::SMatrix<T,D1,D2,R>& rhs) { 00717 return rhs.Print(os); 00718 } 00719 00720 00721 } // namespace Math 00722 00723 } // namespace ROOT 00724 00725 00726 00727 00728 00729 00730 #ifndef __CINT__ 00731 00732 #ifndef ROOT_Math_SMatrix_icc 00733 #include "Math/SMatrix.icc" 00734 #endif 00735 00736 #ifndef ROOT_Math_MatrixFunctions 00737 #include "Math/MatrixFunctions.h" 00738 #endif 00739 00740 #endif //__CINT__ 00741 00742 #endif /* ROOT_Math_SMatrix */