File indexing completed on 2025-01-18 10:10:19
0001
0002
0003
0004 #ifndef ROOT_Math_MatrixFunctions
0005 #define ROOT_Math_MatrixFunctions
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #include "Math/BinaryOpPolicy.h"
0046 #include "Math/Expression.h"
0047 #include "Math/HelperOps.h"
0048 #include "Math/CholeskyDecomp.h"
0049
0050 namespace ROOT {
0051
0052 namespace Math {
0053
0054 template <class T, unsigned int D>
0055 class SVector;
0056
0057 #ifdef XXX
0058
0059
0060
0061 template <class T, unsigned int D1, unsigned int D2, class R>
0062 SVector<T,D1> operator*(const SMatrix<T,D1,D2,R>& rhs, const SVector<T,D2>& lhs)
0063 {
0064 SVector<T,D1> tmp;
0065 for(unsigned int i=0; i<D1; ++i) {
0066 const unsigned int rpos = i*D2;
0067 for(unsigned int j=0; j<D2; ++j) {
0068 tmp[i] += rhs.apply(rpos+j) * lhs.apply(j);
0069 }
0070 }
0071 return tmp;
0072 }
0073 #endif
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 template <unsigned int I>
0084 struct meta_row_dot {
0085 template <class A, class B>
0086 static inline typename A::value_type f(const A& lhs, const B& rhs,
0087 const unsigned int offset) {
0088 return lhs.apply(offset+I) * rhs.apply(I) + meta_row_dot<I-1>::f(lhs,rhs,offset);
0089 }
0090 };
0091
0092
0093
0094
0095
0096 template <>
0097 struct meta_row_dot<0> {
0098 template <class A, class B>
0099 static inline typename A::value_type f(const A& lhs, const B& rhs,
0100 const unsigned int offset) {
0101 return lhs.apply(offset) * rhs.apply(0);
0102 }
0103 };
0104
0105
0106
0107
0108 template <class Matrix, class Vector, unsigned int D2>
0109 class VectorMatrixRowOp {
0110 public:
0111
0112 typedef typename Vector::value_type T;
0113
0114
0115 VectorMatrixRowOp(const Matrix& lhs, const Vector& rhs) :
0116 lhs_(lhs), rhs_(rhs) {}
0117
0118
0119 ~VectorMatrixRowOp() {}
0120
0121
0122 inline typename Matrix::value_type apply(unsigned int i) const {
0123 return meta_row_dot<D2-1>::f(lhs_, rhs_, i*D2);
0124 }
0125
0126
0127
0128 inline bool IsInUse (const T * p) const {
0129 return rhs_.IsInUse(p);
0130 }
0131
0132
0133 protected:
0134 const Matrix& lhs_;
0135 const Vector& rhs_;
0136 };
0137
0138
0139
0140
0141
0142 template <unsigned int I>
0143 struct meta_col_dot {
0144 template <class Matrix, class Vector>
0145 static inline typename Matrix::value_type f(const Matrix& lhs, const Vector& rhs,
0146 const unsigned int offset) {
0147 return lhs.apply(Matrix::kCols*I+offset) * rhs.apply(I) +
0148 meta_col_dot<I-1>::f(lhs,rhs,offset);
0149 }
0150 };
0151
0152
0153
0154
0155
0156 template <>
0157 struct meta_col_dot<0> {
0158 template <class Matrix, class Vector>
0159 static inline typename Matrix::value_type f(const Matrix& lhs, const Vector& rhs,
0160 const unsigned int offset) {
0161 return lhs.apply(offset) * rhs.apply(0);
0162 }
0163 };
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 template <class Vector, class Matrix, unsigned int D1>
0174 class VectorMatrixColOp {
0175 public:
0176
0177 typedef typename Vector::value_type T;
0178
0179 VectorMatrixColOp(const Vector& lhs, const Matrix& rhs) :
0180 lhs_(lhs), rhs_(rhs) {}
0181
0182
0183 ~VectorMatrixColOp() {}
0184
0185
0186 inline typename Matrix::value_type apply(unsigned int i) const {
0187 return meta_col_dot<D1-1>::f(rhs_, lhs_, i);
0188 }
0189
0190
0191
0192 inline bool IsInUse (const T * p) const {
0193 return lhs_.IsInUse(p);
0194 }
0195
0196
0197 protected:
0198 const Vector& lhs_;
0199 const Matrix& rhs_;
0200 };
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 template <class T, unsigned int D1, unsigned int D2, class R>
0212 inline VecExpr<VectorMatrixRowOp<SMatrix<T,D1,D2,R>,SVector<T,D2>, D2>, T, D1>
0213 operator*(const SMatrix<T,D1,D2,R>& lhs, const SVector<T,D2>& rhs) {
0214 typedef VectorMatrixRowOp<SMatrix<T,D1,D2,R>,SVector<T,D2>, D2> VMOp;
0215 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
0216 }
0217
0218
0219
0220
0221 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0222 inline VecExpr<VectorMatrixRowOp<SMatrix<T,D1,D2,R>, VecExpr<A,T,D2>, D2>, T, D1>
0223 operator*(const SMatrix<T,D1,D2,R>& lhs, const VecExpr<A,T,D2>& rhs) {
0224 typedef VectorMatrixRowOp<SMatrix<T,D1,D2,R>,VecExpr<A,T,D2>, D2> VMOp;
0225 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
0226 }
0227
0228
0229
0230
0231 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0232 inline VecExpr<VectorMatrixRowOp<Expr<A,T,D1,D2,R>, SVector<T,D2>, D2>, T, D1>
0233 operator*(const Expr<A,T,D1,D2,R>& lhs, const SVector<T,D2>& rhs) {
0234 typedef VectorMatrixRowOp<Expr<A,T,D1,D2,R>,SVector<T,D2>, D2> VMOp;
0235 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
0236 }
0237
0238
0239
0240
0241 template <class A, class B, class T, unsigned int D1, unsigned int D2, class R>
0242 inline VecExpr<VectorMatrixRowOp<Expr<A,T,D1,D2,R>, VecExpr<B,T,D2>, D2>, T, D1>
0243 operator*(const Expr<A,T,D1,D2,R>& lhs, const VecExpr<B,T,D2>& rhs) {
0244 typedef VectorMatrixRowOp<Expr<A,T,D1,D2,R>,VecExpr<B,T,D2>, D2> VMOp;
0245 return VecExpr<VMOp, T, D1>(VMOp(lhs,rhs));
0246 }
0247
0248
0249
0250
0251 template <class T, unsigned int D1, unsigned int D2, class R>
0252 inline VecExpr<VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2,R>, D1>, T, D2>
0253 operator*(const SVector<T,D1>& lhs, const SMatrix<T,D1,D2,R>& rhs) {
0254 typedef VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2,R>, D1> VMOp;
0255 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
0256 }
0257
0258
0259
0260
0261 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0262 inline VecExpr<VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2,R>, D1>, T, D2>
0263 operator*(const SVector<T,D1>& lhs, const Expr<A,T,D1,D2,R>& rhs) {
0264 typedef VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2,R>, D1> VMOp;
0265 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
0266 }
0267
0268
0269
0270
0271 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0272 inline VecExpr<VectorMatrixColOp<VecExpr<A,T,D1>, SMatrix<T,D1,D2,R>, D1>, T, D2>
0273 operator*(const VecExpr<A,T,D1>& lhs, const SMatrix<T,D1,D2,R>& rhs) {
0274 typedef VectorMatrixColOp<VecExpr<A,T,D1>, SMatrix<T,D1,D2,R>, D1> VMOp;
0275 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
0276 }
0277
0278
0279
0280
0281 template <class A, class B, class T, unsigned int D1, unsigned int D2, class R>
0282 inline VecExpr<VectorMatrixColOp<VecExpr<A,T,D1>, Expr<B,T,D1,D2,R>, D1>, T, D2>
0283 operator*(const VecExpr<A,T,D1>& lhs, const Expr<B,T,D1,D2,R>& rhs) {
0284 typedef VectorMatrixColOp<VecExpr<A,T,D1>, Expr<B,T,D1,D2,R>, D1> VMOp;
0285 return VecExpr<VMOp, T, D2>(VMOp(lhs,rhs));
0286 }
0287
0288
0289
0290
0291 template <unsigned int I>
0292 struct meta_matrix_dot {
0293
0294 template <class MatrixA, class MatrixB>
0295 static inline typename MatrixA::value_type f(const MatrixA& lhs,
0296 const MatrixB& rhs,
0297 const unsigned int offset) {
0298 return lhs.apply(offset/MatrixB::kCols*MatrixA::kCols + I) *
0299 rhs.apply(MatrixB::kCols*I + offset%MatrixB::kCols) +
0300 meta_matrix_dot<I-1>::f(lhs,rhs,offset);
0301 }
0302
0303
0304 template <class MatrixA, class MatrixB>
0305 static inline typename MatrixA::value_type g(const MatrixA& lhs,
0306 const MatrixB& rhs,
0307 unsigned int i,
0308 unsigned int j) {
0309 return lhs(i, I) * rhs(I , j) +
0310 meta_matrix_dot<I-1>::g(lhs,rhs,i,j);
0311 }
0312 };
0313
0314
0315
0316
0317
0318 template <>
0319 struct meta_matrix_dot<0> {
0320
0321 template <class MatrixA, class MatrixB>
0322 static inline typename MatrixA::value_type f(const MatrixA& lhs,
0323 const MatrixB& rhs,
0324 const unsigned int offset) {
0325 return lhs.apply(offset/MatrixB::kCols*MatrixA::kCols) *
0326 rhs.apply(offset%MatrixB::kCols);
0327 }
0328
0329
0330 template <class MatrixA, class MatrixB>
0331 static inline typename MatrixA::value_type g(const MatrixA& lhs,
0332 const MatrixB& rhs,
0333 unsigned int i, unsigned int j) {
0334 return lhs(i,0) * rhs(0,j);
0335 }
0336
0337 };
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 template <class MatrixA, class MatrixB, class T, unsigned int D>
0348 class MatrixMulOp {
0349 public:
0350
0351 MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) :
0352 lhs_(lhs), rhs_(rhs) {}
0353
0354
0355 ~MatrixMulOp() {}
0356
0357
0358 inline T apply(unsigned int i) const {
0359 return meta_matrix_dot<D-1>::f(lhs_, rhs_, i);
0360 }
0361
0362 inline T operator() (unsigned int i, unsigned j) const {
0363 return meta_matrix_dot<D-1>::g(lhs_, rhs_, i, j);
0364 }
0365
0366 inline bool IsInUse (const T * p) const {
0367 return lhs_.IsInUse(p) || rhs_.IsInUse(p);
0368 }
0369
0370
0371 protected:
0372 const MatrixA& lhs_;
0373 const MatrixB& rhs_;
0374 };
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 template < class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0387 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>,T,D>, T, D1, D2, typename MultPolicy<T,R1,R2>::RepType>
0388 operator*(const SMatrix<T,D1,D,R1>& lhs, const SMatrix<T,D,D2,R2>& rhs) {
0389 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, T,D> MatMulOp;
0390 return Expr<MatMulOp,T,D1,D2,
0391 typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0392 }
0393
0394
0395
0396
0397 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0398 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>
0399 operator*(const SMatrix<T,D1,D,R1>& lhs, const Expr<A,T,D,D2,R2>& rhs) {
0400 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>,T,D> MatMulOp;
0401 return Expr<MatMulOp,T,D1,D2,
0402 typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0403 }
0404
0405
0406
0407
0408 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0409 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>
0410 operator*(const Expr<A,T,D1,D,R1>& lhs, const SMatrix<T,D,D2,R2>& rhs) {
0411 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>,T,D> MatMulOp;
0412 return Expr<MatMulOp,T,D1,D2,
0413 typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0414 }
0415
0416
0417
0418
0419 template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0420 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>
0421 operator*(const Expr<A,T,D1,D,R1>& lhs, const Expr<B,T,D,D2,R2>& rhs) {
0422 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>, T,D> MatMulOp;
0423 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0424 }
0425
0426
0427
0428 #ifdef XXX
0429
0430
0431
0432 template <class MatrixA, class MatrixB, unsigned int D>
0433 class MatrixMulOp {
0434 public:
0435
0436 MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) :
0437 lhs_(lhs), rhs_(rhs) {}
0438
0439
0440 ~MatrixMulOp() {}
0441
0442
0443 inline typename MatrixA::value_type apply(unsigned int i) const {
0444 return meta_matrix_dot<D-1>::f(lhs_, rhs_, i);
0445 }
0446
0447 protected:
0448 const MatrixA& lhs_;
0449 const MatrixB& rhs_;
0450 };
0451
0452
0453
0454
0455
0456 template < class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0457 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, D>, T, D1, D2, typename MultPolicy<T,R1,R2>::RepType>
0458 operator*(const SMatrix<T,D1,D,R1>& lhs, const SMatrix<T,D,D2,R2>& rhs) {
0459 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, SMatrix<T,D,D2,R2>, D> MatMulOp;
0460 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0461 }
0462
0463
0464
0465
0466 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0467 inline Expr<MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>, D>, T, D1, D2, typename MultPolicy<T,R1,R2>::RepType>
0468 operator*(const SMatrix<T,D1,D,R1>& lhs, const Expr<A,T,D,D2,R2>& rhs) {
0469 typedef MatrixMulOp<SMatrix<T,D1,D,R1>, Expr<A,T,D,D2,R2>, D> MatMulOp;
0470 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0471 }
0472
0473
0474
0475
0476 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0477 inline Expr<MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>, D>, T, D1, D2, typename MultPolicy<T,R1,R2>::RepType>
0478 operator*(const Expr<A,T,D1,D,R1>& lhs, const SMatrix<T,D,D2,R2>& rhs) {
0479 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, SMatrix<T,D,D2,R2>, D> MatMulOp;
0480 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0481 }
0482
0483
0484
0485
0486 template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2, class R1, class R2>
0487 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>
0488 operator*(const Expr<A,T,D1,D,R1>& lhs, const Expr<B,T,D,D2,R2>& rhs) {
0489 typedef MatrixMulOp<Expr<A,T,D1,D,R1>, Expr<B,T,D,D2,R2>, D> MatMulOp;
0490 return Expr<MatMulOp,T,D1,D2,typename MultPolicy<T,R1,R2>::RepType>(MatMulOp(lhs,rhs));
0491 }
0492 #endif
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 template <class Matrix, class T, unsigned int D1, unsigned int D2=D1>
0503 class TransposeOp {
0504 public:
0505
0506 TransposeOp( const Matrix& rhs) :
0507 rhs_(rhs) {}
0508
0509
0510 ~TransposeOp() {}
0511
0512
0513 inline T apply(unsigned int i) const {
0514 return rhs_.apply( (i%D1)*D2 + i/D1);
0515 }
0516 inline T operator() (unsigned int i, unsigned j) const {
0517 return rhs_( j, i);
0518 }
0519
0520 inline bool IsInUse (const T * p) const {
0521 return rhs_.IsInUse(p);
0522 }
0523
0524 protected:
0525 const Matrix& rhs_;
0526 };
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538 template <class T, unsigned int D1, unsigned int D2, class R>
0539 inline Expr<TransposeOp<SMatrix<T,D1,D2,R>,T,D1,D2>, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
0540 Transpose(const SMatrix<T,D1,D2, R>& rhs) {
0541 typedef TransposeOp<SMatrix<T,D1,D2,R>,T,D1,D2> MatTrOp;
0542
0543 return Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs));
0544 }
0545
0546
0547
0548
0549 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0550 inline Expr<TransposeOp<Expr<A,T,D1,D2,R>,T,D1,D2>, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
0551 Transpose(const Expr<A,T,D1,D2,R>& rhs) {
0552 typedef TransposeOp<Expr<A,T,D1,D2,R>,T,D1,D2> MatTrOp;
0553
0554 return Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs));
0555 }
0556
0557
0558 #ifdef ENABLE_TEMPORARIES_TRANSPOSE
0559
0560
0561
0562
0563
0564 template <class T, unsigned int D1, unsigned int D2, class R>
0565 inline SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
0566 Transpose(const SMatrix<T,D1,D2, R>& rhs) {
0567 typedef TransposeOp<SMatrix<T,D1,D2,R>,T,D1,D2> MatTrOp;
0568
0569 return SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
0570 ( Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs)) );
0571 }
0572
0573
0574
0575
0576 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0577 inline SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
0578 Transpose(const Expr<A,T,D1,D2,R>& rhs) {
0579 typedef TransposeOp<Expr<A,T,D1,D2,R>,T,D1,D2> MatTrOp;
0580
0581 return SMatrix< T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>
0582 ( Expr<MatTrOp, T, D2, D1, typename TranspPolicy<T,D1,D2,R>::RepType>(MatTrOp(rhs)) );
0583 }
0584
0585 #endif
0586
0587
0588 #ifdef OLD
0589
0590
0591
0592 template <class T, unsigned int D, class R>
0593 inline T Product(const SMatrix<T,D,D,R>& lhs, const SVector<T,D>& rhs) {
0594 return Dot(rhs, lhs * rhs);
0595 }
0596
0597
0598
0599
0600 template <class T, unsigned int D, class R>
0601 inline T Product(const SVector<T,D>& lhs, const SMatrix<T,D,D,R>& rhs) {
0602 return Dot(lhs, rhs * lhs);
0603 }
0604
0605
0606
0607
0608 template <class A, class T, unsigned int D, class R>
0609 inline T Product(const SMatrix<T,D,D,R>& lhs, const VecExpr<A,T,D>& rhs) {
0610 return Dot(rhs, lhs * rhs);
0611 }
0612
0613
0614
0615
0616 template <class A, class T, unsigned int D, class R>
0617 inline T Product(const VecExpr<A,T,D>& lhs, const SMatrix<T,D,D,R>& rhs) {
0618 return Dot(lhs, rhs * lhs);
0619 }
0620
0621
0622
0623
0624 template <class A, class T, unsigned int D, class R>
0625 inline T Product(const SVector<T,D>& lhs, const Expr<A,T,D,D,R>& rhs) {
0626 return Dot(lhs, rhs * lhs);
0627 }
0628
0629
0630
0631
0632 template <class A, class T, unsigned int D, class R>
0633 inline T Product(const Expr<A,T,D,D,R>& lhs, const SVector<T,D>& rhs) {
0634 return Dot(rhs, lhs * rhs);
0635 }
0636
0637
0638
0639
0640 template <class A, class B, class T, unsigned int D, class R>
0641 inline T Product(const Expr<A,T,D,D,R>& lhs, const VecExpr<B,T,D>& rhs) {
0642 return Dot(rhs, lhs * rhs);
0643 }
0644
0645
0646
0647
0648 template <class A, class B, class T, unsigned int D, class R>
0649 inline T Product(const VecExpr<A,T,D>& lhs, const Expr<B,T,D,D,R>& rhs) {
0650 return Dot(lhs, rhs * lhs);
0651 }
0652 #endif
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 template <class T, unsigned int D, class R>
0665 inline T Similarity(const SMatrix<T,D,D,R>& lhs, const SVector<T,D>& rhs) {
0666 return Dot(rhs, lhs * rhs);
0667 }
0668
0669
0670
0671
0672 template <class T, unsigned int D, class R>
0673 inline T Similarity(const SVector<T,D>& lhs, const SMatrix<T,D,D,R>& rhs) {
0674 return Dot(lhs, rhs * lhs);
0675 }
0676
0677
0678
0679
0680 template <class A, class T, unsigned int D, class R>
0681 inline T Similarity(const SMatrix<T,D,D,R>& lhs, const VecExpr<A,T,D>& rhs) {
0682 return Dot(rhs, lhs * rhs);
0683 }
0684
0685
0686
0687
0688 template <class A, class T, unsigned int D, class R>
0689 inline T Similarity(const VecExpr<A,T,D>& lhs, const SMatrix<T,D,D,R>& rhs) {
0690 return Dot(lhs, rhs * lhs);
0691 }
0692
0693
0694
0695
0696 template <class A, class T, unsigned int D, class R>
0697 inline T Similarity(const SVector<T,D>& lhs, const Expr<A,T,D,D,R>& rhs) {
0698 return Dot(lhs, rhs * lhs);
0699 }
0700
0701
0702
0703
0704 template <class A, class T, unsigned int D, class R>
0705 inline T Similarity(const Expr<A,T,D,D,R>& lhs, const SVector<T,D>& rhs) {
0706 return Dot(rhs, lhs * rhs);
0707 }
0708
0709
0710
0711
0712 template <class A, class B, class T, unsigned int D, class R>
0713 inline T Similarity(const Expr<A,T,D,D,R>& lhs, const VecExpr<B,T,D>& rhs) {
0714 return Dot(rhs, lhs * rhs);
0715 }
0716
0717
0718
0719
0720 template <class A, class B, class T, unsigned int D, class R>
0721 inline T Similarity(const VecExpr<A,T,D>& lhs, const Expr<B,T,D,D,R>& rhs) {
0722 return Dot(lhs, rhs * lhs);
0723 }
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737 template <class T, unsigned int D1, unsigned int D2, class R>
0738 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) {
0739 SMatrix<T,D1,D2, MatRepStd<T,D1,D2> > tmp = lhs * rhs;
0740 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
0741 SMatrixSym mret;
0742 AssignSym::Evaluate(mret, tmp * Transpose(lhs) );
0743 return mret;
0744 }
0745
0746
0747
0748
0749
0750
0751 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0752 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) {
0753 SMatrix<T,D1,D2,MatRepStd<T,D1,D2> > tmp = lhs * rhs;
0754 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
0755 SMatrixSym mret;
0756 AssignSym::Evaluate(mret, tmp * Transpose(lhs) );
0757 return mret;
0758 }
0759
0760 #ifdef XXX
0761
0762
0763
0764
0765
0766 template <class T, unsigned int D1>
0767 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) {
0768 SMatrix<T,D1,D1, MatRepStd<T,D1,D1> > tmp = lhs * rhs;
0769 typedef SMatrix<T,D1,D1,MatRepSym<T,D1> > SMatrixSym;
0770 SMatrixSym mret;
0771 AssignSym::Evaluate(mret, tmp * lhs );
0772 return mret;
0773 }
0774 #endif
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787 template <class T, unsigned int D1, unsigned int D2, class R>
0788 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) {
0789 SMatrix<T,D1,D2,MatRepStd<T,D1,D2> > tmp = rhs * lhs;
0790 typedef SMatrix<T,D2,D2,MatRepSym<T,D2> > SMatrixSym;
0791 SMatrixSym mret;
0792 AssignSym::Evaluate(mret, Transpose(lhs) * tmp );
0793 return mret;
0794 }
0795
0796
0797
0798
0799
0800
0801 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0802 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) {
0803 SMatrix<T,D1,D2,MatRepStd<T,D1,D2> > tmp = rhs * lhs;
0804 typedef SMatrix<T,D2,D2,MatRepSym<T,D2> > SMatrixSym;
0805 SMatrixSym mret;
0806 AssignSym::Evaluate(mret, Transpose(lhs) * tmp );
0807 return mret;
0808 }
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836 template <class Vector1, class Vector2>
0837 class TensorMulOp {
0838 public:
0839
0840 TensorMulOp( const Vector1 & lhs, const Vector2 & rhs) :
0841 lhs_(lhs),
0842 rhs_(rhs) {}
0843
0844
0845 ~TensorMulOp() {}
0846
0847
0848 inline typename Vector1::value_type apply(unsigned int i) const {
0849 return lhs_.apply( i/ Vector2::kSize) * rhs_.apply( i % Vector2::kSize );
0850 }
0851 inline typename Vector1::value_type operator() (unsigned int i, unsigned j) const {
0852 return lhs_.apply(i) * rhs_.apply(j);
0853 }
0854
0855 inline bool IsInUse (const typename Vector1::value_type * ) const {
0856 return false;
0857 }
0858
0859
0860 protected:
0861
0862 const Vector1 & lhs_;
0863 const Vector2 & rhs_;
0864
0865 };
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876 #ifndef _WIN32
0877
0878
0879
0880
0881
0882
0883 template <class T, unsigned int D1, unsigned int D2>
0884 inline Expr<TensorMulOp<SVector<T,D1>, SVector<T,D2> >, T, D1, D2 >
0885 TensorProd(const SVector<T,D1>& lhs, const SVector<T,D2>& rhs) {
0886 typedef TensorMulOp<SVector<T,D1>, SVector<T,D2> > TVMulOp;
0887 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
0888 }
0889
0890
0891
0892
0893 template <class T, unsigned int D1, unsigned int D2, class A>
0894 inline Expr<TensorMulOp<VecExpr<A,T,D1>, SVector<T,D2> >, T, D1, D2 >
0895 TensorProd(const VecExpr<A,T,D1>& lhs, const SVector<T,D2>& rhs) {
0896 typedef TensorMulOp<VecExpr<A,T,D1>, SVector<T,D2> > TVMulOp;
0897 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
0898 }
0899
0900
0901
0902
0903 template <class T, unsigned int D1, unsigned int D2, class A>
0904 inline Expr<TensorMulOp<SVector<T,D1>, VecExpr<A,T,D2> >, T, D1, D2 >
0905 TensorProd(const SVector<T,D1>& lhs, const VecExpr<A,T,D2>& rhs) {
0906 typedef TensorMulOp<SVector<T,D1>, VecExpr<A,T,D2> > TVMulOp;
0907 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
0908 }
0909
0910
0911
0912
0913
0914 template <class T, unsigned int D1, unsigned int D2, class A, class B>
0915 inline Expr<TensorMulOp<VecExpr<A,T,D1>, VecExpr<B,T,D2> >, T, D1, D2 >
0916 TensorProd(const VecExpr<A,T,D1>& lhs, const VecExpr<B,T,D2>& rhs) {
0917 typedef TensorMulOp<VecExpr<A,T,D1>, VecExpr<B,T,D2> > TVMulOp;
0918 return Expr<TVMulOp,T,D1,D2>(TVMulOp(lhs,rhs));
0919 }
0920
0921 #endif
0922 #ifdef _WIN32
0923
0924
0925
0926
0927
0928 template <class T, unsigned int D1, unsigned int D2>
0929 inline SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> TensorProd(const SVector<T,D1>& lhs, const SVector<T,D2>& rhs) {
0930 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
0931 for (unsigned int i=0; i< D1; ++i)
0932 for (unsigned int j=0; j< D2; ++j) {
0933 tmp(i,j) = lhs[i]*rhs[j];
0934 }
0935
0936 return tmp;
0937 }
0938
0939
0940
0941 template <class T, unsigned int D1, unsigned int D2, class A>
0942 inline SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> TensorProd(const VecExpr<A,T,D1>& lhs, const SVector<T,D2>& rhs) {
0943 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
0944 for (unsigned int i=0; i< D1; ++i)
0945 for (unsigned int j=0; j< D2; ++j)
0946 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
0947
0948 return tmp;
0949 }
0950
0951
0952
0953 template <class T, unsigned int D1, unsigned int D2, class A>
0954 inline SMatrix<T,D1,D2, MatRepStd<T, D1, D2>> TensorProd(const SVector<T,D1>& lhs, const VecExpr<A,T,D2>& rhs) {
0955 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
0956 for (unsigned int i=0; i< D1; ++i)
0957 for (unsigned int j=0; j< D2; ++j)
0958 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
0959
0960 return tmp;
0961 }
0962
0963
0964
0965
0966
0967 template <class T, unsigned int D1, unsigned int D2, class A, class B>
0968 inline SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> TensorProd(const VecExpr<A,T,D1>& lhs, const VecExpr<B,T,D2>& rhs) {
0969 SMatrix<T,D1,D2,MatRepStd<T, D1, D2>> tmp;
0970 for (unsigned int i=0; i< D1; ++i)
0971 for (unsigned int j=0; j< D2; ++j)
0972 tmp(i,j) = lhs.apply(i) * rhs.apply(j);
0973
0974 return tmp;
0975 }
0976
0977
0978 #endif
0979
0980
0981
0982
0983
0984 template <class T, unsigned int D>
0985 bool SolveChol( SMatrix<T, D, D, MatRepSym<T, D> > & mat, SVector<T, D> & vec ) {
0986 CholeskyDecomp<T, D> decomp(mat);
0987 return decomp.Solve(vec);
0988 }
0989
0990
0991
0992 template <class T, unsigned int D>
0993 SVector<T,D> SolveChol( const SMatrix<T, D, D, MatRepSym<T, D> > & mat, const SVector<T, D> & vec, int & ifail ) {
0994 SMatrix<T, D, D, MatRepSym<T, D> > atmp(mat);
0995 SVector<T,D> vret(vec);
0996 bool ok = SolveChol( atmp, vret);
0997 ifail = (ok) ? 0 : -1;
0998 return vret;
0999 }
1000
1001
1002
1003 }
1004
1005 }
1006
1007
1008 #endif