4 #ifndef ROOT_Math_MatrixFunctions
5 #define ROOT_Math_MatrixFunctions
43 #ifndef ROOT_Math_BinaryOpPolicy
46 #ifndef ROOT_Math_Expression
49 #ifndef ROOT_Math_HelperOps
52 #ifndef ROOT_Math_CholeskyDecomp
60 template <
class T,
unsigned int D>
67 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
68 SVector<T,D1>
operator*(
const SMatrix<T,D1,D2,R>& rhs,
const SVector<T,D2>& lhs)
71 for(
unsigned int i=0; i<D1; ++i) {
72 const unsigned int rpos = i*D2;
73 for(
unsigned int j=0; j<D2; ++j) {
74 tmp[i] += rhs.apply(rpos+j) * lhs.apply(j);
89 template <
unsigned int I>
91 template <
class A,
class B>
92 static inline typename A::value_type
f(
const A& lhs,
const B& rhs,
93 const unsigned int offset) {
104 template <
class A,
class B>
105 static inline typename A::value_type
f(
const A& lhs,
const B& rhs,
106 const unsigned int offset) {
107 return lhs.apply(offset) * rhs.apply(0);
114 template <
class Matrix,
class Vector,
unsigned int D2>
118 typedef typename Vector::value_type
T;
128 inline typename Matrix::value_type
apply(
unsigned int i)
const {
135 return rhs_.IsInUse(p);
148 template <
unsigned int I>
150 template <
class Matrix,
class Vector>
151 static inline typename Matrix::value_type
f(
const Matrix& lhs,
const Vector& rhs,
152 const unsigned int offset) {
153 return lhs.apply(Matrix::kCols*
I+offset) * rhs.apply(
I) +
164 template <
class Matrix,
class Vector>
165 static inline typename Matrix::value_type
f(
const Matrix& lhs,
const Vector& rhs,
166 const unsigned int offset) {
167 return lhs.apply(offset) * rhs.apply(0);
179 template <
class Vector,
class Matrix,
unsigned int D1>
183 typedef typename Vector::value_type
T;
192 inline typename Matrix::value_type
apply(
unsigned int i)
const {
199 return lhs_.IsInUse(p);
217 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
227 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
228 inline VecExpr<VectorMatrixRowOp<SMatrix<T,D1,D2,R>, VecExpr<A,T,D2>, D2>,
T, D1>
237 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
238 inline VecExpr<VectorMatrixRowOp<Expr<A,T,D1,D2,R>, SVector<T,D2>, D2>,
T, D1>
247 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D2,
class R>
248 inline VecExpr<VectorMatrixRowOp<Expr<A,T,D1,D2,R>, VecExpr<B,T,D2>, D2>,
T, D1>
257 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
258 inline VecExpr<VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2,R>, D1>,
T, D2>
267 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
268 inline VecExpr<VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2,R>, D1>,
T, D2>
277 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
278 inline VecExpr<VectorMatrixColOp<VecExpr<A,T,D1>, SMatrix<T,D1,D2,R>, D1>,
T, D2>
287 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D2,
class R>
288 inline VecExpr<VectorMatrixColOp<VecExpr<A,T,D1>, Expr<B,T,D1,D2,R>, D1>,
T, D2>
297 template <
unsigned int I>
300 template <
class MatrixA,
class MatrixB>
301 static inline typename MatrixA::value_type
f(
const MatrixA& lhs,
303 const unsigned int offset) {
304 return lhs.apply(offset/MatrixB::kCols*MatrixA::kCols +
I) *
305 rhs.apply(MatrixB::kCols*
I + offset%MatrixB::kCols) +
310 template <
class MatrixA,
class MatrixB>
311 static inline typename MatrixA::value_type
g(
const MatrixA& lhs,
315 return lhs(i,
I) * rhs(
I , j) +
327 template <
class MatrixA,
class MatrixB>
328 static inline typename MatrixA::value_type
f(
const MatrixA& lhs,
330 const unsigned int offset) {
331 return lhs.apply(offset/MatrixB::kCols*MatrixA::kCols) *
332 rhs.apply(offset%MatrixB::kCols);
336 template <
class MatrixA,
class MatrixB>
337 static inline typename MatrixA::value_type
g(
const MatrixA& lhs,
339 unsigned int i,
unsigned int j) {
340 return lhs(i,0) * rhs(0,j);
353 template <
class MatrixA,
class MatrixB,
class T,
unsigned int D>
373 return lhs_.IsInUse(p) ||
rhs_.IsInUse(p);
392 template <
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
393 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>,
SMatrix<T,D,D2,R2>,
T,D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
396 return Expr<MatMulOp,
T,D1,D2,
403 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
404 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>,
T,D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
406 typedef MatrixMulOp<SMatrix<T,D1,D,R1>,
Expr<A,T,D,D2,R2>,
T,D> MatMulOp;
407 return Expr<MatMulOp,
T,D1,D2,
414 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
415 inline Expr<MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>,
T,D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
417 typedef MatrixMulOp<Expr<A,T,D1,D,R1>,
SMatrix<T,D,D2,R2>,
T,D> MatMulOp;
418 return Expr<MatMulOp,
T,D1,D2,
425 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
426 inline Expr<MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>,
T,D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
428 typedef MatrixMulOp<Expr<A,T,D1,D,R1>,
Expr<B,T,D,D2,R2>,
T,D> MatMulOp;
438 template <
class MatrixA,
class MatrixB,
unsigned int D>
442 MatrixMulOp(
const MatrixA& lhs,
const MatrixB& rhs) :
449 inline typename MatrixA::value_type
apply(
unsigned int i)
const {
462 template <
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
463 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
464 operator*(
const SMatrix<T,D1,D,R1>& lhs,
const SMatrix<T,D,D2,R2>& rhs) {
465 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, D> MatMulOp;
466 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
472 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
473 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>, D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
474 operator*(
const SMatrix<T,D1,D,R1>& lhs,
const Expr<A,T,D,D2,R2>& rhs) {
475 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>, D> MatMulOp;
476 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
482 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
483 inline Expr<MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>, D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
484 operator*(
const Expr<A,T,D1,D,R1>& lhs,
const SMatrix<T,D,D2,R2>& rhs) {
485 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>, D> MatMulOp;
486 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
492 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
493 inline Expr<MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>, D>,
T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
494 operator*(
const Expr<A,T,D1,D,R1>& lhs,
const Expr<B,T,D,D2,R2>& rhs) {
495 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>, D> MatMulOp;
496 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
508 template <
class Matrix,
class T,
unsigned int D1,
unsigned int D2=D1>
520 return rhs_.apply( (i%D1)*D2 + i/D1);
527 return rhs_.IsInUse(p);
544 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
545 inline Expr<TransposeOp<SMatrix<T,D1,D2,R>,
T,D1,D2>,
T, D2, D1,
typename TranspPolicy<T,D1,D2,R>::RepType>
555 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
556 inline Expr<TransposeOp<Expr<A,T,D1,D2,R>,
T,D1,D2>,
T, D2, D1,
typename TranspPolicy<T,D1,D2,R>::RepType>
564 #ifdef ENABLE_TEMPORARIES_TRANSPOSE
570 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
571 inline SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
572 Transpose(
const SMatrix<T,D1,D2, R>& rhs) {
573 typedef TransposeOp<SMatrix<T,D1,D2,R>,
T,D1,D2> MatTrOp;
575 return SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
576 ( Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs)) );
582 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
583 inline SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
584 Transpose(
const Expr<A,T,D1,D2,R>& rhs) {
585 typedef TransposeOp<Expr<A,T,D1,D2,R>,
T,D1,D2> MatTrOp;
587 return SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
588 ( Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs)) );
598 template <
class T,
unsigned int D,
class R>
599 inline T Product(
const SMatrix<T,D,D,R>& lhs,
const SVector<T,D>& rhs) {
600 return Dot(rhs, lhs * rhs);
606 template <
class T,
unsigned int D,
class R>
607 inline T Product(
const SVector<T,D>& lhs,
const SMatrix<T,D,D,R>& rhs) {
608 return Dot(lhs, rhs * lhs);
614 template <
class A,
class T,
unsigned int D,
class R>
615 inline T Product(
const SMatrix<T,D,D,R>& lhs,
const VecExpr<A,T,D>& rhs) {
616 return Dot(rhs, lhs * rhs);
622 template <
class A,
class T,
unsigned int D,
class R>
623 inline T Product(
const VecExpr<A,T,D>& lhs,
const SMatrix<T,D,D,R>& rhs) {
624 return Dot(lhs, rhs * lhs);
630 template <
class A,
class T,
unsigned int D,
class R>
631 inline T Product(
const SVector<T,D>& lhs,
const Expr<A,T,D,D,R>& rhs) {
632 return Dot(lhs, rhs * lhs);
638 template <
class A,
class T,
unsigned int D,
class R>
639 inline T Product(
const Expr<A,T,D,D,R>& lhs,
const SVector<T,D>& rhs) {
640 return Dot(rhs, lhs * rhs);
646 template <
class A,
class B,
class T,
unsigned int D,
class R>
647 inline T Product(
const Expr<A,T,D,D,R>& lhs,
const VecExpr<B,T,D>& rhs) {
648 return Dot(rhs, lhs * rhs);
654 template <
class A,
class B,
class T,
unsigned int D,
class R>
655 inline T Product(
const VecExpr<A,T,D>& lhs,
const Expr<B,T,D,D,R>& rhs) {
656 return Dot(lhs, rhs * lhs);
670 template <
class T,
unsigned int D,
class R>
672 return Dot(rhs, lhs * rhs);
678 template <
class T,
unsigned int D,
class R>
680 return Dot(lhs, rhs * lhs);
686 template <
class A,
class T,
unsigned int D,
class R>
688 return Dot(rhs, lhs * rhs);
694 template <
class A,
class T,
unsigned int D,
class R>
696 return Dot(lhs, rhs * lhs);
702 template <
class A,
class T,
unsigned int D,
class R>
704 return Dot(lhs, rhs * lhs);
710 template <
class A,
class T,
unsigned int D,
class R>
712 return Dot(rhs, lhs * rhs);
718 template <
class A,
class B,
class T,
unsigned int D,
class R>
720 return Dot(rhs, lhs * rhs);
726 template <
class A,
class B,
class T,
unsigned int D,
class R>
728 return Dot(lhs, rhs * lhs);
743 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
744 inline SMatrix<T,D1,D1,MatRepSym<T,D1> >
Similarity(
const SMatrix<T,D1,D2,R>& lhs,
const SMatrix<
T,D2,D2,
MatRepSym<T,D2> >& rhs) {
757 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
758 inline SMatrix<T,D1,D1,MatRepSym<T,D1> >
Similarity(
const Expr<A,T,D1,D2,R>& lhs,
const SMatrix<
T,D2,D2,
MatRepSym<T,D2> >& rhs) {
772 template <
class T,
unsigned int D1>
773 inline SMatrix<T,D1,D1,MatRepSym<T,D1> >
Similarity(
const SMatrix<
T,D1,D1,MatRepSym<T,D1> >& lhs,
const SMatrix<
T,D1,D1,MatRepSym<T,D1> >& rhs) {
774 SMatrix<T,D1,D1, MatRepStd<T,D1,D1> > tmp = lhs * rhs;
775 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
793 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
794 inline SMatrix<T,D2,D2,MatRepSym<T,D2> >
SimilarityT(
const SMatrix<T,D1,D2,R>& lhs,
const SMatrix<
T,D1,D1,
MatRepSym<T,D1> >& rhs) {
807 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
808 inline SMatrix<T,D2,D2,MatRepSym<T,D2> >
SimilarityT(
const Expr<A,T,D1,D2,R>& lhs,
const SMatrix<
T,D1,D1,
MatRepSym<T,D1> >& rhs) {
842 template <
class Vector1,
class Vector2>
854 inline typename Vector1::value_type
apply(
unsigned int i)
const {
857 inline typename Vector1::value_type
operator() (
unsigned int i,
unsigned j)
const {
858 return lhs_.apply(i) *
rhs_.apply(j);
861 inline bool IsInUse (
const typename Vector1::value_type * )
const {
889 template <
class T,
unsigned int D1,
unsigned int D2>
899 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
900 inline Expr<TensorMulOp<VecExpr<A,T,D1>, SVector<T,D2> >,
T, D1, D2 >
909 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
910 inline Expr<TensorMulOp<SVector<T,D1>, VecExpr<A,T,D2> >,
T, D1, D2 >
920 template <
class T,
unsigned int D1,
unsigned int D2,
class A,
class B>
921 inline Expr<TensorMulOp<VecExpr<A,T,D1>, VecExpr<B,T,D2> >,
T, D1, D2 >
934 template <
class T,
unsigned int D1,
unsigned int D2>
935 inline SMatrix<T,D1,D2>
TensorProd(
const SVector<T,D1>& lhs,
const SVector<T,D2>& rhs) {
936 SMatrix<T,D1,D2> tmp;
937 for (
unsigned int i=0; i< D1; ++i)
938 for (
unsigned int j=0; j< D2; ++j) {
939 tmp(i,j) = lhs[i]*rhs[j];
947 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
948 inline SMatrix<T,D1,D2>
TensorProd(
const VecExpr<A,T,D1>& lhs,
const SVector<T,D2>& rhs) {
949 SMatrix<T,D1,D2> tmp;
950 for (
unsigned int i=0; i< D1; ++i)
951 for (
unsigned int j=0; j< D2; ++j)
952 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
959 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
960 inline SMatrix<T,D1,D2>
TensorProd(
const SVector<T,D1>& lhs,
const VecExpr<A,T,D2>& rhs) {
961 SMatrix<T,D1,D2> tmp;
962 for (
unsigned int i=0; i< D1; ++i)
963 for (
unsigned int j=0; j< D2; ++j)
964 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
973 template <
class T,
unsigned int D1,
unsigned int D2,
class A,
class B>
974 inline SMatrix<T,D1,D2 >
TensorProd(
const VecExpr<A,T,D1>& lhs,
const VecExpr<B,T,D2>& rhs) {
975 SMatrix<T,D1,D2> tmp;
976 for (
unsigned int i=0; i< D1; ++i)
977 for (
unsigned int j=0; j< D2; ++j)
978 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
990 template <
class T,
unsigned int D>
993 return decomp.
Solve(vec);
998 template <
class T,
unsigned int D>
1003 ifail = (ok) ? 0 : -1;
T Dot(const SVector< T, D > &lhs, const SVector< T, D > &rhs)
Vector dot product.
Class for Vector-Matrix multiplication.
T Similarity(const SMatrix< T, D, D, R > &lhs, const SVector< T, D > &rhs)
Similarity Vector - Matrix Product: v^T * A * v returning a scalar value of type T ...
static Double_t Product(const Double_t *x, const Float_t *y)
Product.
Class for Tensor Multiplication (outer product) of two vectors giving a matrix.
Class for Matrix-Matrix multiplication.
VectorMatrixRowOp(const Matrix &lhs, const Vector &rhs)
MatRepSym Matrix storage representation for a symmetric matrix of dimension NxN This class is a templ...
bool IsInUse(const typename Vector1::value_type *) const
T apply(unsigned int i) const
Matrix::value_type apply(unsigned int i) const
calc
Class for Transpose Operations.
Expr< TransposeOp< SMatrix< T, D1, D2, R >, T, D1, D2 >, T, D2, D1, typename TranspPolicy< T, D1, D2, R >::RepType > Transpose(const SMatrix< T, D1, D2, R > &rhs)
Matrix Transpose B(i,j) = A(j,i) returning a matrix expression.
bool SolveChol(SMatrix< T, D, D, MatRepSym< T, D > > &mat, SVector< T, D > &vec)
T operator()(unsigned int i, unsigned j) const
bool IsInUse(const T *p) const
TensorMulOp(const Vector1 &lhs, const Vector2 &rhs)
header file containing the templated implementation of matrix inversion routines for use with ROOT's ...
bool IsInUse(const T *p) const
class to compute the Cholesky decomposition of a matrix
SMatrix: a generic fixed size D1 x D2 Matrix class.
TransposeOp(const Matrix &rhs)
Expression wrapper class for Matrix objects.
Vector1::value_type apply(unsigned int i) const
Vector2::kSize is the number of columns in the resulting matrix.
T operator()(unsigned int i, unsigned j) const
VectorMatrixColOp(const Vector &lhs, const Matrix &rhs)
bool IsInUse(const T *p) const
T apply(unsigned int i) const
calc
bool Solve(V &rhs) const
solves a linear system for the given right hand side
Expr< TensorMulOp< SVector< T, D1 >, SVector< T, D2 > >, T, D1, D2 > TensorProd(const SVector< T, D1 > &lhs, const SVector< T, D2 > &rhs)
Tensor Vector Product : M(i,j) = v(i) * v(j) returning a matrix expression.
static void Evaluate(SMatrix< T, D, D, MatRepSym< T, D > > &lhs, const Expr< A, T, D, D, R > &rhs)
assign a symmetric matrix from an expression
bool IsInUse(const T *p) const
MatrixMulOp(const MatrixA &lhs, const MatrixB &rhs)
Expression wrapper class for Vector objects.
Vector1::value_type operator()(unsigned int i, unsigned j) const
SMatrix< T, D2, D2, MatRepSym< T, D2 > > SimilarityT(const SMatrix< T, D1, D2, R > &lhs, const SMatrix< T, D1, D1, MatRepSym< T, D1 > > &rhs)
Transpose Similarity Matrix Product : B = U^T * A * U for A symmetric returning a symmetric matrix ex...
Matrix::value_type apply(unsigned int i) const
calc
AxisAngle operator*(RotationX const &r1, AxisAngle const &r2)
Multiplication of an axial rotation by an AxisAngle.
SVector: a generic fixed size Vector class.