4 #ifndef ROOT_Math_MatrixFunctions
5 #define ROOT_Math_MatrixFunctions
52 template <
class T,
unsigned int D>
59 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
60 SVector<T,D1> operator*(
const SMatrix<T,D1,D2,R>& rhs,
const SVector<T,D2>& lhs)
63 for(
unsigned int i=0; i<D1; ++i) {
64 const unsigned int rpos = i*D2;
65 for(
unsigned int j=0; j<D2; ++j) {
66 tmp[i] += rhs.apply(rpos+j) * lhs.apply(j);
81 template <
unsigned int I>
83 template <
class A,
class B>
84 static inline typename A::value_type f(
const A& lhs,
const B& rhs,
85 const unsigned int offset) {
86 return lhs.apply(offset+I) * rhs.apply(I) + meta_row_dot<I-1>::f(lhs,rhs,offset);
95 struct meta_row_dot<0> {
96 template <
class A,
class B>
97 static inline typename A::value_type f(
const A& lhs,
const B& rhs,
98 const unsigned int offset) {
99 return lhs.apply(offset) * rhs.apply(0);
106 template <
class Matrix,
class Vector,
unsigned int D2>
107 class VectorMatrixRowOp {
110 typedef typename Vector::value_type T;
113 VectorMatrixRowOp(
const Matrix& lhs,
const Vector& rhs) :
114 lhs_(lhs), rhs_(rhs) {}
117 ~VectorMatrixRowOp() {}
120 inline typename Matrix::value_type apply(
unsigned int i)
const {
121 return meta_row_dot<D2-1>::f(lhs_, rhs_, i*D2);
126 inline bool IsInUse (
const T * p)
const {
127 return rhs_.IsInUse(p);
140 template <
unsigned int I>
141 struct meta_col_dot {
142 template <
class Matrix,
class Vector>
143 static inline typename Matrix::value_type f(
const Matrix& lhs,
const Vector& rhs,
144 const unsigned int offset) {
145 return lhs.apply(Matrix::kCols*I+offset) * rhs.apply(I) +
146 meta_col_dot<I-1>::f(lhs,rhs,offset);
155 struct meta_col_dot<0> {
156 template <
class Matrix,
class Vector>
157 static inline typename Matrix::value_type f(
const Matrix& lhs,
const Vector& rhs,
158 const unsigned int offset) {
159 return lhs.apply(offset) * rhs.apply(0);
171 template <
class Vector,
class Matrix,
unsigned int D1>
172 class VectorMatrixColOp {
175 typedef typename Vector::value_type T;
177 VectorMatrixColOp(
const Vector& lhs,
const Matrix& rhs) :
178 lhs_(lhs), rhs_(rhs) {}
181 ~VectorMatrixColOp() {}
184 inline typename Matrix::value_type apply(
unsigned int i)
const {
185 return meta_col_dot<D1-1>::f(rhs_, lhs_, i);
190 inline bool IsInUse (
const T * p)
const {
191 return lhs_.IsInUse(p);
209 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
210 inline VecExpr<VectorMatrixRowOp<SMatrix<T,D1,D2,R>,SVector<T,D2>, D2>, T, D1>
211 operator*(
const SMatrix<T,D1,D2,R>& lhs,
const SVector<T,D2>& rhs) {
212 typedef VectorMatrixRowOp<SMatrix<T,D1,D2,R>,SVector<T,D2>, D2> VMOp;
213 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
219 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
220 inline VecExpr<VectorMatrixRowOp<SMatrix<T,D1,D2,R>, VecExpr<A,T,D2>, D2>, T, D1>
221 operator*(
const SMatrix<T,D1,D2,R>& lhs,
const VecExpr<A,T,D2>& rhs) {
222 typedef VectorMatrixRowOp<SMatrix<T,D1,D2,R>,VecExpr<A,T,D2>, D2> VMOp;
223 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
229 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
230 inline VecExpr<VectorMatrixRowOp<Expr<A,T,D1,D2,R>, SVector<T,D2>, D2>, T, D1>
231 operator*(
const Expr<A,T,D1,D2,R>& lhs,
const SVector<T,D2>& rhs) {
232 typedef VectorMatrixRowOp<Expr<A,T,D1,D2,R>,SVector<T,D2>, D2> VMOp;
233 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
239 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D2,
class R>
240 inline VecExpr<VectorMatrixRowOp<Expr<A,T,D1,D2,R>, VecExpr<B,T,D2>, D2>, T, D1>
241 operator*(
const Expr<A,T,D1,D2,R>& lhs,
const VecExpr<B,T,D2>& rhs) {
242 typedef VectorMatrixRowOp<Expr<A,T,D1,D2,R>,VecExpr<B,T,D2>, D2> VMOp;
243 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
249 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
250 inline VecExpr<VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2,R>, D1>, T, D2>
251 operator*(
const SVector<T,D1>& lhs,
const SMatrix<T,D1,D2,R>& rhs) {
252 typedef VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2,R>, D1> VMOp;
253 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
259 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
260 inline VecExpr<VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2,R>, D1>, T, D2>
261 operator*(
const SVector<T,D1>& lhs,
const Expr<A,T,D1,D2,R>& rhs) {
262 typedef VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2,R>, D1> VMOp;
263 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
269 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
270 inline VecExpr<VectorMatrixColOp<VecExpr<A,T,D1>, SMatrix<T,D1,D2,R>, D1>, T, D2>
271 operator*(
const VecExpr<A,T,D1>& lhs,
const SMatrix<T,D1,D2,R>& rhs) {
272 typedef VectorMatrixColOp<VecExpr<A,T,D1>, SMatrix<T,D1,D2,R>, D1> VMOp;
273 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
279 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D2,
class R>
280 inline VecExpr<VectorMatrixColOp<VecExpr<A,T,D1>, Expr<B,T,D1,D2,R>, D1>, T, D2>
281 operator*(
const VecExpr<A,T,D1>& lhs,
const Expr<B,T,D1,D2,R>& rhs) {
282 typedef VectorMatrixColOp<VecExpr<A,T,D1>, Expr<B,T,D1,D2,R>, D1> VMOp;
283 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
289 template <
unsigned int I>
290 struct meta_matrix_dot {
292 template <
class MatrixA,
class MatrixB>
293 static inline typename MatrixA::value_type f(
const MatrixA& lhs,
295 const unsigned int offset) {
296 return lhs.apply(offset/MatrixB::kCols*MatrixA::kCols + I) *
297 rhs.apply(MatrixB::kCols*I + offset%MatrixB::kCols) +
298 meta_matrix_dot<I-1>::f(lhs,rhs,offset);
302 template <
class MatrixA,
class MatrixB>
303 static inline typename MatrixA::value_type g(
const MatrixA& lhs,
307 return lhs(i, I) * rhs(I , j) +
308 meta_matrix_dot<I-1>::g(lhs,rhs,i,j);
317 struct meta_matrix_dot<0> {
319 template <
class MatrixA,
class MatrixB>
320 static inline typename MatrixA::value_type f(
const MatrixA& lhs,
322 const unsigned int offset) {
323 return lhs.apply(offset/MatrixB::kCols*MatrixA::kCols) *
324 rhs.apply(offset%MatrixB::kCols);
328 template <
class MatrixA,
class MatrixB>
329 static inline typename MatrixA::value_type g(
const MatrixA& lhs,
331 unsigned int i,
unsigned int j) {
332 return lhs(i,0) * rhs(0,j);
345 template <
class MatrixA,
class MatrixB,
class T,
unsigned int D>
349 MatrixMulOp(
const MatrixA& lhs,
const MatrixB& rhs) :
350 lhs_(lhs), rhs_(rhs) {}
356 inline T apply(
unsigned int i)
const {
357 return meta_matrix_dot<D-1>::f(lhs_, rhs_, i);
360 inline T operator() (
unsigned int i,
unsigned j)
const {
361 return meta_matrix_dot<D-1>::g(lhs_, rhs_, i, j);
364 inline bool IsInUse (
const T * p)
const {
365 return lhs_.IsInUse(p) || rhs_.IsInUse(p);
384 template <
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
385 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>,T,D>, T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
386 operator*(
const SMatrix<T,D1,D,R1>& lhs,
const SMatrix<T,D,D2,R2>& rhs) {
387 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, T,D> MatMulOp;
388 return Expr<MatMulOp,T,D1,D2,
389 typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
395 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
396 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>
397 operator*(
const SMatrix<T,D1,D,R1>& lhs,
const Expr<A,T,D,D2,R2>& rhs) {
398 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>,T,D> MatMulOp;
399 return Expr<MatMulOp,T,D1,D2,
400 typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
406 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
407 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>
408 operator*(
const Expr<A,T,D1,D,R1>& lhs,
const SMatrix<T,D,D2,R2>& rhs) {
409 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>,T,D> MatMulOp;
410 return Expr<MatMulOp,T,D1,D2,
411 typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
417 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
418 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>
419 operator*(
const Expr<A,T,D1,D,R1>& lhs,
const Expr<B,T,D,D2,R2>& rhs) {
420 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>, T,D> MatMulOp;
421 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
430 template <
class MatrixA,
class MatrixB,
unsigned int D>
434 MatrixMulOp(
const MatrixA& lhs,
const MatrixB& rhs) :
435 lhs_(lhs), rhs_(rhs) {}
441 inline typename MatrixA::value_type apply(
unsigned int i)
const {
442 return meta_matrix_dot<D-1>::f(lhs_, rhs_, i);
454 template <
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
455 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, D>, T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
456 operator*(
const SMatrix<T,D1,D,R1>& lhs,
const SMatrix<T,D,D2,R2>& rhs) {
457 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, D> MatMulOp;
458 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
464 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
465 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>, D>, T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
466 operator*(
const SMatrix<T,D1,D,R1>& lhs,
const Expr<A,T,D,D2,R2>& rhs) {
467 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>, D> MatMulOp;
468 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
474 template <
class A,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
475 inline Expr<MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>, D>, T, D1, D2,
typename MultPolicy<T,R1,R2>::RepType>
476 operator*(
const Expr<A,T,D1,D,R1>& lhs,
const SMatrix<T,D,D2,R2>& rhs) {
477 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>, D> MatMulOp;
478 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
484 template <
class A,
class B,
class T,
unsigned int D1,
unsigned int D,
unsigned int D2,
class R1,
class R2>
485 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>
486 operator*(
const Expr<A,T,D1,D,R1>& lhs,
const Expr<B,T,D,D2,R2>& rhs) {
487 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>, D> MatMulOp;
488 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
500 template <
class Matrix,
class T,
unsigned int D1,
unsigned int D2=D1>
504 TransposeOp(
const Matrix& rhs) :
511 inline T apply(
unsigned int i)
const {
512 return rhs_.apply( (i%D1)*D2 + i/D1);
514 inline T operator() (
unsigned int i,
unsigned j)
const {
518 inline bool IsInUse (
const T * p)
const {
519 return rhs_.IsInUse(p);
536 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
537 inline Expr<TransposeOp<SMatrix<T,D1,D2,R>,T,D1,D2>, T, D2, D1,
typename TranspPolicy<T,D1,D2,R>::RepType>
538 Transpose(
const SMatrix<T,D1,D2, R>& rhs) {
539 typedef TransposeOp<SMatrix<T,D1,D2,R>,T,D1,D2> MatTrOp;
541 return Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs));
547 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
548 inline Expr<TransposeOp<Expr<A,T,D1,D2,R>,T,D1,D2>, T, D2, D1,
typename TranspPolicy<T,D1,D2,R>::RepType>
549 Transpose(
const Expr<A,T,D1,D2,R>& rhs) {
550 typedef TransposeOp<Expr<A,T,D1,D2,R>,T,D1,D2> MatTrOp;
552 return Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs));
556 #ifdef ENABLE_TEMPORARIES_TRANSPOSE
562 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
563 inline SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
564 Transpose(
const SMatrix<T,D1,D2, R>& rhs) {
565 typedef TransposeOp<SMatrix<T,D1,D2,R>,T,D1,D2> MatTrOp;
567 return SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
568 ( Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs)) );
574 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
575 inline SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
576 Transpose(
const Expr<A,T,D1,D2,R>& rhs) {
577 typedef TransposeOp<Expr<A,T,D1,D2,R>,T,D1,D2> MatTrOp;
579 return SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
580 ( Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs)) );
590 template <
class T,
unsigned int D,
class R>
591 inline T Product(
const SMatrix<T,D,D,R>& lhs,
const SVector<T,D>& rhs) {
592 return Dot(rhs, lhs * rhs);
598 template <
class T,
unsigned int D,
class R>
599 inline T Product(
const SVector<T,D>& lhs,
const SMatrix<T,D,D,R>& rhs) {
600 return Dot(lhs, rhs * lhs);
606 template <
class A,
class T,
unsigned int D,
class R>
607 inline T Product(
const SMatrix<T,D,D,R>& lhs,
const VecExpr<A,T,D>& rhs) {
608 return Dot(rhs, lhs * rhs);
614 template <
class A,
class T,
unsigned int D,
class R>
615 inline T Product(
const VecExpr<A,T,D>& lhs,
const SMatrix<T,D,D,R>& rhs) {
616 return Dot(lhs, rhs * lhs);
622 template <
class A,
class T,
unsigned int D,
class R>
623 inline T Product(
const SVector<T,D>& lhs,
const Expr<A,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 Expr<A,T,D,D,R>& lhs,
const SVector<T,D>& rhs) {
632 return Dot(rhs, lhs * rhs);
638 template <
class A,
class B,
class T,
unsigned int D,
class R>
639 inline T Product(
const Expr<A,T,D,D,R>& lhs,
const VecExpr<B,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 VecExpr<A,T,D>& lhs,
const Expr<B,T,D,D,R>& rhs) {
648 return Dot(lhs, rhs * lhs);
662 template <
class T,
unsigned int D,
class R>
663 inline T Similarity(
const SMatrix<T,D,D,R>& lhs,
const SVector<T,D>& rhs) {
664 return Dot(rhs, lhs * rhs);
670 template <
class T,
unsigned int D,
class R>
671 inline T Similarity(
const SVector<T,D>& lhs,
const SMatrix<T,D,D,R>& rhs) {
672 return Dot(lhs, rhs * lhs);
678 template <
class A,
class T,
unsigned int D,
class R>
679 inline T Similarity(
const SMatrix<T,D,D,R>& lhs,
const VecExpr<A,T,D>& rhs) {
680 return Dot(rhs, lhs * rhs);
686 template <
class A,
class T,
unsigned int D,
class R>
687 inline T Similarity(
const VecExpr<A,T,D>& lhs,
const SMatrix<T,D,D,R>& rhs) {
688 return Dot(lhs, rhs * lhs);
694 template <
class A,
class T,
unsigned int D,
class R>
695 inline T Similarity(
const SVector<T,D>& lhs,
const Expr<A,T,D,D,R>& rhs) {
696 return Dot(lhs, rhs * lhs);
702 template <
class A,
class T,
unsigned int D,
class R>
703 inline T Similarity(
const Expr<A,T,D,D,R>& lhs,
const SVector<T,D>& rhs) {
704 return Dot(rhs, lhs * rhs);
710 template <
class A,
class B,
class T,
unsigned int D,
class R>
711 inline T Similarity(
const Expr<A,T,D,D,R>& lhs,
const VecExpr<B,T,D>& rhs) {
712 return Dot(rhs, lhs * rhs);
718 template <
class A,
class B,
class T,
unsigned int D,
class R>
719 inline T Similarity(
const VecExpr<A,T,D>& lhs,
const Expr<B,T,D,D,R>& rhs) {
720 return Dot(lhs, rhs * lhs);
735 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
736 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) {
737 SMatrix<T,D1,D2, MatRepStd<T,D1,D2> > tmp = lhs * rhs;
738 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
740 AssignSym::Evaluate(mret, tmp * Transpose(lhs) );
749 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
750 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) {
751 SMatrix<T,D1,D2,MatRepStd<T,D1,D2> > tmp = lhs * rhs;
752 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
754 AssignSym::Evaluate(mret, tmp * Transpose(lhs) );
764 template <
class T,
unsigned int D1>
765 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) {
766 SMatrix<T,D1,D1, MatRepStd<T,D1,D1> > tmp = lhs * rhs;
767 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
769 AssignSym::Evaluate(mret, tmp * lhs );
785 template <
class T,
unsigned int D1,
unsigned int D2,
class R>
786 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) {
787 SMatrix<T,D1,D2,MatRepStd<T,D1,D2> > tmp = rhs * lhs;
788 typedef SMatrix<T,D2,D2,MatRepSym<T,D2> > SMatrixSym;
790 AssignSym::Evaluate(mret, Transpose(lhs) * tmp );
799 template <
class A,
class T,
unsigned int D1,
unsigned int D2,
class R>
800 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) {
801 SMatrix<T,D1,D2,MatRepStd<T,D1,D2> > tmp = rhs * lhs;
802 typedef SMatrix<T,D2,D2,MatRepSym<T,D2> > SMatrixSym;
804 AssignSym::Evaluate(mret, Transpose(lhs) * tmp );
834 template <
class Vector1,
class Vector2>
838 TensorMulOp(
const Vector1 & lhs,
const Vector2 & rhs) :
846 inline typename Vector1::value_type apply(
unsigned int i)
const {
847 return lhs_.apply( i/ Vector2::kSize) * rhs_.apply( i % Vector2::kSize );
849 inline typename Vector1::value_type operator() (
unsigned int i,
unsigned j)
const {
850 return lhs_.apply(i) * rhs_.apply(j);
853 inline bool IsInUse (
const typename Vector1::value_type * )
const {
860 const Vector1 & lhs_;
861 const Vector2 & rhs_;
881 template <
class T,
unsigned int D1,
unsigned int D2>
882 inline Expr<TensorMulOp<SVector<T,D1>, SVector<T,D2> >, T, D1, D2 >
883 TensorProd(
const SVector<T,D1>& lhs,
const SVector<T,D2>& rhs) {
884 typedef TensorMulOp<SVector<T,D1>, SVector<T,D2> > TVMulOp;
885 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
891 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
892 inline Expr<TensorMulOp<VecExpr<A,T,D1>, SVector<T,D2> >, T, D1, D2 >
893 TensorProd(
const VecExpr<A,T,D1>& lhs,
const SVector<T,D2>& rhs) {
894 typedef TensorMulOp<VecExpr<A,T,D1>, SVector<T,D2> > TVMulOp;
895 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
901 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
902 inline Expr<TensorMulOp<SVector<T,D1>, VecExpr<A,T,D2> >, T, D1, D2 >
903 TensorProd(
const SVector<T,D1>& lhs,
const VecExpr<A,T,D2>& rhs) {
904 typedef TensorMulOp<SVector<T,D1>, VecExpr<A,T,D2> > TVMulOp;
905 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
912 template <
class T,
unsigned int D1,
unsigned int D2,
class A,
class B>
913 inline Expr<TensorMulOp<VecExpr<A,T,D1>, VecExpr<B,T,D2> >, T, D1, D2 >
914 TensorProd(
const VecExpr<A,T,D1>& lhs,
const VecExpr<B,T,D2>& rhs) {
915 typedef TensorMulOp<VecExpr<A,T,D1>, VecExpr<B,T,D2> > TVMulOp;
916 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
926 template <
class T,
unsigned int D1,
unsigned int D2>
927 inline SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> TensorProd(
const SVector<T,D1>& lhs,
const SVector<T,D2>& rhs) {
928 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
929 for (
unsigned int i=0; i< D1; ++i)
930 for (
unsigned int j=0; j< D2; ++j) {
931 tmp(i,j) = lhs[i]*rhs[j];
939 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
940 inline SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> TensorProd(
const VecExpr<A,T,D1>& lhs,
const SVector<T,D2>& rhs) {
941 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
942 for (
unsigned int i=0; i< D1; ++i)
943 for (
unsigned int j=0; j< D2; ++j)
944 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
951 template <
class T,
unsigned int D1,
unsigned int D2,
class A>
952 inline SMatrix<T,D1,D2, MatRepStd<T, D1, D2>> TensorProd(
const SVector<T,D1>& lhs,
const VecExpr<A,T,D2>& rhs) {
953 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
954 for (
unsigned int i=0; i< D1; ++i)
955 for (
unsigned int j=0; j< D2; ++j)
956 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
965 template <
class T,
unsigned int D1,
unsigned int D2,
class A,
class B>
966 inline SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> TensorProd(
const VecExpr<A,T,D1>& lhs,
const VecExpr<B,T,D2>& rhs) {
967 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
968 for (
unsigned int i=0; i< D1; ++i)
969 for (
unsigned int j=0; j< D2; ++j)
970 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
982 template <
class T,
unsigned int D>
983 bool SolveChol( SMatrix<T, D, D, MatRepSym<T, D> > & mat, SVector<T, D> & vec ) {
984 CholeskyDecomp<T, D> decomp(mat);
985 return decomp.Solve(vec);
990 template <
class T,
unsigned int D>
991 SVector<T,D> SolveChol(
const SMatrix<T, D, D, MatRepSym<T, D> > & mat,
const SVector<T, D> & vec,
int & ifail ) {
992 SMatrix<T, D, D, MatRepSym<T, D> > atmp(mat);
993 SVector<T,D> vret(vec);
994 bool ok = SolveChol( atmp, vret);
995 ifail = (ok) ? 0 : -1;