testSMatrix.cxx

Go to the documentation of this file.
00001 #include <cmath>
00002 #include "Math/SVector.h"
00003 #include "Math/SMatrix.h"
00004 
00005 #include <iostream>
00006 #include <vector>
00007 #include <string>
00008 #include <limits>
00009 
00010 
00011 using namespace ROOT::Math;
00012 
00013 using std::cout;
00014 using std::endl;
00015 
00016 
00017 //#define TEST_STATIC_CHECK  // for testing compiler failures (static check)
00018 
00019 #define XXX
00020 
00021 template<class T> 
00022 int compare( T a, T b, const std::string & s="",double tol = 1) { 
00023   if (a == b) return 0; 
00024   double eps = tol*8.*std::numeric_limits<T>::epsilon();
00025 
00026   if (a == 0 && std::abs(b) < eps ) return 0; 
00027   if (b == 0 && std::abs(a) < eps ) return 0; 
00028   if (std::abs(a-b) < a*eps) return 0; 
00029   if ( s =="" ) 
00030     std::cout << "\nFailure " << a << " different than " << b << std::endl;
00031   else 
00032     std::cout << "\n" << s << " : Failure " << a << " different than " << b << std::endl;
00033   return 1;
00034 }
00035 
00036 int compare( int a, int b, const std::string & s="") { 
00037   if (a == b) return 0; 
00038   if ( s =="" ) 
00039     std::cout << "\nFailure " << a << " different than " << b << std::endl;
00040   else 
00041     std::cout << "\n" << s << " : Failure " << a << " different than " << b << std::endl;
00042   return 1;
00043 }
00044 int compare( bool a, bool b, const std::string & s="") { 
00045   return compare(static_cast<int>(a), static_cast<int>(b),s); 
00046 }
00047 
00048 int test1() { 
00049 
00050   SVector<float,3> x(4,5,6);
00051   SVector<float,2> y(2.0,3.0);
00052   cout << "x: " << x << endl;
00053   cout << "y: " << y << endl;
00054 
00055 //   float yy1=2.; float yy2 = 3;
00056 //   SVector<float,2> y2(yy1,yy2);
00057   
00058   
00059   SMatrix<float,4,3> A;
00060   SMatrix<float,2,2> B;
00061   
00062   A.Place_in_row(y, 1, 1);
00063   A.Place_in_col(x, 1, 0);
00064   A.Place_in_col(x + 2, 1, 0);
00065   A.Place_in_row(y + 3, 1, 1);
00066   
00067 
00068 #ifndef _WIN32
00069   A.Place_at(B , 2, 1);
00070 #else
00071   //Windows need template parameters
00072   A.Place_at<2,2>(B , 2, 1);
00073 #endif
00074   cout << "A: " << endl << A << endl;
00075 
00076   SVector<float,3> z(x+2);
00077   z.Place_at(y, 1);
00078   z.Place_at(y+3, 1);
00079   cout << "z: " << endl << z << endl;
00080 
00081   
00082 #ifdef TEST_STATIC_CHECK
00083   // create a vector of size 2 from 3 arguments
00084   SVector<float, 2> vbad(1,2,3);
00085 #endif
00086   
00087   // test STL interface
00088   
00089   //float p[2] = {1,2};
00090   float m[4] = {1,2,3,4};
00091   
00092   //SVector<float, 2> sp(p,2);
00093   SMatrix<float, 2,2> sm(m,4);
00094 
00095   //cout << "sp: " << endl << sp << endl;
00096   cout << "sm: " << endl << sm << endl;
00097 
00098   //std::vector<float> vp(sp.begin(), sp.end() );
00099   std::vector<float> vm(sm.begin(), sm.end() );
00100 
00101   SVector<float, 4> sp1(m,4);
00102   SVector<float, 4> sp2(sm.begin(),sm.end());
00103   SMatrix<float, 2,2> sm2(vm.begin(),vm.end());
00104 
00105   if ( sp1 != sp2) { cout << "Test STL interface for SVector failed" << endl; return -1; }
00106   if ( sm2 != sm) { cout << "Test STL interface for SMatrix failed" << endl; return -1; }
00107 
00108 
00109   // test construction from identity
00110   SMatrix<float,3,3> i3 = SMatrixIdentity(); 
00111 
00112   cout << "3x3 Identity\n" << i3 << endl;
00113 
00114   SMatrix<float,2,3> i23 = SMatrixIdentity(); 
00115   cout << "2x3 Identity\n" << i23 << endl;
00116 
00117   SMatrix<float,3,3,MatRepSym<float,3> > is3 = SMatrixIdentity(); 
00118   cout << "Sym matrix Identity\n" << is3 << endl;
00119 
00120 
00121   // test operator = from identity
00122   A = SMatrixIdentity();
00123   cout << "4x3 Identity\n" << A << endl;
00124 
00125   std::vector<float> v(6);
00126   for (int i = 0; i <6; ++i) v[i] = double(i+1);
00127   SMatrix<float,3,3,MatRepSym<float,3> > s3(v.begin(), v.end() );
00128   cout << s3 << endl;
00129 
00130     
00131   return 0;
00132     
00133 }
00134 
00135 int test2() { 
00136 #ifdef XXX
00137   SMatrix<double,3> A;
00138   A(0,0) = A(1,0) = 1;
00139   A(0,1) = 3;
00140   A(1,1) = A(2,2) = 2;
00141   cout << "A: " << endl << A << endl;
00142 
00143   SVector<double,3> x = A.Row(0);
00144   cout << "x: " << x << endl;
00145 
00146   SVector<double,3> y = A.Col(1);
00147   cout << "y: " << y << endl;
00148 
00149   return 0;
00150 #endif
00151 }
00152 
00153 int test3() { 
00154 #ifdef XXX
00155   SMatrix<double,3> A;
00156   A(0,0) = A(0,1) = A(1,0) = 1;
00157   A(1,1) = A(2,2) = 2;
00158 
00159   SMatrix<double,3> B = A; // save A in B
00160   cout << "A: " << endl << A << endl;
00161 
00162   double det = 0.;
00163   A.Det(det);
00164   cout << "Determinant: " << det << endl;
00165   // WARNING: A has changed!!
00166   cout << "A again: " << endl << A << endl;
00167   A = B; 
00168 
00169   A.Invert();
00170   cout << "A^-1: " << endl << A << endl;
00171 
00172   // check if this is really the inverse:
00173   cout << "A^-1 * B: " << endl << A * B << endl;
00174 
00175   return 0;
00176 #endif
00177 }
00178 
00179 int test4() { 
00180 #ifdef XXX
00181   SMatrix<double,3> A;
00182   A(0,0) = A(0,1) = A(1,0) = 1;
00183   A(1,1) = A(2,2) = 2;
00184   cout << " A: " << endl << A << endl;
00185 
00186   SVector<double,3> x(1,2,3);
00187   cout << "x: " << x << endl;
00188 
00189   // we add 1 to each component of x and A
00190   cout << " (x+1)^T * (A+1) * (x+1): " << Similarity(x+1,A+1) << endl;
00191 
00192   return 0;
00193 #endif
00194 }
00195 
00196 int test5() { 
00197 #ifdef XXX
00198   SMatrix<float,4,3> A;
00199   A(0,0) = A(0,1) = A(1,1) = A(2,2) = 4.;
00200   A(2,3) = 1.;
00201   cout << "A: " << endl << A << endl;
00202   SVector<float,4> x(1,2,3,4);
00203   cout << " x: " << x << endl;
00204   SVector<float,3> a(1,2,3);
00205   cout << " a: " << a << endl;
00206   SVector<float,4> y = x + A * a;
00207   //    SVector<float,4> y = A * a;
00208   cout << " y: " << y << endl;
00209 
00210   SVector<float,3> b = (x+1) * (A+1);
00211   cout << " b: " << b << endl;
00212 
00213   return 0;
00214 #endif
00215 }
00216 
00217 int test6() { 
00218 #ifdef XXX
00219   SMatrix<float,4,2> A;
00220   A(0,0) = A(0,1) = A(1,1) = A(2,0) = A(3,1) = 4.;
00221   cout << "A: " << endl << A << endl;
00222   
00223   SMatrix<float,2,3> S;
00224   S(0,0) = S(0,1) = S(1,1) = S(0,2) = 1.;
00225   cout << " S: " << endl << S << endl;
00226   
00227   SMatrix<float,4,3> C = A * S;
00228   cout << " C: " << endl << C << endl;
00229   
00230   return 0;
00231 #endif
00232 }
00233 
00234 int test7() { 
00235 #ifdef XXX
00236   SVector<float,3>    xv(4,4,4);
00237   SVector<float,3>    yv(5,5,5);
00238   SVector<float,2>    zv(64,64);
00239   SMatrix<float,2,3>  x; 
00240   x.Place_in_row(xv,0,0);
00241   x.Place_in_row(xv,1,0);
00242   SMatrix<float,2,3>  y;  
00243   y.Place_in_row(yv,0,0);
00244   y.Place_in_row(yv,1,0);
00245   SMatrix<float,2,3>  z;
00246   z.Place_in_col(zv,0,0);
00247   z.Place_in_col(zv,0,1);
00248   z.Place_in_col(zv,0,2);
00249 
00250   cout << "x\n" << x << "y\n" << y << "z\n" << z << endl;
00251 
00252   // element wise multiplication
00253   cout << "x * (- y) : " << endl << Times(x, -y) << endl;
00254 
00255   x += z - y;
00256   cout << "x += z - y: " << endl << x << endl;
00257 
00258   // element wise square root
00259   cout << "sqrt(z): " << endl << sqrt(z) << endl;
00260 
00261   // element wise multiplication with constant
00262   cout << "2 * y: " << endl << 2 * y << endl;
00263 
00264   // a more complex expression (failure on Win32)
00265 #ifndef _WIN32
00266   //cout << "fabs(-z + 3*x): " << endl << fabs(-z + 3*x) << endl;
00267   cout << "fabs(3*x -z): " << endl << fabs(3*x -z) << endl;
00268 #else 
00269   // doing directly gives internal compiler error on windows
00270   SMatrix<float,2,3>  ztmp = 3*x - z; 
00271   cout << " fabs(-z+3*x) " << endl << fabs(ztmp) << endl;
00272 #endif
00273 
00274   return 0;
00275 #endif
00276 }
00277 
00278 int test8() { 
00279 #ifdef XXX
00280   SMatrix<float,2,3> A;
00281   SVector<float,3>    av1(5.,15.,5.);
00282   SVector<float,3>    av2(15.,5.,15.);
00283   A.Place_in_row(av1,0,0);
00284   A.Place_in_row(av2,1,0);
00285   
00286   cout << "A: " << endl << A << endl;
00287 
00288   SVector<float,3>    x(1,2,3);
00289   SVector<float,3>    y(4,5,6);
00290 
00291   cout << "dot(x,y): " << Dot(x,y) << endl;
00292 
00293   cout << "mag(x): " << Mag(x) << endl;
00294 
00295   cout << "cross(x,y): " << Cross(x,y) << endl;
00296 
00297   cout << "unit(x): " << Unit(x) << endl;
00298 
00299   SVector<float,3>    z(4,16,64);
00300   cout << "x + y: " << x+y << endl;
00301 
00302   cout << "x + y(0) " << (x+y)(0) << endl;
00303 
00304   cout << "x * -y: " << x * -y << endl;
00305   x += z - y;
00306   cout << "x += z - y: " << x << endl;
00307 
00308   // element wise square root
00309   cout << "sqrt(z): " << sqrt(z) << endl;
00310 
00311   // element wise multiplication with constant
00312   cout << "2 * y: " << 2 * y << endl;
00313 
00314   // a more complex expression
00315   cout << "fabs(-z + 3*x): " << fabs(-z + 3*x) << endl;
00316 
00317   SVector<float,4> a;
00318   SVector<float,2> b(1,2);
00319   a.Place_at(b,2);
00320   cout << "a: " << a << endl;
00321 #endif
00322 
00323   SVector<float,3> x2 = Square(x); 
00324   std::cout << x2 << std::endl;
00325 
00326 
00327   return 0;
00328 }
00329 
00330 int test9() { 
00331   // test non mutating inversions
00332   SMatrix<double,3> A;
00333   A(0,0) = A(0,1) = A(1,0) = 1;
00334   A(1,1) = A(2,2) = 2;
00335 
00336 
00337   double det = 0.;
00338   A.Det2(det);
00339   cout << "Determinant: " << det << endl;
00340 
00341   int ifail; 
00342   SMatrix<double,3> Ainv = A.Inverse(ifail);
00343   if (ifail) { 
00344     cout << "inversion failed\n";
00345     return -1;
00346   } 
00347   cout << "A^-1: " << endl << Ainv << endl;
00348 
00349   // check if this is really the inverse:
00350   cout << "A^-1 * A: " << endl << Ainv * A << endl;
00351 
00352   return 0;
00353 }
00354 
00355 int test10() { 
00356   // test slices
00357   int iret = 0;
00358   double d[9] = { 1,2,3,4,5,6,7,8,9};
00359   SMatrix<double,3> A( d,d+9);
00360 
00361   cout << "A: " << A << endl;
00362 
00363   SVector<double,2> v23 = A.SubRow<SVector<double,2> >( 0,1);    
00364   SVector<double,2> v69 = A.SubCol<SVector<double,2> >( 2,1);    
00365 
00366   std::cout << " v23 =  " << v23 << " \tv69 = " << v69 << std::endl;
00367   iret |= compare( Dot(v23,v69),double(2*6+3*9) ); 
00368   
00369 //    SMatrix<double,2,2> subA1 = A.Sub<2,2>( 1,0);
00370 //    SMatrix<double,2,3> subA2 = A.Sub<2,3>( 0,0);
00371   SMatrix<double,2,2> subA1 = A.Sub< SMatrix<double,2,2> > ( 1,0);
00372   SMatrix<double,2,3> subA2 = A.Sub< SMatrix<double,2,3> > ( 0,0);
00373   std::cout << " subA1 =  " << subA1 << " \nsubA2 = " << subA2 << std::endl;
00374   iret |= compare ( subA1(0,0), subA2(1,0)); 
00375   iret |= compare ( subA1(0,1), subA2(1,1)); 
00376 
00377 
00378 
00379   SVector<double,3> diag = A.Diagonal();
00380   std::cout << " diagonal =  " << diag << std::endl; 
00381   iret |= compare( Mag2(diag) , double(1+5*5+9*9) ); 
00382   iret |= compare( A.Trace() , double(1+5+9) ); 
00383 
00384 
00385   SMatrix<double,3> B = Transpose(A);
00386   std::cout << " B = " << B << std::endl;
00387 
00388 #ifdef UNSUPPORTED_TEMPLATE_EXPRESSION
00389   // in this case  function is templated. Need to pass the 6 
00390   SVector<double,6> vU = A.UpperBlock< SVector<double,6> >();
00391   SVector<double,6> vL = B.LowerBlock< SVector<double,6> >();
00392 #else 
00393   // standards
00394   SVector<double,6> vU = A.UpperBlock();
00395   SVector<double,6> vL = B.LowerBlock();
00396 #endif
00397   std::cout << " vU =  " << vU << " \tvL = " << vL << std::endl;
00398   // need to test mag since order can change
00399   iret |= compare( Mag(vU), Mag(vL) ); 
00400 
00401   // test subvector
00402   SVector<double,3> subV = vU.Sub< SVector<double,3> >(1);
00403   std::cout << " sub vU =  " << subV << std::endl;
00404 
00405   iret |= compare( vU[2], subV[1] ); 
00406   
00407   // test constructor from subVectors
00408   SMatrix<double,3> C(vU,false);
00409   SMatrix<double,3> D(vL,true);
00410 
00411 //   std::cout << " C =  " << C << std::endl;
00412 //   std::cout << " D =  " << D << std::endl;
00413 
00414   iret |= compare( static_cast<int>(C==D), 1 ); 
00415 
00416   SMatrix<double,3, 3, MatRepSym<double,3> > C2(vU,false);
00417   SMatrix<double,3, 3, MatRepSym<double,3> > D2(vL,true);
00418 
00419   iret |= compare( static_cast<int>(C==C2), 1 ); 
00420   iret |= compare( static_cast<int>(D==D2), 1 ); 
00421 
00422 
00423   return iret;
00424 }
00425 
00426 
00427 int test11() { 
00428 
00429   int iret = 0;
00430   double dSym[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
00431   double d3[10] = {1,2,3,4,5,6,7,8,9,10};
00432   double d2[10] = {10,1,4,5,8,2,3,6,7,9};
00433 
00434   SVector<double,15> vsym(dSym,15);
00435   
00436   SMatrix<double,5,5> m1(vsym);
00437   SMatrix<double,2,5> m2(d2,d2+10);
00438   SMatrix<double,5,2> m3(d3,d3+10);
00439   //SMatrix<double,5,5> I; 
00440 
00441   SMatrix<double,5,5> m32 = m3*m2;
00442 
00443   SMatrix<double,5,5> m4 = m1 -  m32 * m1; 
00444   SMatrix<double,5,5> m5 = m3*m2;
00445 
00446   // now thanks to the IsInUse() function this should work 
00447   m5 =  m1 - m5 * m1;
00448 
00449   // this works probably becuse here multiplication is done first
00450   
00451   SMatrix<double,5,5> m6 = m3*m2;
00452   //m6 =  - m6 * m1 + m1;
00453   // this does not work if use reference in binary and unary operators , better this
00454   m6 =  - m32 * m1 + m1;
00455 
00456   
00457   std::cout << m4 << std::endl;
00458   std::cout << m5 << std::endl;
00459   std::cout << m6 << std::endl;
00460 
00461   // this is test will now work  
00462   iret |= compare( m4==m5, true ); 
00463   iret |= compare( m4==m6, true ); 
00464 
00465 
00466 
00467   return iret;
00468 }
00469 
00470 
00471 int test12() {
00472   // test of symmetric matrices
00473 
00474   int iret = 0; 
00475   SMatrix<double,2,2,MatRepSym<double,2> >  S; 
00476   S(0,0) = 1.233;
00477   S(0,1) = 2.33; 
00478   S(1,1) = 3.45; 
00479   std::cout << "S\n" << S << std::endl;
00480 
00481   double a = 3; 
00482   std::cout << "S\n" << a * S << std::endl;
00483 
00484   // test inversion
00485   int ifail1 = 0; 
00486   //int ifail2 = 0; 
00487   SMatrix<double,2,2,MatRepSym<double,2> > Sinv1 = S.Inverse (ifail1);  
00488   //SMatrix<double,2,2,MatRepSym<double,2> > Sinv2 = S.Sinverse(ifail2);
00489   //std::cout << "Inverse:  S-1 " <<  Sinv1 << "\nifail=" << ifail1 << std::endl;
00490   //std::cout << "Sinverse: S-1"  << Sinv2 << "\nifail=" << ifail2 << std::endl;
00491 
00492   SMatrix<double,2> IS1 = S*Sinv1;
00493   //SMatrix<double,2> IS2 = S*Sinv2;
00494   double d1 = std::sqrt( IS1(1,0)*IS1(1,0) + IS1(0,1)*IS1(0,1) ); 
00495   //double d2 = std::sqrt( IS2(1,0)*IS2(1,0) + IS2(0,1)*IS2(0,1) ); 
00496 
00497 
00498   iret |= compare( d1 < 1E-6,true,"inversion1" ); 
00499   //iret |= compare( d2 < 1E-6,true,"inversion2" ); 
00500   
00501 
00502   SMatrix<double,2,3  >  M1 =  SMatrixIdentity(); 
00503   M1(0,1) = 1; M1(1,0) = 1; M1(0,2) = 1; M1(1,2) = 1;
00504   SMatrix<double,2,3  >  M2 =  SMatrixIdentity(); 
00505   SMatrix<double,2,2,MatRepSym<double,2> >  S2=S; 
00506   // S2 -= M1*Transpose(M2);  // this should fails to compile
00507   SMatrix<double,2 > mS2(S2);  
00508   mS2 -= M1*Transpose(M2);
00509   //std::cout << "S2=S-M1*M2T\n" << mS2 << std::endl;
00510   iret |= compare( mS2(0,1), S(0,1)-1 ); 
00511   mS2 += M1*Transpose(M2); 
00512   iret |= compare( mS2(0,1), S(0,1) ); 
00513  
00514   //std::cout << "S2+=M1*M2T\n" << mS2 << std::endl;
00515 
00516 
00517   SMatrix<float,100,100,MatRepSym<float,100> >  mSym; 
00518   SMatrix<float,100 >  m; 
00519   //std::cout << " Symmetric matrix size: " << sizeof(mSym) << std::endl; 
00520   //std::cout << " Normal    matrix size: " << sizeof( m  ) << std::endl; 
00521 
00522   SMatrix<float,100,100,MatRepSym<float,100> >  mSym2; 
00523   //std::cout << " Symmetric matrix size: " << sizeof(mSym2) << std::endl; 
00524 
00525 
00526   return iret; 
00527 } 
00528 
00529 int test13() { 
00530   // test of operation with a constant; 
00531 
00532   int iret = 0; 
00533 
00534   int a = 2;
00535   float b = 3;
00536 
00537 
00538   SVector<double,2> v(1,2); 
00539   SVector<double,2> v2= v + a; 
00540   iret |= compare( v2[1], v[1]+a ); 
00541   SVector<double,2> v3= a + v; 
00542   iret |= compare( v3[1], v[1]+a ); 
00543   iret |= compare( v3[0], v2[0] ); 
00544 
00545   v2 = v - a; 
00546   iret |= compare( v2[1], v[1]-a ); 
00547   v3 = a - v; 
00548   iret |= compare( v3[1], a - v[1] ); 
00549 
00550   // test now with expression
00551   v2 = b*v + a; 
00552   iret |= compare( v2[1], b*v[1]+a ); 
00553   v3 = a + v*b; 
00554   iret |= compare( v3[1], b*v[1]+a ); 
00555   v2 = v*b - a; 
00556   iret |= compare( v2[1], b*v[1]-a ); 
00557   v3 = a - b*v; 
00558   iret |= compare( v3[1], a - b*v[1] ); 
00559 
00560   v2 = a * v/b; 
00561   iret |= compare( v2[1], a*v[1]/b ); 
00562 
00563   SVector<double,2> p(1,2); 
00564   SVector<double,2> q(3,4);
00565   v = p+q; 
00566   v2 = a*(p+q);
00567   iret |= compare( v2[1], a*v[1] ); 
00568   v3 = (p+q)*b;
00569   iret |= compare( v3[1], b*v[1] ); 
00570   v2 = (p+q)/b;
00571   iret |= compare( v2[1], v[1]/b ); 
00572 
00573   //std::cout << "tested vector -constant operations : v2 = " << v2 << " v3 = " << v3 << std::endl;
00574 
00575   // now test the matrix (normal)
00576 
00577   SMatrix<double,2,2> m; 
00578   m.Place_in_row(p,0,0);
00579   m.Place_in_row(q,1,0);
00580 
00581   SMatrix<double,2,2> m2,m3; 
00582 
00583   m2= m + a; 
00584   iret |= compare( m2(1,0), m(1,0)+a ); 
00585   m3= a + m; 
00586   iret |= compare( m3(1,0), m(1,0)+a ); 
00587   iret |= compare( m3(0,0), m2(0,0) ); 
00588 
00589   m2 = m - a; 
00590   iret |= compare( m2(1,0), m(1,0)-a ); 
00591   m3 = a - m; 
00592   iret |= compare( m3(1,0), a - m(1,0) ); 
00593 
00594   // test now with expression
00595   m2 = b*m + a; 
00596   iret |= compare( m2(1,0), b*m(1,0)+a ); 
00597   m3 = a + m*b; 
00598   iret |= compare( m3(1,0), b*m(1,0)+a ); 
00599   m2 = m*b - a; 
00600   iret |= compare( m2(1,0), b*m(1,0)-a ); 
00601   m3 = a - b*m; 
00602   iret |= compare( m3(1,0), a - b*m(1,0) ); 
00603 
00604   m2 = a * m/b; 
00605   iret |= compare( m2(1,0), a*m(1,0)/b ); 
00606 
00607   SMatrix<double,2> u = m; 
00608   SMatrix<double,2> w; 
00609   w(0,0) = 5; w(0,1) = 6; w(1,0)=7; w(1,1) = 8;
00610 
00611   m = u+w; 
00612   m2 = a*(u+w);
00613   iret |= compare( m2(1,0), a*m(1,0) ); 
00614   m3 = (u+w)*b;
00615   iret |= compare( m3(1,0), b*m(1,0) ); 
00616   m2 = (u+w)/b;
00617   iret |= compare( m2(1,0), m(1,0)/b ); 
00618   
00619   //std::cout << "tested general matrix -constant operations :\nm2 =\n" << m2 << "\nm3 =\n" << m3 << std::endl;
00620 
00621   // now test the symmetric matrix 
00622 
00623   SMatrix<double,2,2,MatRepSym<double,2> > s; 
00624   s(0,0) = 1; s(1,0) = 2; s(1,1) = 3; 
00625 
00626   SMatrix<double,2,2,MatRepSym<double,2> > s2,s3; 
00627 
00628   s2= s + a; 
00629   iret |= compare( s2(1,0), s(1,0)+a ); 
00630   s3= a + s; 
00631   iret |= compare( s3(1,0), s(1,0)+a ); 
00632   iret |= compare( s3(0,0), s2(0,0) ); 
00633 
00634   s2 = s - a; 
00635   iret |= compare( s2(1,0), s(1,0)-a ); 
00636   s3 = a - s; 
00637   iret |= compare( s3(1,0), a - s(1,0) ); 
00638 
00639 
00640   // test now with expression
00641   s2 = b*s + a; 
00642   iret |= compare( s2(1,0), b*s(1,0)+a ); 
00643   s3 = a + s*b; 
00644   iret |= compare( s3(1,0), b*s(1,0)+a ); 
00645   s2 = s*b - a; 
00646   iret |= compare( s2(1,0), b*s(1,0)-a ); 
00647   s3 = a - b*s; 
00648   iret |= compare( s3(1,0), a - b*s(1,0) ); 
00649 
00650   s2 = a * s/b; 
00651   iret |= compare( s2(1,0), a*s(1,0)/b ); 
00652 
00653 
00654   SMatrix<double,2,2,MatRepSym<double,2> > r = s; 
00655   SMatrix<double,2,2,MatRepSym<double,2> > t; 
00656   t(0,0) = 4; t(0,1) = 5; t(1,1) = 6;
00657 
00658   s = r+t; 
00659   s2 = a*(r+t);
00660   iret |= compare( s2(1,0), a*s(1,0),"a*(r+t)" ); 
00661   s3 = (t+r)*b;
00662   iret |= compare( s3(1,0), b*s(1,0), "(t+r)*b" ); 
00663   s2 = (r+t)/b;
00664   iret |= compare( s2(1,0), s(1,0)/b, "(r+t)/b" ); 
00665 
00666   //std::cout << "tested sym matrix -constant operations :\ns2 =\n" << s2 << "\ns3 =\n" << s3 << std::endl;
00667 
00668 
00669   return iret; 
00670 }
00671 
00672 
00673 int test14() { 
00674   // test place_at (insertion) of all type of matrices
00675 
00676   int iret = 0; 
00677 
00678   // test place at with sym matrices 
00679 
00680   SMatrix<double,2,2,MatRepSym<double,2> >  S; 
00681   S(0,0) = 1;
00682   S(0,1) = 2; 
00683   S(1,1) = 3; 
00684 
00685   double u[6] = {1,2,3,4,5,6};
00686   SMatrix<double,2,3,MatRepStd<double,2,3> >  U(u,u+6); 
00687 
00688   //place general matrix in general matrix  
00689   SMatrix<double,4,4> A; 
00690   A.Place_at(U,1,0); 
00691   //std::cout << "Test general matrix placed in general at 1,0 :\nA=\n" << A << std::endl; 
00692   iret |= compare( A(1,0),U(0,0) );
00693   iret |= compare( A(1,1),U(0,1) );
00694   iret |= compare( A(2,1),U(1,1) );
00695   iret |= compare( A(2,2),U(1,2) );
00696 
00697   A.Place_at(-2*U,1,0);
00698   iret |= compare( A(1,0),-2*U(0,0) );
00699   iret |= compare( A(1,1),-2*U(0,1) );
00700   iret |= compare( A(2,1),-2*U(1,1) );
00701   iret |= compare( A(2,2),-2*U(1,2) );
00702 
00703 
00704   //place symmetric in general (should work always)
00705   A.Place_at(S,0,0); 
00706   //std::cout << "Test symmetric matrix placed in general at 0,0:\nA=\n" << A << std::endl; 
00707   iret |= compare( A(0,0),S(0,0) );
00708   iret |= compare( A(1,0),S(0,1) );
00709   iret |= compare( A(1,1),S(1,1) );
00710 
00711   A.Place_at(2*S,0,0); 
00712   iret |= compare( A(0,0),2*S(0,0) );
00713   iret |= compare( A(1,0),2*S(0,1) );
00714   iret |= compare( A(1,1),2*S(1,1) );
00715 
00716 
00717   A.Place_at(S,2,0); 
00718   //std::cout << "A=\n" << A << std::endl; 
00719   iret |= compare( A(2,0),S(0,0) );
00720   iret |= compare( A(3,0),S(0,1) );
00721   iret |= compare( A(3,1),S(1,1) );
00722 
00723 
00724   SMatrix<double,3,3,MatRepSym<double,3> >  B; 
00725 
00726   //place symmetric in symmetric (OK for col=row) 
00727   B.Place_at(S,1,1);
00728   //std::cout << "Test symmetric matrix placed in symmetric at 1,1:\nB=\n" << B << std::endl; 
00729   iret |= compare( B(1,1),S(0,0) );
00730   iret |= compare( B(2,1),S(0,1) );
00731   iret |= compare( B(2,2),S(1,1) );
00732 
00733   B.Place_at(-S,0,0);
00734   //std::cout << "B=\n" << B << std::endl; 
00735   iret |= compare( B(0,0),-S(0,0) );
00736   iret |= compare( B(1,0),-S(0,1) );
00737   iret |= compare( B(1,1),-S(1,1) );
00738 
00739 
00740   //this should assert at run time
00741   //B.Place_at(S,1,0); 
00742   //B.Place_at(2*S,1,0); 
00743 
00744   //place general in symmetric should fail to compiler
00745 #ifdef TEST_STATIC_CHECK
00746   B.Place_at(U,0,0);
00747   B.Place_at(-U,0,0);
00748 #endif
00749 
00750   // test place vector in matrices
00751   SVector<double,2> v(1,2);
00752 
00753   A.Place_in_row(v,1,1); 
00754   iret |= compare( A(1,1),v[0] );
00755   iret |= compare( A(1,2),v[1] );
00756   A.Place_in_row(2*v,1,1); 
00757   iret |= compare( A(1,1),2*v[0] );
00758   iret |= compare( A(1,2),2*v[1] );
00759 
00760   A.Place_in_col(v,1,1); 
00761   iret |= compare( A(1,1),v[0] );
00762   iret |= compare( A(2,1),v[1] );
00763   A.Place_in_col(2*v,1,1); 
00764   iret |= compare( A(1,1),2*v[0] );
00765   iret |= compare( A(2,1),2*v[1] );
00766   
00767   //place vector in sym matrices  
00768   B.Place_in_row(v,0,1); 
00769   //std::cout << "B=\n" << B << std::endl;
00770   iret |= compare( B(0,1),v[0] );
00771   iret |= compare( B(1,0),v[0] );
00772   iret |= compare( B(2,0),v[1] );
00773   B.Place_in_row(2*v,1,1); 
00774   iret |= compare( B(1,1),2*v[0] );
00775   iret |= compare( B(2,1),2*v[1] );
00776 
00777   B.Place_in_col(v,1,0); 
00778   //std::cout << "B=\n" << B << std::endl;
00779   iret |= compare( B(0,1),v[0] );
00780   iret |= compare( B(1,0),v[0] );
00781   iret |= compare( B(0,2),v[1] );
00782   B.Place_in_col(2*v,1,1); 
00783   iret |= compare( B(1,1),2*v[0] );
00784   iret |= compare( B(1,2),2*v[1] );
00785 
00786 
00787   // test Sub 
00788   SMatrix<double,2,2,MatRepSym<double,2> > sB = B.Sub<SMatrix<double,2,2,MatRepSym<double,2> > > (1,1); 
00789   iret |= compare( sB(0,0),B(1,1) );
00790   iret |= compare( sB(1,0),B(1,2) );
00791   iret |= compare( sB(1,1),B(2,2) );
00792 
00793   SMatrix<double,2,3,MatRepStd<double,2,3> > sA = A.Sub<SMatrix<double,2,3,MatRepStd<double,2,3> > > (1,0); 
00794   iret |= compare( sA(0,0),A(1,0) );
00795   iret |= compare( sA(1,0),A(2,0) );
00796   iret |= compare( sA(1,1),A(2,1) );
00797   iret |= compare( sA(1,2),A(2,2) );
00798 
00799   sA = B.Sub<SMatrix<double,2,3,MatRepStd<double,2,3> > > (0,0); 
00800   iret |= compare( sA(0,0),B(0,0) );
00801   iret |= compare( sA(1,0),B(1,0) );
00802   iret |= compare( sA(0,1),B(0,1) );
00803   iret |= compare( sA(1,1),B(1,1) );
00804   iret |= compare( sA(1,2),B(1,2) );
00805 
00806   //this should run assert
00807   //  sA = A.Sub<SMatrix<double,2,3,MatRepStd<double,2,3> > > (0,2); 
00808   //  sB = B.Sub<SMatrix<double,2,2,MatRepSym<double,2> > > (0,1);
00809 
00810 #ifdef TEST_STATIC_CHECK
00811   sB = A.Sub<SMatrix<double,2,2,MatRepSym<double,2> > > (0,0);
00812   SMatrix<double,5,2> tmp1 = A.Sub<SMatrix<double,5,2> >(0,0); 
00813   SMatrix<double,2,5> tmp2 = A.Sub<SMatrix<double,2,5> >(0,0); 
00814 #endif
00815 
00816 
00817   // test setDiagonal
00818   
00819 #ifdef TEST_STATIC_CHECK
00820   SVector<double,3> w(-1,-2,3);
00821   sA.SetDiagonal(w);
00822   sB.SetDiagonal(w);
00823 #endif
00824 
00825   sA.SetDiagonal(v);
00826   iret |= compare( sA(1,1),v[1] );
00827   sB.SetDiagonal(v);
00828   iret |= compare( sB(0,0),v[0] );
00829   
00830   // test Trace
00831   iret |= compare( sA.Trace(), v[0]+v[1]);
00832   iret |= compare( sB.Trace(), v[0]+v[1]);
00833   SMatrix<double,3,2> sAt = Transpose(sA);
00834   iret |= compare( sAt.Trace(), v[0]+v[1]);
00835 
00836 
00837   return iret;
00838 }
00839 
00840 
00841 
00842 int test15() { 
00843   // test using iterators 
00844   int iret = 0; 
00845 
00846   double u[12] = {1,2,3,4,5,6,7,8,9,10,11,12}; 
00847   double w[6] = {1,2,3,4,5,6};
00848 
00849   SMatrix<double,3,4> A1(u,12);
00850   iret |= compare( A1(0,0),u[0] );
00851   iret |= compare( A1(1,2),u[6] );
00852   iret |= compare( A1(2,3),u[11] );
00853   //cout << A1 << endl;
00854 
00855   SMatrix<double,3,4> A2(w,6,true,true);
00856   iret |= compare( A2(0,0),w[0] );
00857   iret |= compare( A2(1,0),w[1] );
00858   iret |= compare( A2(2,0),w[3] );
00859   iret |= compare( A2(2,2),w[5] );
00860   //cout << A2 << endl;
00861 
00862   // upper diagonal (needs 9 elements)
00863   SMatrix<double,3,4> A3(u,9,true,false);
00864   iret |= compare( A3(0,0),u[0] );
00865   iret |= compare( A3(0,1),u[1] );
00866   iret |= compare( A3(0,2),u[2] );
00867   iret |= compare( A3(1,2),u[5] );
00868   iret |= compare( A3(2,3),u[8] );
00869   //cout << A3 << endl;
00870 
00871 
00872   //cout << "test sym matrix " << endl;
00873   SMatrix<double,3,3,MatRepSym<double,3> > S1(w,6,true); 
00874   iret |= compare( S1(0,0),w[0] );
00875   iret |= compare( S1(1,0),w[1] );
00876   iret |= compare( S1(1,1),w[2] );
00877   iret |= compare( S1(2,0),w[3] );
00878   iret |= compare( S1(2,1),w[4] );
00879   iret |= compare( S1(2,2),w[5] );
00880 
00881   SMatrix<double,3,3,MatRepSym<double,3> > S2(w,6,true,false); 
00882   iret |= compare( S2(0,0),w[0] );
00883   iret |= compare( S2(1,0),w[1] );
00884   iret |= compare( S2(2,0),w[2] );
00885   iret |= compare( S2(1,1),w[3] );
00886   iret |= compare( S2(2,1),w[4] );
00887   iret |= compare( S2(2,2),w[5] );
00888 
00889   // check retrieve
00890   double * pA1 = A1.begin();
00891   for ( int i = 0; i< 12; ++i) 
00892     iret |= compare( pA1[i],u[i] );
00893 
00894   double * pS1 = S1.begin();
00895   for ( int i = 0; i< 6; ++i) 
00896     iret |= compare( pS1[i],w[i] );
00897 
00898 
00899   // check with SetElements
00900   std::vector<double> vu(u,u+12);
00901   std::vector<double> vw(w,w+6);
00902   SMatrix<double,3,4> B1;
00903   B1.SetElements(vu.begin(),10); 
00904   iret |= compare( B1(0,0),u[0] );
00905   iret |= compare( B1(1,2),u[6] );
00906   iret |= compare( B1(2,3),0.0 );
00907 
00908   B1.SetElements(vu.begin(),vu.end()); 
00909   iret |= compare( B1(0,0),vu[0] );
00910   iret |= compare( B1(1,2),vu[6] );
00911   iret |= compare( B1(2,3),vu[11] );
00912 
00913   B1.SetElements(vw.begin(),vw.end(),true,true); 
00914   iret |= compare( B1(0,0),w[0] );
00915   iret |= compare( B1(1,0),w[1] );
00916   iret |= compare( B1(2,0),w[3] );
00917   iret |= compare( B1(2,2),w[5] );
00918 
00919   SVector<double,12> v1; 
00920   v1.SetElements(vu.begin(),vu.end() ); 
00921   for (unsigned int i = 0; i < v1.kSize; ++i) 
00922      iret |= compare( v1[i],vu[i] );
00923 
00924   // v1.SetElements(vw.begin(),vw.end() ); // this assert at run-time
00925   v1.SetElements(vw.begin(), vw.size() );
00926   for (unsigned int i = 0; i < vw.size(); ++i) 
00927      iret |= compare( v1[i],vw[i] );
00928 
00929 
00930 
00931   return iret;
00932 }
00933 
00934 int test16() { 
00935   // test IsInUse() function  to create automatically temporaries 
00936   int iret = 0; 
00937 
00938   double a[6] = {1,2,3,4,5,6};
00939   double w[9] = {10,2,3,4,50,6,7,8,90};
00940   
00941   SMatrix<double,3,3,MatRepSym<double,3> > A(a,a+6); 
00942   SMatrix<double,3,3,MatRepSym<double,3> > B;
00943 //   SMatrix<double,3,3,MatRepSym<double,3> > C; 
00944 
00945   B = Transpose(A);
00946   A = Transpose(A);
00947   iret |= compare( A==B,true,"transp");
00948   
00949   SMatrix<double,3 > W(w,w+9); 
00950   SMatrix<double,3 > Y = W.Inverse(iret);
00951   SMatrix<double,3 > Z; 
00952   Z = W *  Y; 
00953   Y = W *  Y; 
00954 #ifndef _WIN32
00955   // this fails on Windows (bad calculations)
00956   iret |= compare( Z==Y,true,"mult");
00957 #else 
00958   for (int i = 0; i< 9; ++i) { 
00959     // avoid small value of a 
00960     double a = Z.apply(i); 
00961     double eps = std::numeric_limits<double>::epsilon();
00962     if (a < eps) a = 0; 
00963     iret |= compare(a,Y.apply(i),"index");
00964   }
00965 #endif
00966 
00967   Z = (A+W)*(B+Y); 
00968   Y = (A+W)*(B+Y); 
00969 
00970   iret |= compare( Z==Y,true,"complex mult");
00971 
00972 
00973   // test of assign sym
00974 //   AssignSym::Evaluate(A,  W * A * Transpose(W)  );
00975 //   AssignSym::Evaluate(B,  W * A * Transpose(W)  );
00976 //   iret |= compare( A==B,true,"assignsym");
00977   
00978 
00979   return iret; 
00980 }
00981 
00982 
00983 int test17() { 
00984   int iret =0;
00985   // tets tensor product
00986   SVector<double,2> v1(1,2); 
00987   SVector<double,3> v2(1,2,3); 
00988 
00989   SMatrix<double,2,3> m = TensorProd(v1,v2); 
00990   for (int i = 0; i < m.kRows ; ++i) 
00991      for (int j = 0; j < m.kCols ; ++j) 
00992         iret |= compare(m(i,j),v1(i)*v2(j) );
00993   //std::cout << "Tensor Product \n" << m << std::endl;
00994 
00995   SVector<double,4> a1(2,-1,3,4); 
00996   SVector<double,4> a2(5,6,1,-2); 
00997   
00998   SMatrix<double,4> A = TensorProd(a1,a2); 
00999   double r1 = Dot(a1, A * a2 ); 
01000   double r2 = Dot(a1, a1) * Dot(a2,a2 );
01001   iret |= compare(r1,r2,"tensor prod");
01002 
01003   A = TensorProd(2.*a1,a2); 
01004   r1 = Dot(a1, A * a2 )/2; 
01005   r2 = Dot(a1, a1) * Dot(a2,a2 );
01006   iret |= compare(r1,r2,"tensor prod");
01007 
01008 
01009   A = TensorProd(a1,2*a2); 
01010   r1 = Dot(a1, A * a2 )/2; 
01011   r2 = Dot(a1, a1) * Dot(a2,a2 );
01012   iret |= compare(r1,r2,"tensor prod");
01013 
01014   A = TensorProd(0.5*a1,2*a2); 
01015   r1 = Dot(a1, A * a2 ); 
01016   r2 = Dot(a1, a1) * Dot(a2,a2 );
01017   iret |= compare(r1,r2,"tensor prod");
01018  
01019   return iret;
01020 }
01021 
01022 // test inverison of large matrix (double) 
01023 int test18() { 
01024   int iret =0;
01025   // data for a 7x7 sym matrix to invert
01026   SMatrix<double,7,7,MatRepSym<double,7> > S;
01027   for (int i = 0; i < 7; ++i) {
01028     for (int j = 0; j <= i; ++j) { 
01029       if (i == j) 
01030         S(i,j) = 10*double(std::rand())/(RAND_MAX); // generate between 0,10
01031       else
01032         S(i,j) = 2*double(std::rand())/(RAND_MAX)-1; // generate between -1,1
01033     }
01034   }
01035   int ifail = 0;
01036   SMatrix<double,7,7,MatRepSym<double,7> > Sinv = S.Inverse(ifail);
01037   iret |= compare(ifail,0,"sym7x7 inversion");
01038   SMatrix<double,7> Id = S*Sinv; 
01039   for (int i = 0; i < 7; ++i)
01040     iret |= compare(Id(i,i),1.,"inv result");
01041 
01042   double sum = 0; 
01043   for (int i = 0; i < 7; ++i) 
01044     for (int j = 0; j <i; ++j)
01045       sum+= std::fabs(Id(i,j) );  // sum of off diagonal elements
01046 
01047   iret |= compare(sum < 1.E-10, true,"inv off diag");
01048 
01049   // now test inversion of general 
01050   SMatrix<double,7> M;
01051   for (int i = 0; i < 7; ++i) {
01052     for (int j = 0; j < 7; ++j) { 
01053       if (i == j) 
01054         M(i,j) = 10*double(std::rand())/(RAND_MAX); // generate between 0,10
01055       else
01056         M(i,j) = 2*double(std::rand())/(RAND_MAX)-1; // generate between -1,1
01057     }
01058   }
01059   ifail = 0;
01060   SMatrix<double,7 > Minv = M.Inverse(ifail);
01061   iret |= compare(ifail,0,"7x7 inversion");
01062   Id = M*Minv; 
01063   for (int i = 0; i < 7; ++i)
01064     iret |= compare(Id(i,i),1.,"inv result");
01065 
01066   sum = 0; 
01067   for (int i = 0; i < 7; ++i) 
01068     for (int j = 0; j <i; ++j)
01069       sum+= std::fabs(Id(i,j) );  // sum of off diagonal elements
01070 
01071   iret |= compare(sum < 1.E-10, true,"inv off diag");
01072   
01073   
01074   return iret; 
01075 }
01076 
01077 // test inversion of large matrices (float)
01078 int test19() { 
01079   int iret =0;
01080   // data for a 7x7 sym matrix to invert
01081   SMatrix<float,7,7,MatRepSym<float,7> > S;
01082   for (int i = 0; i < 7; ++i) {
01083     for (int j = 0; j <= i; ++j) { 
01084       if (i == j) 
01085         S(i,j) = 10*float(std::rand())/(RAND_MAX); // generate between 0,10
01086       else
01087         S(i,j) = 2*float(std::rand())/(RAND_MAX)-1; // generate between -1,1
01088     }
01089   }
01090   int ifail = 0;
01091   SMatrix<float,7,7,MatRepSym<float,7> > Sinv = S.Inverse(ifail);
01092   iret |= compare(ifail,0,"sym7x7 inversion");
01093   SMatrix<float,7> Id = S*Sinv; 
01094 
01095   //std::cout << S << "\n" << Sinv << "\n" << Id << "\n";
01096 
01097   for (int i = 0; i < 7; ++i)
01098     iret |= compare(Id(i,i),float(1.),"inv sym result");
01099 
01100   double sum = 0; 
01101   for (int i = 0; i < 7; ++i) 
01102     for (int j = 0; j <i; ++j)
01103       sum+= std::fabs(Id(i,j) );  // sum of off diagonal elements
01104 
01105   iret |= compare(sum < 1.E-5, true,"inv sym off diag");
01106 
01107   // now test inversion of general 
01108   SMatrix<float,7> M;
01109   for (int i = 0; i < 7; ++i) {
01110     for (int j = 0; j < 7; ++j) { 
01111       if (i == j) 
01112         M(i,j) = 10*float(std::rand())/(RAND_MAX); // generate between 0,10
01113       else
01114         M(i,j) = 2*float(std::rand())/(RAND_MAX)-1; // generate between -1,1
01115     }
01116   }
01117   ifail = 0;
01118   SMatrix<float,7 > Minv = M.Inverse(ifail);
01119   iret |= compare(ifail,0,"7x7 inversion");
01120   Id = M*Minv; 
01121 
01122   //std::cout << M << "\n" << Minv << "\n" << Id << "\n";
01123 
01124   for (int i = 0; i < 7; ++i)
01125     iret |= compare(Id(i,i),float(1.),"inv result");
01126 
01127   sum = 0; 
01128   for (int i = 0; i < 7; ++i) 
01129     for (int j = 0; j <i; ++j)
01130       sum+= std::fabs(Id(i,j) );  // sum of off diagonal elements
01131 
01132   iret |= compare(sum < 1.E-5, true,"inv off diag");
01133   
01134   
01135   return iret; 
01136 }
01137 
01138 
01139 int test20() { 
01140 // test operator += , -= 
01141   int iret =0;
01142   //std::cout.precision(18); 
01143 
01144 
01145   double d1[6]={1,2,3,4,5,6};
01146   double d2[6]={1,2,5,3,4,6};
01147 
01148   SMatrix<double,2>    m1_0(d1,4);
01149   SMatrix<double,2 >   m2_0(d2,4);
01150   SMatrix<double,2>    m1 = m1_0;
01151   SMatrix<double,2 >   m2 = m2_0;
01152   SMatrix<double,2>    m3;
01153  
01154 
01155   m3 = m1+m2; 
01156   m1+= m2; 
01157  
01158   if (iret) std::cout << "m1+= m2" << m1  << std::endl;
01159 
01160   iret |= compare(m1==m3,true); 
01161 
01162   m3 = m1 + 3;
01163   m1+= 3;
01164   iret |= compare(m1==m3,true); 
01165   if (iret)std::cout << "m1 + 3\n" << m1 << " \n  " << m3  << std::endl;
01166 
01167   m3 = m1 - m2; 
01168   m1-= m2; 
01169   iret |= compare(m1==m3,true); 
01170   if (iret) std::cout << "m1-= m2\n" << m1 << " \n  " << m3  << std::endl;
01171   
01172   m3 = m1 - 3; 
01173   m1-= 3; 
01174   iret |= compare(m1==m3,true); 
01175   if (iret) std::cout << "m1-= 3\n" << m1 << " \n " << m3  << std::endl;
01176 
01177 
01178   m3 = m1*2;
01179   m1*= 2; 
01180   iret |= compare(m1==m3,true); 
01181   if (iret) std::cout << "m1*= 2\n" << m1 << "\n" << m3  << std::endl;
01182 
01183   // matrix multiplication (*= works only for squared matrix mult.) 
01184   m3 = m1*m2; 
01185   m1*= m2; 
01186   iret |= compare(m1==m3,true); 
01187   if (iret) std::cout << "m1*= m2\n" << m1 << " \n " << m3  << std::endl;
01188 
01189   m3 = m1/2;
01190   m1/= 2; 
01191   iret |= compare(m1==m3,true); 
01192   if (iret) std::cout << "m1/=2\n" << m1 << " \n " << m3  << std::endl;
01193 
01194   // test mixed with a scalar 
01195   double a = 2; 
01196   m3 = m2 + a*m1; 
01197   m2 += a*m1; 
01198   iret |= compare(m2==m3,true); 
01199   if (iret) std::cout << "m2 += a*m1\n" << m2 << "\n  " << m3  << std::endl;
01200 
01201 
01202   // more complex op (passing expressions)
01203 
01204   m1 = m1_0;
01205   m2 = m2_0;
01206 
01207 
01208   m3 = m1 + (m1 * m2);
01209   m1 += m1 * m2;
01210   iret |= compare(m1==m3,true); 
01211   if (iret) std::cout << "m1 += m1*m2\n" << m1 << "\n  " << m3  << std::endl;
01212 
01213   m3 = m1 - (m1 * m2);
01214   m1 -= m1 * m2;
01215   iret |= compare(m1==m3,true); 
01216   if (iret) std::cout << "m1 -= m1*m2\n" << m1 << " \n " << m3  << std::endl;
01217 
01218   m3 = m1 * (m1 * m2);
01219   m1 *= m1 * m2;
01220   iret |= compare(m1==m3,true); 
01221   if (iret) std::cout << "m1 *= m1*m2\n" << m1 << "\n  " << m3  << std::endl;
01222 
01223   // test operation involving 2 expressions
01224   // (check bug 35076)
01225 
01226   // reset initial matrices to avoid numerical problems
01227   m1 = m1_0;
01228   m2 = m2_0;
01229 
01230   m3 = m1+m2;
01231   SMatrix<double,2>    m4;
01232   SMatrix<double,2>    m5;
01233   m4 = (m1*m2) + (m1*m3);
01234   m5 = m1*m2;
01235   m5 += m1*m3;
01236   iret |= compare(m4==m5,true); 
01237   if (iret) std::cout << "m5 = m1*m3\n" << m4 << "\n  " << m5  << std::endl;
01238 
01239 
01240   m4 = (m1*m2) - (m1*m3);
01241   m5 = m1*m2;
01242   m5 -= m1*m3;
01243   iret |= compare(m4==m5,true); 
01244   if (iret) std::cout << "m5 -= m1*m3\n" << m4 << "\n  " << m5  << std::endl;
01245 
01246 
01247   m4 = (m1+m2) * (m1-m3);
01248   m5 = m1+m2;
01249   m5 = m5 * (m1-m3);
01250   iret |= compare(m4==m5,true); 
01251 
01252   if (iret) std::cout << "m5= m5*(m1-m3) \n"  << m4 << " \n " << m5  << std::endl;
01253 
01254 
01255   // test with vectors 
01256   SVector<double,4>    v1(d1,4);
01257   SVector<double,4 >   v2(d2,4);
01258   SVector<double,4 >   v3;
01259 
01260   v3 = v1+v2;
01261   v1 += v2; 
01262   iret |= compare(v1==v3,true); 
01263 
01264   v3 = v1 + 2; 
01265   v1 += 2;
01266   iret |= compare(v1==v3,true); 
01267 
01268   v3 = v1+ (v1 + v2);
01269   v1 +=  v1 + v2;
01270   iret |= compare(v1==v3,true); 
01271 
01272   v3 = v1 - v2;
01273   v1 -= v2; 
01274   iret |= compare(v1==v3,true); 
01275 
01276   v3 = v1 - 2; 
01277   v1 -= 2;
01278   iret |= compare(v1==v3,true); 
01279 
01280   v3 = v1 - (v1 + v2);
01281   v1 -=  v1 + v2;
01282   iret |= compare(v1==v3,true); 
01283 
01284   v3 = v1 * 2;
01285   v1 *= 2;
01286   iret |= compare(v1==v3,true); 
01287 
01288   v3 = v1 / 2;
01289   v1 /= 2;
01290   iret |= compare(v1==v3,true); 
01291 
01292   // test with symmetric matrices 
01293 
01294   //double d1[6]={1,2,3,4,5,6};
01295   SMatrix<double,3,3,MatRepSym<double,3> >   ms1(d1,d1+6);
01296   SMatrix<double,3,3,MatRepSym<double,3> >   ms2(d1,d1+6,true, false);
01297   SMatrix<double,3,3,MatRepSym<double,3> >   ms3; 
01298   SMatrix<double,3,3,MatRepSym<double,3> >   ms4; 
01299 
01300   // using complex expressions
01301   ms3 = ms1 + (ms1 + ms2);
01302   ms1 += ms1 + ms2;
01303   iret |= compare(ms1==ms3,true); 
01304 
01305   ms3 = ms1 - (ms1 + ms2);
01306   ms1 -= ms1 + ms2;
01307   iret |= compare(ms1==ms3,true); 
01308 
01309 
01310   a = 2; 
01311   ms3 = ms1 + a*ms2; 
01312 
01313   ms4 = ms1; 
01314   ms4 += a*ms2; 
01315 
01316   iret |= compare(ms3==ms4,true); 
01317 
01318   ms3 = ms1 - a*ms2; 
01319   ms4 = ms1; 
01320   ms4 -= a*ms2; 
01321   iret |= compare(ms3==ms4,true); 
01322 
01323   return iret; 
01324 }
01325 
01326 int test21() { 
01327 
01328    // test global matrix function (element-wise operations)
01329 
01330   int iret =0;
01331 
01332   double d1[4]={4,6,3,4};
01333   double d2[4]={2,3,1,4};
01334 
01335   SMatrix<double,2>    m1(d1,4);
01336   SMatrix<double,2 >   m2(d2,4);
01337   SMatrix<double,2>    m3;
01338 
01339   // test element-wise multiplication
01340   m3 = Times(m1,m2);
01341   for (int i = 0; i < 4; ++i)
01342      iret |= compare(m3.apply(i),m1.apply(i)*m2.apply(i)); 
01343 
01344   // matrix division is element-wise division
01345   m3 = Div(m1,m2);
01346   for (int i = 0; i < 4; ++i)
01347      iret |= compare(m3.apply(i),m1.apply(i)/m2.apply(i)); 
01348 
01349 
01350   return iret; 
01351 
01352 }
01353 
01354 
01355 int test22() { 
01356 
01357    // test conversion to scalar for size 1 matrix and vectors 
01358 
01359   int iret =0;
01360   SMatrix<double,1> m1(2); 
01361   iret |= compare(m1(0,0),2.); 
01362 
01363   SVector<double,1> v1;
01364   v1 = 2; 
01365   iret |= compare(m1(0,0),2.); 
01366 
01367   return iret; 
01368 }
01369 
01370 int test23() { 
01371    // test cholesky inversion and solving 
01372    int iret = 0; 
01373 
01374    double m[] = { 100, .15, 2.3, 0.01, .01,  1.}; 
01375    SMatrix<double, 3, 3, MatRepSym<double, 3> >  smat(m, m+6); 
01376 
01377    //std::cout << "Perform inversion  of matrix \n" << smat << std::endl; 
01378 
01379    int ifail = 0; 
01380    SMatrix<double, 3, 3, MatRepSym<double, 3> > imat = smat.InverseChol(ifail); 
01381    iret |= compare(ifail==0, true, "inversion");
01382 
01383    // test max deviations from identity for m = imat * smat
01384 
01385    SMatrix<double, 3> mid = imat * smat; 
01386    int n = 3; 
01387    double prod = 1; 
01388    double vmax = 0; 
01389    for (int i = 0; i < n; ++i) { 
01390       for (int j = 0; j < n; ++j) { 
01391          if (i == j) 
01392             prod *= mid(i,i); 
01393          else { 
01394             if (std::abs (mid(i,j)) > vmax ) vmax = std::abs( mid(i,j) ); 
01395          }
01396       }
01397    } 
01398    iret |= compare(prod, 1., "max dev diagonal");
01399    iret |= compare(vmax, 0., "max dev offdiag ",10);
01400 
01401    // test now solving of linear system
01402    SVector<double, 3> vec(1,2,3); 
01403 
01404    SVector<double, 3> x = SolveChol( smat, vec, ifail); 
01405 
01406    //std::cout << "linear system solution " << x << std::endl;
01407 
01408    iret |= compare( (ifail==0), true, "solve chol"); 
01409 
01410    SVector<double, 3> v2 = smat * x;  
01411 
01412    for (int i = 0; i < 3; ++i) 
01413       iret |= compare(v2[i], vec[i], "v2 ==vec"); 
01414    
01415    return iret; 
01416 
01417 }
01418 
01419 int test24() { 
01420    // add transpose test
01421    // see bug #65531
01422    double a[9] = { 1,-2,3,4,-5,6,-7,8,9};
01423    double b[9] = { 1,-1,0,0,2,0,-1,0,3};
01424 
01425    SMatrix<double,3> A(a,a+9); 
01426    SMatrix<double,3> B(b,b+9); 
01427 
01428    SMatrix<double,3> R = A * B * Transpose(A);
01429 
01430    SMatrix<double,3> temp1 = A * B; 
01431    SMatrix<double,3> R1 = temp1 * Transpose(A);
01432 
01433    SMatrix<double,3> temp2 = B * Transpose(A); 
01434    SMatrix<double,3> R2 = A * temp2;
01435 
01436    int iret = 0; 
01437    iret |= compare(R1 == R2, true);
01438    iret |= compare(R == R1,true);
01439    return iret; 
01440 
01441 }
01442 
01443 #define TEST(N)                                                                 \
01444   itest = N;                                                                    \
01445   if (test##N() == 0) std::cerr << " Test " << itest << "  OK " << std::endl; \
01446   else { std::cerr << " Test " << itest << "  FAILED " << std::endl;    \
01447      iret +=1; };
01448 
01449 
01450 
01451 
01452 int testSMatrix() {
01453 
01454   int iret = 0; 
01455   int itest;
01456   TEST(1);
01457   TEST(2);
01458   TEST(3);
01459   TEST(4);
01460   TEST(5);
01461   TEST(6);
01462   TEST(7);
01463   TEST(8);
01464   TEST(9);
01465   TEST(10);
01466   TEST(11);
01467   TEST(12);
01468   TEST(13);
01469   TEST(14);
01470   TEST(15);
01471   TEST(16);
01472   TEST(17);
01473   TEST(18);
01474   TEST(19);
01475   TEST(20);
01476   TEST(21);
01477   TEST(22);
01478   TEST(23);
01479   TEST(24);
01480 
01481   return iret;
01482 }
01483 
01484 int main() { 
01485    int ret = testSMatrix();
01486    if (ret)  std::cerr << "test SMatrix:\t  FAILED !!! " << std::endl; 
01487    else   std::cerr << "test SMatrix: \t OK " << std::endl;
01488    return ret; 
01489 }

Generated on Tue Jul 5 14:43:22 2011 for ROOT_528-00b_version by  doxygen 1.5.1