File indexing completed on 2025-01-18 10:10:17
0001
0002
0003
0004 #ifndef ROOT_Math_HelperOps
0005 #define ROOT_Math_HelperOps 1
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include "Math/StaticCheck.h"
0021 #include <algorithm> // required by std::copy
0022 #include <cassert>
0023
0024 namespace ROOT {
0025
0026 namespace Math {
0027
0028 template <class T, unsigned int D1, unsigned int D2, class R>
0029 class SMatrix;
0030
0031 template <class A, class T, unsigned int D1, unsigned int D2, class R>
0032 class Expr;
0033
0034 template <class T, unsigned int D>
0035 class MatRepSym;
0036
0037 template <class T, unsigned int D1, unsigned int D2>
0038 class MatRepStd;
0039
0040
0041
0042
0043
0044 template <class T,
0045 unsigned int D1, unsigned int D2,
0046 class A, class R1, class R2>
0047
0048 struct Assign
0049 {
0050
0051
0052
0053
0054
0055 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D1,D2,R2>& rhs)
0056 {
0057 if (! rhs.IsInUse(lhs.begin() ) ) {
0058 unsigned int l = 0;
0059 for(unsigned int i=0; i<D1; ++i)
0060 for(unsigned int j=0; j<D2; ++j) {
0061 lhs.fRep[l] = rhs(i,j);
0062 l++;
0063 }
0064 }
0065
0066 else {
0067
0068 T tmp[D1*D2];
0069 unsigned int l = 0;
0070 for(unsigned int i=0; i<D1; ++i)
0071 for(unsigned int j=0; j<D2; ++j) {
0072 tmp[l] = rhs(i,j);
0073 l++;
0074 }
0075
0076 for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] = tmp[i];
0077 }
0078
0079 }
0080
0081 };
0082
0083
0084
0085
0086 template <class T,
0087 unsigned int D1, unsigned int D2,
0088 class A>
0089
0090 struct Assign<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> >
0091 {
0092
0093
0094
0095
0096
0097 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
0098 const Expr<A,T,D1,D2,MatRepSym<T,D1> >& rhs)
0099 {
0100 if (! rhs.IsInUse(lhs.begin() ) ) {
0101 unsigned int l = 0;
0102 for(unsigned int i=0; i<D1; ++i)
0103
0104 for(unsigned int j=0; j<=i; ++j) {
0105 lhs.fRep.Array()[l] = rhs(i,j);
0106 l++;
0107 }
0108 }
0109
0110 else {
0111 T tmp[MatRepSym<T,D1>::kSize];
0112 unsigned int l = 0;
0113 for(unsigned int i=0; i<D1; ++i)
0114 for(unsigned int j=0; j<=i; ++j) {
0115 tmp[l] = rhs(i,j);
0116 l++;
0117 }
0118
0119 for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] = tmp[i];
0120 }
0121 }
0122 };
0123
0124
0125
0126
0127
0128
0129
0130 template <class T, unsigned int D1, unsigned int D2, class A>
0131 struct Assign<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> >
0132 {
0133 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,
0134 const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&)
0135 {
0136 STATIC_CHECK(0==1, Cannot_assign_general_to_symmetric_matrix);
0137 }
0138
0139 };
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 struct AssignSym
0150 {
0151
0152 template <class T,
0153 unsigned int D,
0154 class A,
0155 class R>
0156 static void Evaluate(SMatrix<T,D,D,MatRepSym<T,D> >& lhs, const Expr<A,T,D,D,R>& rhs)
0157 {
0158
0159 unsigned int l = 0;
0160 for(unsigned int i=0; i<D; ++i)
0161
0162 for(unsigned int j=0; j<=i; ++j) {
0163 lhs.fRep.Array()[l] = rhs(i,j);
0164 l++;
0165 }
0166 }
0167
0168 template <class T,
0169 unsigned int D,
0170 class R>
0171 static void Evaluate(SMatrix<T,D,D,MatRepSym<T,D> >& lhs, const SMatrix<T,D,D,R>& rhs)
0172 {
0173
0174 unsigned int l = 0;
0175 for(unsigned int i=0; i<D; ++i)
0176
0177 for(unsigned int j=0; j<=i; ++j) {
0178 lhs.fRep.Array()[l] = rhs(i,j);
0179 l++;
0180 }
0181 }
0182
0183
0184 };
0185
0186
0187
0188
0189
0190
0191
0192
0193 template <class T, unsigned int D1, unsigned int D2, class A,
0194 class R1, class R2>
0195 struct PlusEquals
0196 {
0197 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D1,D2,R2>& rhs)
0198 {
0199 if (! rhs.IsInUse(lhs.begin() ) ) {
0200 unsigned int l = 0;
0201 for(unsigned int i=0; i<D1; ++i)
0202 for(unsigned int j=0; j<D2; ++j) {
0203 lhs.fRep[l] += rhs(i,j);
0204 l++;
0205 }
0206 }
0207 else {
0208 T tmp[D1*D2];
0209 unsigned int l = 0;
0210 for(unsigned int i=0; i<D1; ++i)
0211 for(unsigned int j=0; j<D2; ++j) {
0212 tmp[l] = rhs(i,j);
0213 l++;
0214 }
0215
0216 for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] += tmp[i];
0217 }
0218 }
0219 };
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229 template <class T,
0230 unsigned int D1, unsigned int D2,
0231 class A>
0232 struct PlusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> >
0233 {
0234 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, const Expr<A,T,D1,D2, MatRepSym<T,D1> >& rhs)
0235 {
0236 if (! rhs.IsInUse(lhs.begin() ) ) {
0237 unsigned int l = 0;
0238 for(unsigned int i=0; i<D1; ++i)
0239 for(unsigned int j=0; j<=i; ++j) {
0240 lhs.fRep.Array()[l] += rhs(i,j);
0241 l++;
0242 }
0243 }
0244 else {
0245 T tmp[MatRepSym<T,D1>::kSize];
0246 unsigned int l = 0;
0247 for(unsigned int i=0; i<D1; ++i)
0248 for(unsigned int j=0; j<=i; ++j) {
0249 tmp[l] = rhs(i,j);
0250 l++;
0251 }
0252
0253 for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] += tmp[i];
0254 }
0255 }
0256 };
0257
0258
0259
0260 template <class T, unsigned int D1, unsigned int D2, class A>
0261 struct PlusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> >
0262 {
0263 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,
0264 const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&)
0265 {
0266 STATIC_CHECK(0==1, Cannot_plusEqual_general_to_symmetric_matrix);
0267 }
0268 };
0269
0270
0271
0272
0273
0274
0275
0276
0277 template <class T, unsigned int D1, unsigned int D2, class A,
0278 class R1, class R2>
0279 struct MinusEquals
0280 {
0281 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D1,D2,R2>& rhs)
0282 {
0283 if (! rhs.IsInUse(lhs.begin() ) ) {
0284 unsigned int l = 0;
0285 for(unsigned int i=0; i<D1; ++i)
0286 for(unsigned int j=0; j<D2; ++j) {
0287 lhs.fRep[l] -= rhs(i,j);
0288 l++;
0289 }
0290 }
0291 else {
0292 T tmp[D1*D2];
0293 unsigned int l = 0;
0294 for(unsigned int i=0; i<D1; ++i)
0295 for(unsigned int j=0; j<D2; ++j) {
0296 tmp[l] = rhs(i,j);
0297 l++;
0298 }
0299
0300 for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] -= tmp[i];
0301 }
0302 }
0303 };
0304
0305
0306
0307
0308
0309
0310
0311
0312 template <class T,
0313 unsigned int D1, unsigned int D2,
0314 class A>
0315 struct MinusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> >
0316 {
0317 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, const Expr<A,T,D1,D2, MatRepSym<T,D1> >& rhs)
0318 {
0319 if (! rhs.IsInUse(lhs.begin() ) ) {
0320 unsigned int l = 0;
0321 for(unsigned int i=0; i<D1; ++i)
0322 for(unsigned int j=0; j<=i; ++j) {
0323 lhs.fRep.Array()[l] -= rhs(i,j);
0324 l++;
0325 }
0326 }
0327 else {
0328 T tmp[MatRepSym<T,D1>::kSize];
0329 unsigned int l = 0;
0330 for(unsigned int i=0; i<D1; ++i)
0331 for(unsigned int j=0; j<=i; ++j) {
0332 tmp[l] = rhs(i,j);
0333 l++;
0334 }
0335
0336 for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] -= tmp[i];
0337 }
0338 }
0339 };
0340
0341
0342
0343
0344 template <class T, unsigned int D1, unsigned int D2, class A>
0345 struct MinusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> >
0346 {
0347 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,
0348 const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&)
0349 {
0350 STATIC_CHECK(0==1, Cannot_minusEqual_general_to_symmetric_matrix);
0351 }
0352 };
0353
0354
0355
0356
0357
0358 template <class T, unsigned int D1, unsigned int D2,
0359 unsigned int D3, unsigned int D4,
0360 class R1, class R2>
0361 struct PlaceMatrix
0362 {
0363 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const SMatrix<T,D3,D4,R2>& rhs,
0364 unsigned int row, unsigned int col) {
0365
0366 assert(row+D3 <= D1 && col+D4 <= D2);
0367 const unsigned int offset = row*D2+col;
0368
0369 for(unsigned int i=0; i<D3*D4; ++i) {
0370 lhs.fRep[offset+(i/D4)*D2+i%D4] = rhs.apply(i);
0371 }
0372
0373 }
0374 };
0375
0376 template <class T, unsigned int D1, unsigned int D2,
0377 unsigned int D3, unsigned int D4,
0378 class A, class R1, class R2>
0379 struct PlaceExpr {
0380 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D3,D4,R2>& rhs,
0381 unsigned int row, unsigned int col) {
0382
0383 assert(row+D3 <= D1 && col+D4 <= D2);
0384 const unsigned int offset = row*D2+col;
0385
0386 for(unsigned int i=0; i<D3*D4; ++i) {
0387 lhs.fRep[offset+(i/D4)*D2+i%D4] = rhs.apply(i);
0388 }
0389 }
0390 };
0391
0392
0393 template <class T, unsigned int D1, unsigned int D2,
0394 unsigned int D3, unsigned int D4 >
0395 struct PlaceMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > {
0396 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,
0397 const SMatrix<T,D3,D4,MatRepStd<T,D3,D4> >& ,
0398 unsigned int , unsigned int )
0399 {
0400 STATIC_CHECK(0==1, Cannot_Place_Matrix_general_in_symmetric_matrix);
0401 }
0402 };
0403
0404
0405 template <class T, unsigned int D1, unsigned int D2,
0406 unsigned int D3, unsigned int D4, class A >
0407 struct PlaceExpr<T, D1, D2, D3, D4, A, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > {
0408 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,
0409 const Expr<A,T,D3,D4,MatRepStd<T,D3,D4> >& ,
0410 unsigned int , unsigned int )
0411 {
0412 STATIC_CHECK(0==1, Cannot_Place_Matrix_general_in_symmetric_matrix);
0413 }
0414 };
0415
0416
0417
0418 template <class T, unsigned int D1, unsigned int D2,
0419 unsigned int D3, unsigned int D4 >
0420 struct PlaceMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepSym<T,D3> > {
0421 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
0422 const SMatrix<T,D3,D4,MatRepSym<T,D3> >& rhs,
0423 unsigned int row, unsigned int col )
0424 {
0425
0426 assert(row == col);
0427
0428 for(unsigned int i=0; i<D3; ++i) {
0429 for(unsigned int j=0; j<=i; ++j)
0430 lhs.fRep(row+i,col+j) = rhs(i,j);
0431 }
0432 }
0433 };
0434
0435
0436 template <class T, unsigned int D1, unsigned int D2,
0437 unsigned int D3, unsigned int D4, class A >
0438 struct PlaceExpr<T, D1, D2, D3, D4, A, MatRepSym<T,D1>, MatRepSym<T,D3> > {
0439 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
0440 const Expr<A,T,D3,D4,MatRepSym<T,D3> >& rhs,
0441 unsigned int row, unsigned int col )
0442 {
0443
0444 assert(row == col);
0445
0446 for(unsigned int i=0; i<D3; ++i) {
0447 for(unsigned int j=0; j<=i; ++j)
0448 lhs.fRep(row+i,col+j) = rhs(i,j);
0449 }
0450 }
0451 };
0452
0453
0454
0455
0456
0457
0458 template <class T, unsigned int D1, unsigned int D2,
0459 unsigned int D3, unsigned int D4,
0460 class R1, class R2>
0461 struct RetrieveMatrix
0462 {
0463 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const SMatrix<T,D3,D4,R2>& rhs,
0464 unsigned int row, unsigned int col) {
0465 STATIC_CHECK( D1 <= D3,Smatrix_nrows_too_small);
0466 STATIC_CHECK( D2 <= D4,Smatrix_ncols_too_small);
0467
0468 assert(row + D1 <= D3);
0469 assert(col + D2 <= D4);
0470
0471 for(unsigned int i=0; i<D1; ++i) {
0472 for(unsigned int j=0; j<D2; ++j)
0473 lhs(i,j) = rhs(i+row,j+col);
0474 }
0475 }
0476 };
0477
0478
0479 template <class T, unsigned int D1, unsigned int D2,
0480 unsigned int D3, unsigned int D4 >
0481 struct RetrieveMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > {
0482 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,
0483 const SMatrix<T,D3,D4,MatRepStd<T,D3,D4> >& ,
0484 unsigned int , unsigned int )
0485 {
0486 STATIC_CHECK(0==1, Cannot_Sub_Matrix_symmetric_in_general_matrix);
0487 }
0488 };
0489
0490
0491 template <class T, unsigned int D1, unsigned int D2,
0492 unsigned int D3, unsigned int D4 >
0493 struct RetrieveMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepSym<T,D3> > {
0494 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
0495 const SMatrix<T,D3,D4,MatRepSym<T,D3> >& rhs,
0496 unsigned int row, unsigned int col )
0497 {
0498 STATIC_CHECK( D1 <= D3,Smatrix_dimension1_too_small);
0499
0500 assert(row == col);
0501 assert(row + D1 <= D3);
0502
0503 for(unsigned int i=0; i<D1; ++i) {
0504 for(unsigned int j=0; j<=i; ++j)
0505 lhs(i,j) = rhs(i+row,j+col );
0506 }
0507 }
0508
0509 };
0510
0511
0512
0513
0514
0515
0516 template <class T, unsigned int D1, unsigned int D2, class R>
0517 struct AssignItr {
0518 template<class Iterator>
0519 static void Evaluate(SMatrix<T,D1,D2,R>& lhs, Iterator begin, Iterator end,
0520 bool triang, bool lower,bool check=true) {
0521
0522
0523 if (triang) {
0524 Iterator itr = begin;
0525 if (lower) {
0526 for (unsigned int i = 0; i < D1; ++i)
0527 for (unsigned int j =0; j <= i; ++j) {
0528
0529 lhs.fRep[i*D2+j] = *itr++;
0530 }
0531
0532 }
0533 else {
0534 for (unsigned int i = 0; i < D1; ++i)
0535 for (unsigned int j = i; j <D2; ++j) {
0536 if (itr != end)
0537 lhs.fRep[i*D2+j] = *itr++;
0538 else
0539 return;
0540 }
0541
0542 }
0543 }
0544
0545 else {
0546 if (check) assert( begin + R::kSize == end);
0547
0548 std::copy(begin, end, lhs.fRep.Array() );
0549 }
0550 }
0551
0552 };
0553
0554
0555
0556
0557
0558
0559 template <class T, unsigned int D1, unsigned int D2>
0560 struct AssignItr<T, D1, D2, MatRepSym<T,D1> > {
0561 template<class Iterator>
0562 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, Iterator begin, Iterator end, bool , bool lower, bool check = true) {
0563
0564 if (lower) {
0565 if (check) {
0566 assert(begin+ static_cast< int>( MatRepSym<T,D1>::kSize) == end);
0567 }
0568 std::copy(begin, end, lhs.fRep.Array() );
0569 }
0570 else {
0571 Iterator itr = begin;
0572 for (unsigned int i = 0; i < D1; ++i)
0573 for (unsigned int j = i; j <D2; ++j) {
0574 if (itr != end)
0575 lhs(i,j) = *itr++;
0576 else
0577 return;
0578 }
0579 }
0580 }
0581
0582 };
0583
0584
0585 }
0586
0587 }
0588
0589 #endif