00001
00002
00003 #include "Math/SVector.h"
00004 #include "Math/SMatrix.h"
00005
00006 #include "TMatrixD.h"
00007 #include "TVectorD.h"
00008
00009 #include "TRandom3.h"
00010
00011 #include "matrix_util.h"
00012
00013
00014 #define TEST_SYM
00015
00016
00017 #ifdef HAVE_CLHEP
00018 #include "CLHEP/Matrix/SymMatrix.h"
00019 #include "CLHEP/Matrix/Matrix.h"
00020 #include "CLHEP/Matrix/Vector.h"
00021 #endif
00022
00023
00024
00025
00026
00027 #include <iostream>
00028
00029 #ifndef NDIM1
00030 #define NDIM1 2
00031 #endif
00032 #ifndef NDIM2
00033 #define NDIM2 5
00034 #endif
00035
00036 #define NITER 1 // number of iterations
00037
00038 #define NLOOP 1000000 // number of time the test is repeted
00039
00040 using namespace ROOT::Math;
00041
00042 #include "TestTimer.h"
00043
00044 int test_smatrix_kalman() {
00045
00046
00047
00048
00049 typedef SMatrix<double, NDIM1, NDIM1> MnMatrixNN;
00050 typedef SMatrix<double, NDIM2, NDIM2> MnMatrixMM;
00051 typedef SMatrix<double, NDIM1, NDIM2> MnMatrixNM;
00052 typedef SMatrix<double, NDIM2 , NDIM1> MnMatrixMN;
00053 typedef SMatrix<double, NDIM1 > MnSymMatrixNN;
00054 typedef SMatrix<double, NDIM2 > MnSymMatrixMM;
00055 typedef SVector<double, NDIM1> MnVectorN;
00056 typedef SVector<double, NDIM2> MnVectorM;
00057
00058
00059
00060 int first = NDIM1;
00061 int second = NDIM2;
00062
00063
00064 std::cout << "************************************************\n";
00065 std::cout << " SMatrix kalman test " << first << " x " << second << std::endl;
00066 std::cout << "************************************************\n";
00067
00068
00069
00070
00071 int npass = NITER;
00072 TRandom3 r(111);
00073 double x2sum = 0, c2sum = 0;
00074 for (int k = 0; k < npass; k++) {
00075
00076
00077
00078 MnMatrixNM H;
00079 MnMatrixMN K0;
00080 MnSymMatrixMM Cp;
00081 MnSymMatrixNN V;
00082 MnVectorN m;
00083 MnVectorM xp;
00084
00085
00086 {
00087
00088 fillRandomMat(r,H,first,second);
00089 fillRandomMat(r,K0,second,first);
00090 fillRandomSym(r,Cp,second);
00091 fillRandomSym(r,V,first);
00092 fillRandomVec(r,m,first);
00093 fillRandomVec(r,xp,second);
00094 }
00095
00096
00097 MnSymMatrixMM I;
00098 for(int i = 0; i < second; i++)
00099 I(i,i) = 1;
00100
00101 #ifdef DEBUG
00102 std::cout << "pass " << k << std::endl;
00103 if (k == 0) {
00104 std::cout << " K0 = " << K0 << std::endl;
00105 std::cout << " H = " << K0 << std::endl;
00106 std::cout << " Cp = " << Cp << std::endl;
00107 std::cout << " V = " << V << std::endl;
00108 std::cout << " m = " << m << std::endl;
00109 std::cout << " xp = " << xp << std::endl;
00110 }
00111 #endif
00112
00113
00114 {
00115 double x2 = 0,c2 = 0;
00116 test::Timer t("SMatrix Kalman ");
00117
00118 MnVectorM x;
00119 MnMatrixMN tmp;
00120 MnSymMatrixNN Rinv;
00121 MnMatrixMN K;
00122 MnSymMatrixMM C;
00123 MnVectorN vtmp1;
00124 MnVectorN vtmp;
00125
00126 for (int l = 0; l < NLOOP; l++)
00127 {
00128
00129
00130
00131 vtmp1 = H*xp -m;
00132
00133 x = xp - K0 * vtmp1;
00134 tmp = Cp * Transpose(H);
00135 Rinv = V; Rinv += H * tmp;
00136
00137 bool test = Rinv.Invert();
00138 if(!test) {
00139 std::cout<<"inversion failed" <<std::endl;
00140 std::cout << Rinv << std::endl;
00141 }
00142
00143 K = tmp * Rinv ;
00144 C = Cp; C -= K * Transpose(tmp);
00145
00146
00147 vtmp = m-H*xp;
00148 x2 = Dot(vtmp, Rinv*vtmp);
00149
00150 }
00151
00152 x2sum += x2;
00153 c2 = 0;
00154 for (int i=0; i<NDIM2; ++i)
00155 for (int j=0; j<NDIM2; ++j)
00156 c2 += C(i,j);
00157 c2sum += c2;
00158 }
00159 }
00160
00161
00162 std::cerr << "SMatrix: x2sum = " << x2sum << "\tc2sum = " << c2sum << std::endl;
00163
00164 return 0;
00165 }
00166
00167 #ifdef TEST_SYM
00168 int test_smatrix_sym_kalman() {
00169
00170
00171
00172
00173 typedef SMatrix<double, NDIM1, NDIM1> MnMatrixNN;
00174 typedef SMatrix<double, NDIM2, NDIM2> MnMatrixMM;
00175 typedef SMatrix<double, NDIM1, NDIM2> MnMatrixNM;
00176 typedef SMatrix<double, NDIM2 , NDIM1> MnMatrixMN;
00177 typedef SMatrix<double, NDIM1, NDIM1, MatRepSym<double, NDIM1> > MnSymMatrixNN;
00178 typedef SMatrix<double, NDIM2, NDIM2, MatRepSym<double, NDIM2> > MnSymMatrixMM;
00179 typedef SVector<double, NDIM1> MnVectorN;
00180 typedef SVector<double, NDIM2> MnVectorM;
00181 typedef SVector<double, NDIM1*(NDIM1+1)/2> MnVectorN2;
00182 typedef SVector<double, NDIM2*(NDIM2+1)/2> MnVectorM2;
00183
00184
00185
00186 int first = NDIM1;
00187 int second = NDIM2;
00188
00189
00190 std::cout << "************************************************\n";
00191 std::cout << " SMatrix_SyM kalman test " << first << " x " << second << std::endl;
00192 std::cout << "************************************************\n";
00193
00194
00195
00196
00197 int npass = NITER;
00198 TRandom3 r(111);
00199 double x2sum = 0, c2sum = 0;
00200 for (int k = 0; k < npass; k++) {
00201
00202
00203
00204 MnMatrixNM H;
00205 MnMatrixMN K0;
00206 MnSymMatrixMM Cp;
00207 MnSymMatrixNN V;
00208 MnVectorN m;
00209 MnVectorM xp;
00210
00211
00212 {
00213
00214 fillRandomMat(r,H,first,second);
00215 fillRandomMat(r,K0,second,first);
00216 fillRandomSym(r,Cp,second);
00217 fillRandomSym(r,V,first);
00218 fillRandomVec(r,m,first);
00219 fillRandomVec(r,xp,second);
00220 }
00221
00222
00223 MnSymMatrixMM I;
00224 for(int i = 0; i < second; i++)
00225 I(i,i) = 1;
00226
00227 #ifdef DEBUG
00228 std::cout << "pass " << k << std::endl;
00229 if (k == 0) {
00230 std::cout << " K0 = " << K0 << std::endl;
00231 std::cout << " H = " << K0 << std::endl;
00232 std::cout << " Cp = " << Cp << std::endl;
00233 std::cout << " V = " << V << std::endl;
00234 std::cout << " m = " << m << std::endl;
00235 std::cout << " xp = " << xp << std::endl;
00236 }
00237 #endif
00238
00239
00240 {
00241 double x2 = 0,c2 = 0;
00242 test::Timer t("SMatrix Kalman ");
00243
00244 MnVectorM x;
00245 MnSymMatrixNN RinvSym;
00246 MnMatrixMN K;
00247 MnSymMatrixMM C;
00248 MnSymMatrixMM Ctmp;
00249 MnVectorN vtmp1;
00250 MnVectorN vtmp;
00251 #define OPTIMIZED_SMATRIX_SYM
00252 #ifdef OPTIMIZED_SMATRIX_SYM
00253 MnMatrixMN tmp;
00254 #endif
00255
00256 for (int l = 0; l < NLOOP; l++)
00257 {
00258
00259
00260 #ifdef OPTIMIZED_SMATRIX_SYM
00261 vtmp1 = H*xp -m;
00262
00263 x = xp - K0 * vtmp1;
00264 tmp = Cp * Transpose(H);
00265
00266 AssignSym::Evaluate(RinvSym,H*tmp);
00267 RinvSym += V;
00268
00269 bool test = RinvSym.Invert();
00270 if(!test) {
00271 std::cout<<"inversion failed" <<std::endl;
00272 std::cout << RinvSym << std::endl;
00273 }
00274
00275 K = tmp * RinvSym ;
00276
00277 AssignSym::Evaluate(Ctmp, K*Transpose(tmp) );
00278 C = Cp; C -= Ctmp;
00279
00280
00281 vtmp = m-H*xp;
00282 x2 = Dot(vtmp, RinvSym*vtmp);
00283 #else
00284
00285 vtmp1 = H*xp -m;
00286 x = xp - K0 * vtmp1;
00287 RinvSym = V; RinvSym += Similarity(H,Cp);
00288
00289 bool test = RinvSym.Invert();
00290 if(!test) {
00291 std::cout<<"inversion failed" <<std::endl;
00292 std::cout << RinvSym << std::endl;
00293 }
00294
00295 Ctmp = SimilarityT(H, RinvSym);
00296 C = Cp; C -= Similarity(Cp, Ctmp);
00297 vtmp = m-H*xp;
00298 x2 = Similarity(vtmp, RinvSym);
00299 #endif
00300
00301 }
00302
00303 x2sum += x2;
00304 c2 = 0;
00305 for (int i=0; i<NDIM2; ++i)
00306 for (int j=0; j<NDIM2; ++j)
00307 c2 += C(i,j);
00308 c2sum += c2;
00309 }
00310 }
00311
00312
00313 std::cerr << "SMatrixSym: x2sum = " << x2sum << "\tc2sum = " << c2sum << std::endl;
00314
00315 return 0;
00316 }
00317
00318 #endif
00319
00320
00321
00322
00323
00324 int test_tmatrix_kalman() {
00325
00326
00327
00328
00329 typedef TMatrixD MnMatrix;
00330 typedef TVectorD MnVector;
00331
00332
00333
00334
00335
00336 int first = NDIM1;
00337 int second = NDIM2;
00338
00339
00340 std::cout << "************************************************\n";
00341 std::cout << " TMatrix Kalman test " << first << " x " << second << std::endl;
00342 std::cout << "************************************************\n";
00343
00344
00345
00346 int npass = NITER;
00347 TRandom3 r(111);
00348 gMatrixCheck = 0;
00349 double x2sum = 0,c2sum = 0;
00350
00351 for (int k = 0; k < npass; k++)
00352 {
00353
00354 MnMatrix H(first,second);
00355 MnMatrix K0(second,first);
00356 MnMatrix Cp(second,second);
00357 MnMatrix V(first,first);
00358 MnVector m(first);
00359 MnVector xp(second);
00360
00361
00362 fillRandomMat(r,H,first,second);
00363 fillRandomMat(r,K0,second,first);
00364 fillRandomSym(r,Cp,second);
00365 fillRandomSym(r,V,first);
00366 fillRandomVec(r,m,first);
00367 fillRandomVec(r,xp,second);
00368
00369
00370 MnMatrix I(second,second);
00371 for (int i = 0; i < second; i++)
00372 for(int j = 0; j <second; j++) {
00373 I(i,j) = 0.0;
00374 if (i==j) I(i,i) = 1.0;
00375 }
00376
00377
00378
00379
00380
00381
00382 {
00383 double x2 = 0,c2 = 0;
00384 TVectorD x(second);
00385 TMatrixD Rinv(first,first);
00386 TMatrixD Rtmp(first,first);
00387 TMatrixDSym RinvSym;
00388 TMatrixD K(second,first);
00389 TMatrixD C(second,second);
00390 TMatrixD Ctmp(second,second);
00391 TVectorD tmp1(first);
00392 TMatrixD tmp2(second,first);
00393 #define OPTIMIZED_TMATRIX
00394 #ifndef OPTIMIZED_TMATRIX
00395 TMatrixD HT(second,first);
00396 TMatrixD tmp2T(first,second);
00397 #endif
00398
00399 test::Timer t("TMatrix Kalman ");
00400 for (Int_t l = 0; l < NLOOP; l++)
00401 {
00402 #ifdef OPTIMIZED_TMATRIX
00403 tmp1 = m; Add(tmp1,-1.0,H,xp);
00404 x = xp; Add(x,+1.0,K0,tmp1);
00405 tmp2.MultT(Cp,H);
00406 Rtmp.Mult(H,tmp2);
00407 Rinv.Plus(V,Rtmp);
00408 RinvSym.Use(first,Rinv.GetMatrixArray());
00409 RinvSym.InvertFast();
00410 K.Mult(tmp2,Rinv);
00411 Ctmp.MultT(K,tmp2);
00412 C.Minus(Cp,Ctmp);
00413 x2 = RinvSym.Similarity(tmp1);
00414
00415 #else
00416 tmp1 = H*xp -m;
00417
00418 x = xp - K0 * tmp1;
00419 tmp2 = Cp * HT.Transpose(H);
00420 Rinv = V; Rinv += H * tmp2;
00421 RinvSym.Use(first,Rinv.GetMatrixArray());
00422 RinvSym.InvertFast();
00423 K= tmp2* Rinv;
00424 C = Cp; C -= K*tmp2T.Transpose(tmp2);
00425 x2= RinvSym.Similarity(tmp1);
00426 #endif
00427
00428 }
00429 x2sum += x2;
00430 c2 = 0;
00431 for (int i=0; i<NDIM2; ++i)
00432 for (int j=0; j<NDIM2; ++j)
00433 c2 += C(i,j);
00434 c2sum += c2;
00435 }
00436
00437
00438 }
00439
00440 std::cerr << "TMatrix: x2sum = " << x2sum << "\tc2sum = " << c2sum << std::endl;
00441
00442 return 0;
00443 }
00444
00445
00446
00447
00448 #ifdef HAVE_CLHEP
00449 int test_clhep_kalman() {
00450
00451
00452
00453 typedef HepSymMatrix MnSymMatrix;
00454 typedef HepMatrix MnMatrix;
00455 typedef HepVector MnVector;
00456
00457
00458
00459
00460
00461
00462 int first = NDIM1;
00463 int second = NDIM2;
00464
00465
00466 std::cout << "************************************************\n";
00467 std::cout << " CLHEP Kalman test " << first << " x " << second << std::endl;
00468 std::cout << "************************************************\n";
00469
00470
00471
00472 int npass = NITER;
00473 TRandom3 r(111);
00474 double x2sum = 0,c2sum = 0;
00475
00476 for (int k = 0; k < npass; k++)
00477 {
00478
00479
00480 MnMatrix H(first,second);
00481 MnMatrix K0(second,first);
00482 MnMatrix Cp(second,second);
00483 MnMatrix V(first,first);
00484 MnVector m(first);
00485 MnVector xp(second);
00486
00487
00488 fillRandomMat(r,H,first,second,1);
00489 fillRandomMat(r,K0,second,first,1);
00490 fillRandomSym(r,Cp,second,1);
00491 fillRandomSym(r,V,first,1);
00492 fillRandomVec(r,m,first);
00493 fillRandomVec(r,xp,second);
00494
00495 MnSymMatrix I(second,1);
00496
00497 {
00498 double x2 = 0,c2 = 0;
00499 MnVector x(second);
00500 MnMatrix Rinv(first,first);
00501 MnSymMatrix RinvSym(first);
00502 MnMatrix K(second,first);
00503 MnSymMatrix C(second);
00504 MnVector vtmp1(first);
00505 MnMatrix tmp(second,first);
00506
00507 test::Timer t("CLHEP Kalman ");
00508 int ifail;
00509 for (Int_t l = 0; l < NLOOP; l++)
00510 {
00511
00512
00513 vtmp1 = H*xp -m;
00514
00515 x = xp - K0 * vtmp1;
00516 tmp = Cp * H.T();
00517 Rinv = V; Rinv += H * tmp;
00518 RinvSym.assign(Rinv);
00519 RinvSym.invert(ifail);
00520 if (ifail !=0) { std::cout << "Error inverting Rinv" << std::endl; break; }
00521 K = tmp*RinvSym;
00522
00523
00524 C.assign( (I-K*H)*Cp );
00525 x2= RinvSym.similarity(vtmp1);
00526 if(ifail!=0) { std::cout << "Error inverting Rinv" << std::endl; break; }
00527 }
00528
00529 x2sum += x2;
00530
00531 c2 = 0;
00532 for (int i=1; i<=NDIM2; ++i)
00533 for (int j=1; j<=NDIM2; ++j)
00534 c2 += C(i,j);
00535 c2sum += c2;
00536 }
00537
00538
00539 }
00540
00541 std::cerr << "x2sum = " << x2sum << "\tc2sum = " << c2sum << std::endl;
00542
00543 return 0;
00544 }
00545 #endif
00546
00547
00548
00549 int testKalman() {
00550
00551 #ifdef TEST_SYM
00552 test_smatrix_sym_kalman();
00553 #endif
00554
00555 test_smatrix_kalman();
00556 test_tmatrix_kalman();
00557 #ifdef HAVE_CLHEP
00558 test_clhep_kalman();
00559 #endif
00560
00561 return 0;
00562
00563
00564 }
00565
00566 int main() {
00567 return testKalman();
00568 }