00001
00002
00003
00004 #ifndef ROOT_Math_HelperOps
00005 #define ROOT_Math_HelperOps 1
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "Math/StaticCheck.h"
00021 #include <algorithm>
00022
00023 namespace ROOT {
00024
00025 namespace Math {
00026
00027 template <class T, unsigned int D1, unsigned int D2, class R>
00028 class SMatrix;
00029
00030 template <class A, class T, unsigned int D1, unsigned int D2, class R>
00031 class Expr;
00032
00033
00034
00035
00036
00037 template <class T,
00038 unsigned int D1, unsigned int D2,
00039 class A, class R1, class R2>
00040
00041 struct Assign
00042 {
00043
00044
00045
00046
00047
00048 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D1,D2,R2>& rhs)
00049 {
00050 if (! rhs.IsInUse(lhs.begin() ) ) {
00051 unsigned int l = 0;
00052 for(unsigned int i=0; i<D1; ++i)
00053 for(unsigned int j=0; j<D2; ++j) {
00054 lhs.fRep[l] = rhs(i,j);
00055 l++;
00056 }
00057 }
00058
00059 else {
00060
00061 T tmp[D1*D2];
00062 unsigned int l = 0;
00063 for(unsigned int i=0; i<D1; ++i)
00064 for(unsigned int j=0; j<D2; ++j) {
00065 tmp[l] = rhs(i,j);
00066 l++;
00067 }
00068
00069 for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] = tmp[i];
00070 }
00071
00072 }
00073
00074 };
00075
00076
00077
00078
00079 template <class T,
00080 unsigned int D1, unsigned int D2,
00081 class A>
00082
00083 struct Assign<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> >
00084 {
00085
00086
00087
00088
00089
00090 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
00091 const Expr<A,T,D1,D2,MatRepSym<T,D1> >& rhs)
00092 {
00093 if (! rhs.IsInUse(lhs.begin() ) ) {
00094 unsigned int l = 0;
00095 for(unsigned int i=0; i<D1; ++i)
00096
00097 for(unsigned int j=0; j<=i; ++j) {
00098 lhs.fRep.Array()[l] = rhs(i,j);
00099 l++;
00100 }
00101 }
00102
00103 else {
00104 T tmp[MatRepSym<T,D1>::kSize];
00105 unsigned int l = 0;
00106 for(unsigned int i=0; i<D1; ++i)
00107 for(unsigned int j=0; j<=i; ++j) {
00108 tmp[l] = rhs(i,j);
00109 l++;
00110 }
00111
00112 for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] = tmp[i];
00113 }
00114 }
00115 };
00116
00117
00118
00119
00120
00121
00122
00123 template <class T, unsigned int D1, unsigned int D2, class A>
00124 struct Assign<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> >
00125 {
00126 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,
00127 const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&)
00128 {
00129 STATIC_CHECK(0==1, Cannot_assign_general_to_symmetric_matrix);
00130 }
00131
00132 };
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 struct AssignSym
00143 {
00144
00145 template <class T,
00146 unsigned int D,
00147 class A,
00148 class R>
00149 static void Evaluate(SMatrix<T,D,D,MatRepSym<T,D> >& lhs, const Expr<A,T,D,D,R>& rhs)
00150 {
00151
00152 unsigned int l = 0;
00153 for(unsigned int i=0; i<D; ++i)
00154
00155 for(unsigned int j=0; j<=i; ++j) {
00156 lhs.fRep.Array()[l] = rhs(i,j);
00157 l++;
00158 }
00159 }
00160
00161 template <class T,
00162 unsigned int D,
00163 class R>
00164 static void Evaluate(SMatrix<T,D,D,MatRepSym<T,D> >& lhs, const SMatrix<T,D,D,R>& rhs)
00165 {
00166
00167 unsigned int l = 0;
00168 for(unsigned int i=0; i<D; ++i)
00169
00170 for(unsigned int j=0; j<=i; ++j) {
00171 lhs.fRep.Array()[l] = rhs(i,j);
00172 l++;
00173 }
00174 }
00175
00176
00177 };
00178
00179
00180
00181
00182
00183
00184
00185
00186 template <class T, unsigned int D1, unsigned int D2, class A,
00187 class R1, class R2>
00188 struct PlusEquals
00189 {
00190 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D1,D2,R2>& rhs)
00191 {
00192 if (! rhs.IsInUse(lhs.begin() ) ) {
00193 unsigned int l = 0;
00194 for(unsigned int i=0; i<D1; ++i)
00195 for(unsigned int j=0; j<D2; ++j) {
00196 lhs.fRep[l] += rhs(i,j);
00197 l++;
00198 }
00199 }
00200 else {
00201 T tmp[D1*D2];
00202 unsigned int l = 0;
00203 for(unsigned int i=0; i<D1; ++i)
00204 for(unsigned int j=0; j<D2; ++j) {
00205 tmp[l] = rhs(i,j);
00206 l++;
00207 }
00208
00209 for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] += tmp[i];
00210 }
00211 }
00212 };
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 template <class T,
00223 unsigned int D1, unsigned int D2,
00224 class A>
00225 struct PlusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> >
00226 {
00227 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, const Expr<A,T,D1,D2, MatRepSym<T,D1> >& rhs)
00228 {
00229 if (! rhs.IsInUse(lhs.begin() ) ) {
00230 unsigned int l = 0;
00231 for(unsigned int i=0; i<D1; ++i)
00232 for(unsigned int j=0; j<=i; ++j) {
00233 lhs.fRep.Array()[l] += rhs(i,j);
00234 l++;
00235 }
00236 }
00237 else {
00238 T tmp[MatRepSym<T,D1>::kSize];
00239 unsigned int l = 0;
00240 for(unsigned int i=0; i<D1; ++i)
00241 for(unsigned int j=0; j<=i; ++j) {
00242 tmp[l] = rhs(i,j);
00243 l++;
00244 }
00245
00246 for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] += tmp[i];
00247 }
00248 }
00249 };
00250
00251
00252
00253 template <class T, unsigned int D1, unsigned int D2, class A>
00254 struct PlusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> >
00255 {
00256 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,
00257 const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&)
00258 {
00259 STATIC_CHECK(0==1, Cannot_plusEqual_general_to_symmetric_matrix);
00260 }
00261 };
00262
00263
00264
00265
00266
00267
00268
00269
00270 template <class T, unsigned int D1, unsigned int D2, class A,
00271 class R1, class R2>
00272 struct MinusEquals
00273 {
00274 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D1,D2,R2>& rhs)
00275 {
00276 if (! rhs.IsInUse(lhs.begin() ) ) {
00277 unsigned int l = 0;
00278 for(unsigned int i=0; i<D1; ++i)
00279 for(unsigned int j=0; j<D2; ++j) {
00280 lhs.fRep[l] -= rhs(i,j);
00281 l++;
00282 }
00283 }
00284 else {
00285 T tmp[D1*D2];
00286 unsigned int l = 0;
00287 for(unsigned int i=0; i<D1; ++i)
00288 for(unsigned int j=0; j<D2; ++j) {
00289 tmp[l] = rhs(i,j);
00290 l++;
00291 }
00292
00293 for(unsigned int i=0; i<D1*D2; ++i) lhs.fRep[i] -= tmp[i];
00294 }
00295 }
00296 };
00297
00298
00299
00300
00301
00302
00303
00304
00305 template <class T,
00306 unsigned int D1, unsigned int D2,
00307 class A>
00308 struct MinusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepSym<T,D1> >
00309 {
00310 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, const Expr<A,T,D1,D2, MatRepSym<T,D1> >& rhs)
00311 {
00312 if (! rhs.IsInUse(lhs.begin() ) ) {
00313 unsigned int l = 0;
00314 for(unsigned int i=0; i<D1; ++i)
00315 for(unsigned int j=0; j<=i; ++j) {
00316 lhs.fRep.Array()[l] -= rhs(i,j);
00317 l++;
00318 }
00319 }
00320 else {
00321 T tmp[MatRepSym<T,D1>::kSize];
00322 unsigned int l = 0;
00323 for(unsigned int i=0; i<D1; ++i)
00324 for(unsigned int j=0; j<=i; ++j) {
00325 tmp[l] = rhs(i,j);
00326 l++;
00327 }
00328
00329 for(unsigned int i=0; i<MatRepSym<T,D1>::kSize; ++i) lhs.fRep.Array()[i] -= tmp[i];
00330 }
00331 }
00332 };
00333
00334
00335
00336
00337 template <class T, unsigned int D1, unsigned int D2, class A>
00338 struct MinusEquals<T, D1, D2, A, MatRepSym<T,D1>, MatRepStd<T,D1,D2> >
00339 {
00340 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >&,
00341 const Expr<A,T,D1,D2,MatRepStd<T,D1,D2> >&)
00342 {
00343 STATIC_CHECK(0==1, Cannot_minusEqual_general_to_symmetric_matrix);
00344 }
00345 };
00346
00347
00348
00349
00350
00351 template <class T, unsigned int D1, unsigned int D2,
00352 unsigned int D3, unsigned int D4,
00353 class R1, class R2>
00354 struct PlaceMatrix
00355 {
00356 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const SMatrix<T,D3,D4,R2>& rhs,
00357 unsigned int row, unsigned int col) {
00358
00359 assert(row+D3 <= D1 && col+D4 <= D2);
00360 const unsigned int offset = row*D2+col;
00361
00362 for(unsigned int i=0; i<D3*D4; ++i) {
00363 lhs.fRep[offset+(i/D4)*D2+i%D4] = rhs.apply(i);
00364 }
00365
00366 }
00367 };
00368
00369 template <class T, unsigned int D1, unsigned int D2,
00370 unsigned int D3, unsigned int D4,
00371 class A, class R1, class R2>
00372 struct PlaceExpr {
00373 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const Expr<A,T,D3,D4,R2>& rhs,
00374 unsigned int row, unsigned int col) {
00375
00376 assert(row+D3 <= D1 && col+D4 <= D2);
00377 const unsigned int offset = row*D2+col;
00378
00379 for(unsigned int i=0; i<D3*D4; ++i) {
00380 lhs.fRep[offset+(i/D4)*D2+i%D4] = rhs.apply(i);
00381 }
00382 }
00383 };
00384
00385
00386 template <class T, unsigned int D1, unsigned int D2,
00387 unsigned int D3, unsigned int D4 >
00388 struct PlaceMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > {
00389 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,
00390 const SMatrix<T,D3,D4,MatRepStd<T,D3,D4> >& ,
00391 unsigned int , unsigned int )
00392 {
00393 STATIC_CHECK(0==1, Cannot_Place_Matrix_general_in_symmetric_matrix);
00394 }
00395 };
00396
00397
00398 template <class T, unsigned int D1, unsigned int D2,
00399 unsigned int D3, unsigned int D4, class A >
00400 struct PlaceExpr<T, D1, D2, D3, D4, A, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > {
00401 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,
00402 const Expr<A,T,D3,D4,MatRepStd<T,D3,D4> >& ,
00403 unsigned int , unsigned int )
00404 {
00405 STATIC_CHECK(0==1, Cannot_Place_Matrix_general_in_symmetric_matrix);
00406 }
00407 };
00408
00409
00410
00411 template <class T, unsigned int D1, unsigned int D2,
00412 unsigned int D3, unsigned int D4 >
00413 struct PlaceMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepSym<T,D3> > {
00414 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
00415 const SMatrix<T,D3,D4,MatRepSym<T,D3> >& rhs,
00416 unsigned int row, unsigned int col )
00417 {
00418
00419 assert(row == col);
00420
00421 for(unsigned int i=0; i<D3; ++i) {
00422 for(unsigned int j=0; j<=i; ++j)
00423 lhs.fRep(row+i,col+j) = rhs(i,j);
00424 }
00425 }
00426 };
00427
00428
00429 template <class T, unsigned int D1, unsigned int D2,
00430 unsigned int D3, unsigned int D4, class A >
00431 struct PlaceExpr<T, D1, D2, D3, D4, A, MatRepSym<T,D1>, MatRepSym<T,D3> > {
00432 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
00433 const Expr<A,T,D3,D4,MatRepSym<T,D3> >& rhs,
00434 unsigned int row, unsigned int col )
00435 {
00436
00437 assert(row == col);
00438
00439 for(unsigned int i=0; i<D3; ++i) {
00440 for(unsigned int j=0; j<=i; ++j)
00441 lhs.fRep(row+i,col+j) = rhs(i,j);
00442 }
00443 }
00444 };
00445
00446
00447
00448
00449
00450
00451 template <class T, unsigned int D1, unsigned int D2,
00452 unsigned int D3, unsigned int D4,
00453 class R1, class R2>
00454 struct RetrieveMatrix
00455 {
00456 static void Evaluate(SMatrix<T,D1,D2,R1>& lhs, const SMatrix<T,D3,D4,R2>& rhs,
00457 unsigned int row, unsigned int col) {
00458 STATIC_CHECK( D1 <= D3,Smatrix_nrows_too_small);
00459 STATIC_CHECK( D2 <= D4,Smatrix_ncols_too_small);
00460
00461 assert(row + D1 <= D3);
00462 assert(col + D2 <= D4);
00463
00464 for(unsigned int i=0; i<D1; ++i) {
00465 for(unsigned int j=0; j<D2; ++j)
00466 lhs(i,j) = rhs(i+row,j+col);
00467 }
00468 }
00469 };
00470
00471
00472 template <class T, unsigned int D1, unsigned int D2,
00473 unsigned int D3, unsigned int D4 >
00474 struct RetrieveMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepStd<T,D3,D4> > {
00475 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& ,
00476 const SMatrix<T,D3,D4,MatRepStd<T,D3,D4> >& ,
00477 unsigned int , unsigned int )
00478 {
00479 STATIC_CHECK(0==1, Cannot_Sub_Matrix_symmetric_in_general_matrix);
00480 }
00481 };
00482
00483
00484 template <class T, unsigned int D1, unsigned int D2,
00485 unsigned int D3, unsigned int D4 >
00486 struct RetrieveMatrix<T, D1, D2, D3, D4, MatRepSym<T,D1>, MatRepSym<T,D3> > {
00487 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs,
00488 const SMatrix<T,D3,D4,MatRepSym<T,D3> >& rhs,
00489 unsigned int row, unsigned int col )
00490 {
00491 STATIC_CHECK( D1 <= D3,Smatrix_dimension1_too_small);
00492
00493 assert(row == col);
00494 assert(row + D1 <= D3);
00495
00496 for(unsigned int i=0; i<D1; ++i) {
00497 for(unsigned int j=0; j<=i; ++j)
00498 lhs(i,j) = rhs(i+row,j+col );
00499 }
00500 }
00501
00502 };
00503
00504
00505
00506
00507
00508
00509 template <class T, unsigned int D1, unsigned int D2, class R>
00510 struct AssignItr {
00511 template<class Iterator>
00512 static void Evaluate(SMatrix<T,D1,D2,R>& lhs, Iterator begin, Iterator end,
00513 bool triang, bool lower,bool check=true) {
00514
00515
00516 if (triang) {
00517 Iterator itr = begin;
00518 if (lower) {
00519 for (unsigned int i = 0; i < D1; ++i)
00520 for (unsigned int j =0; j <= i; ++j) {
00521
00522 lhs.fRep[i*D2+j] = *itr++;
00523 }
00524
00525 }
00526 else {
00527 for (unsigned int i = 0; i < D1; ++i)
00528 for (unsigned int j = i; j <D2; ++j) {
00529 if (itr != end)
00530 lhs.fRep[i*D2+j] = *itr++;
00531 else
00532 return;
00533 }
00534
00535 }
00536 }
00537
00538 else {
00539 if (check) assert( begin + R::kSize == end);
00540
00541 std::copy(begin, end, lhs.fRep.Array() );
00542 }
00543 }
00544
00545 };
00546
00547
00548
00549
00550
00551
00552 template <class T, unsigned int D1, unsigned int D2>
00553 struct AssignItr<T, D1, D2, MatRepSym<T,D1> > {
00554 template<class Iterator>
00555 static void Evaluate(SMatrix<T,D1,D2,MatRepSym<T,D1> >& lhs, Iterator begin, Iterator end, bool , bool lower, bool check = true) {
00556
00557 if (lower) {
00558 if (check) {
00559 const int size = MatRepSym<T,D1>::kSize;
00560 assert( begin + size == end);
00561 }
00562 std::copy(begin, end, lhs.fRep.Array() );
00563 }
00564 else {
00565 Iterator itr = begin;
00566 for (unsigned int i = 0; i < D1; ++i)
00567 for (unsigned int j = i; j <D2; ++j) {
00568 if (itr != end)
00569 lhs(i,j) = *itr++;
00570 else
00571 return;
00572 }
00573 }
00574 }
00575
00576 };
00577
00578
00579 }
00580
00581 }
00582
00583 #endif // MATH_HELPEROPS_H