vvector.cxx

Go to the documentation of this file.
00001 // @(#)root/test:$Id: vvector.cxx 36320 2010-10-12 19:00:12Z brun $
00002 // Author: Fons Rademakers and Eddy Offermann  Nov 2003
00003 
00004 //////////////////////////////////////////////////////////////////////////
00005 //                                                                      //
00006 // Linear Algebra Package -- Vector Verifications.                      //
00007 //                                                                      //
00008 // This file implements a large set of TVectorD operation tests.        //
00009 // *******************************************************************  //
00010 // *  Starting  Vector - S T R E S S suite                              //
00011 // *******************************************************************  //
00012 // Test  1 : Allocation, Filling, Resizing......................... OK  //
00013 // Test  2 : Uniform vector operations............................. OK  //
00014 // Test  3 : Binary vector element-by-element operations............OK  //
00015 // Test  4 : Vector Norms...........................................OK  //
00016 // Test  5 : Matrix Slices to Vectors...............................OK  //
00017 // Test  6 : Vector Persistence.....................................OK  //
00018 // *******************************************************************  //
00019 //                                                                      //
00020 //////////////////////////////////////////////////////////////////////////
00021 
00022 //_____________________________batch only_____________________
00023 #ifndef __CINT__
00024 
00025 #include "TROOT.h"
00026 #include "TFile.h"
00027 #include "Riostream.h"
00028 #include "TVectorD.h"
00029 #include "TMath.h"
00030 
00031 void stress_vector       (Int_t verbose);
00032 void stress_allocation   ();
00033 void stress_element_op   (Int_t vsize);
00034 void stress_binary_op    (Int_t vsize);
00035 void stress_norms        (Int_t vsize);
00036 void stress_matrix_slices(Int_t vsize);
00037 void stress_vector_io    ();
00038 
00039 int main(int argc,char **argv)
00040 {
00041   Int_t verbose = 0;
00042   Char_t c;
00043   while (argc > 1 && argv[1][0] == '-' && argv[1][1] != 0) {
00044     for (Int_t i = 1; (c = argv[1][i]) != 0; i++) {
00045       switch (c) {
00046         case 'v':
00047           verbose = 1;
00048           break;
00049         default:
00050           Error("vvector", "unknown flag -%c",c);
00051           break;
00052       }
00053     }
00054     argc--;
00055     argv++;
00056   }
00057   stress_vector(verbose);
00058   return 0;
00059 }
00060 
00061 #endif
00062 
00063 #define EPSILON 1.0e-14
00064 
00065 Int_t gVerbose = 0;
00066 
00067 //________________________________common part_________________________
00068 
00069 void stress_vector(Int_t verbose=0)
00070 {
00071   cout << "******************************************************************" <<endl;
00072   cout << "*  Starting  Vector - S T R E S S suite                          *" <<endl;
00073   cout << "******************************************************************" <<endl;
00074 
00075   gVerbose = verbose;
00076   stress_allocation();
00077   stress_element_op(20);
00078   stress_binary_op(20);
00079   stress_norms(20);
00080   stress_matrix_slices(20);
00081   stress_vector_io();
00082 
00083   cout << "******************************************************************" <<endl;
00084 }
00085 
00086 void StatusPrint(Int_t id,const Char_t *title,Bool_t status)
00087 {
00088   // Print test program number and its title
00089 //   const Int_t kMAX = 65;
00090 //   TString header = TString("Test ")+Form("%2d",id)+" : "+title;
00091 //   const Int_t nch = header.Length();
00092 //   for (Int_t i = nch; i < kMAX; i++) header += '.';
00093 //   cout << header << (status ? "OK" : "FAILED") << endl;
00094   // Print test program number and its title
00095    const Int_t kMAX = 65;
00096    char header[80];
00097    sprintf(header,"Test %2d : %s",id,title);
00098    Int_t nch = strlen(header);
00099    for (Int_t i=nch;i<kMAX;i++) header[i] = '.';
00100    header[kMAX] = 0;
00101    header[kMAX-1] = ' ';
00102    cout << header << (status ? "OK" : "FAILED") << endl;
00103 }
00104 
00105 //------------------------------------------------------------------------
00106 //          Test allocation functions and compatibility check
00107 //
00108 
00109 void stress_allocation()
00110 {
00111   if (gVerbose)
00112     cout << "\n\n---> Test allocation and compatibility check" << endl;
00113 
00114   Bool_t ok = kTRUE;
00115   TVectorD v1(20);
00116   TVectorD v2(0,19);
00117   TVectorD v3(1,20);
00118   TVectorD v4(v1);
00119 
00120   if (gVerbose) {
00121     cout << "\nStatus information reported for vector v3:" << endl;
00122     cout << "  Lower bound ... " << v3.GetLwb() << endl;
00123     cout << "  Upper bound ... " << v3.GetUpb() << endl;
00124     cout << "  No. of elements " << v3.GetNoElements() << endl;
00125   }
00126 
00127   if (gVerbose)
00128     cout << "\nCheck vectors 1 & 2 for compatibility" << endl;
00129   ok &= AreCompatible(v1,v2,gVerbose);
00130 
00131   if (gVerbose)
00132     cout << "Check vectors 1 & 4 for compatibility" << endl;
00133   ok &= AreCompatible(v1,v4,gVerbose);
00134 
00135   if (gVerbose)
00136     cout << "v2 has to be compatible with v3 after resizing to v3" << endl;
00137   v2.ResizeTo(v3);
00138   ok &= AreCompatible(v2,v3,gVerbose);
00139 
00140   TVectorD v5(v1.GetUpb()+5);
00141   if (gVerbose)
00142     cout << "v1 has to be compatible with v5 after resizing to v5.upb" << endl;
00143   v1.ResizeTo(v5.GetNoElements());
00144   ok &= AreCompatible(v1,v5,gVerbose);
00145 
00146   {
00147     if (gVerbose)
00148       cout << "Check that shrinking does not change remaining elements" << endl;
00149     TVectorD vb(-1,20);
00150     Int_t i;
00151     for (i = vb.GetLwb(); i <= vb.GetUpb(); i++)
00152       vb(i) = i+TMath::Pi();
00153     TVectorD v = vb;
00154     ok &= ( v == vb ) ? kTRUE : kFALSE;
00155     ok &= ( v != 0 ) ? kTRUE : kFALSE;
00156     v.ResizeTo(0,10);
00157     for (i = v.GetLwb(); i <= v.GetUpb(); i++)
00158       ok &= ( v(i) == vb(i) ) ? kTRUE : kFALSE;
00159     if (gVerbose)
00160       cout << "Check that expansion expands by zeros" << endl;
00161     const Int_t old_nelems = v.GetNoElements();
00162     const Int_t old_lwb    = v.GetLwb();
00163     v.ResizeTo(vb);
00164     ok &= ( !(v == vb) ) ? kTRUE : kFALSE;
00165     for (i = old_lwb; i < old_lwb+old_nelems; i++)
00166       ok &= ( v(i) == vb(i) ) ? kTRUE : kFALSE;
00167     for (i = v.GetLwb(); i < old_lwb; i++)
00168       ok &= ( v(i) == 0 ) ? kTRUE : kFALSE;
00169     for (i = old_lwb+old_nelems; i <= v.GetUpb(); i++)
00170       ok &= ( v(i) == 0 ) ? kTRUE : kFALSE;
00171   }
00172 
00173   if (gVerbose)
00174     cout << "\nDone\n" << endl;
00175   StatusPrint(1,"Allocation, Filling, Resizing",ok);
00176 }
00177 
00178 //
00179 //------------------------------------------------------------------------
00180 //                Test uniform element operations
00181 //
00182 class SinAction : public TElementActionD {
00183   void Operation(Double_t &element) const { element = TMath::Sin(element); }
00184   public:
00185     SinAction() { }
00186 };
00187 
00188 class CosAction : public TElementPosActionD {
00189   Double_t factor;
00190   void Operation(Double_t &element) const { element = TMath::Cos(factor*fI); }
00191   public:
00192     CosAction() { }
00193     CosAction(Int_t no_elems): factor(2*TMath::Pi()/no_elems) { }
00194 };
00195 
00196 void stress_element_op(Int_t vsize)
00197 {
00198   if (gVerbose)
00199     cout << "\n---> Test operations that treat each element uniformly" << endl;
00200 
00201   Bool_t ok = kTRUE;
00202   const double pattern = TMath::Pi();
00203 
00204   TVectorD v(-1,vsize-2);
00205   TVectorD v1(v);
00206 
00207   if (gVerbose)
00208     cout << "\nWriting zeros to v..." << endl;
00209   for (Int_t i = v.GetLwb(); i <= v.GetUpb(); i++)
00210     v(i) = 0;
00211   ok &= VerifyVectorValue(v,0.0,gVerbose,EPSILON);
00212 
00213   if (gVerbose)
00214     cout << "Clearing v1 ..." << endl;
00215   v1.Zero();
00216   ok &= VerifyVectorValue(v1,0.0,gVerbose,EPSILON);
00217 
00218   if (gVerbose)
00219     cout << "Comparing v1 with 0 ..." << endl;
00220   ok &= (v1 == 0) ? kTRUE : kFALSE;
00221 
00222   if (gVerbose)
00223     cout << "Writing a pattern " << pattern << " by assigning to v(i)..." << endl;
00224   {
00225     for (Int_t i = v.GetLwb(); i <= v.GetUpb(); i++)
00226       v(i) = pattern;
00227     ok &= VerifyVectorValue(v,pattern,gVerbose,EPSILON);
00228   }
00229 
00230   if (gVerbose)
00231     cout << "Writing the pattern by assigning to v1 as a whole ..." << endl;
00232   v1 = pattern;
00233   ok &= VerifyVectorValue(v1,pattern,gVerbose,EPSILON);
00234 
00235   if (gVerbose)
00236     cout << "Comparing v and v1 ..." << endl;
00237   ok &= (v == v1) ? kTRUE : kFALSE;
00238   if (gVerbose)
00239     cout << "Comparing (v=0) and v1 ..." << endl;
00240   ok &= (!(v.Zero() == v1)) ? kTRUE : kFALSE;
00241 
00242   if (gVerbose)
00243     cout << "\nClear v and add the pattern" << endl;
00244   v.Zero();
00245   v += pattern;
00246   ok &= VerifyVectorValue(v,pattern,gVerbose,EPSILON);
00247   if (gVerbose)
00248     cout << "   add the doubled pattern with the negative sign" << endl;
00249   v += -2*pattern;
00250   ok &= VerifyVectorValue(v,-pattern,gVerbose,EPSILON);
00251   if (gVerbose)
00252     cout << "   subtract the trippled pattern with the negative sign" << endl;
00253   v -= -3*pattern;
00254   ok &= VerifyVectorValue(v,2*pattern,gVerbose,EPSILON);
00255 
00256   if (gVerbose)
00257     cout << "\nVerify comparison operations" << endl;
00258   v = pattern;
00259   ok &= ( v == pattern && !(v != pattern) && v >= pattern && v <= pattern ) ? kTRUE : kFALSE;
00260   ok &= ( v > 0 && v >= 0 ) ? kTRUE : kFALSE;
00261   ok &= ( v > -pattern && v >= -pattern ) ? kTRUE : kFALSE;
00262   ok &= ( v < pattern+1 && v <= pattern+1 ) ? kTRUE : kFALSE;
00263   v(v.GetUpb()) += 1;
00264   ok &= ( !(v==pattern)      && !(v != pattern)  && v != pattern-1 ) ? kTRUE : kFALSE;
00265   ok &= ( v >= pattern       && !(v > pattern)   && !(v >= pattern+1) ) ? kTRUE : kFALSE;
00266   ok &= ( v <= pattern+1.001 && !(v < pattern+1) && !(v <= pattern) ) ? kTRUE : kFALSE;
00267 
00268   if (gVerbose)
00269     cout << "\nAssign 2*pattern to v by repeating additions" << endl;
00270   v = 0; v += pattern; v += pattern;
00271   if (gVerbose)
00272     cout << "Assign 2*pattern to v1 by multiplying by two" << endl;
00273   v1 = pattern; v1 *= 2;
00274   ok &= VerifyVectorValue(v1,2*pattern,gVerbose,EPSILON);
00275   ok &= ( v == v1 ) ? kTRUE : kFALSE;
00276   if (gVerbose)
00277     cout << "Multiply v1 by one half returning it to the 1*pattern" << endl;
00278   v1 *= 1/2.;
00279   ok &= VerifyVectorValue(v1,pattern,gVerbose,EPSILON);
00280 
00281   if (gVerbose)
00282     cout << "\nAssign -pattern to v and v1" << endl;
00283   v.Zero(); v -= pattern; v1 = -pattern;
00284   ok &= VerifyVectorValue(v,-pattern,gVerbose,EPSILON);
00285   ok &= ( v == v1 ) ? kTRUE : kFALSE;
00286   if (gVerbose)
00287     cout << "v = sqrt(sqr(v)); v1 = abs(v1); Now v and v1 have to be the same" << endl;
00288   v.Sqr();
00289   ok &= VerifyVectorValue(v,pattern*pattern,gVerbose,EPSILON);
00290   v.Sqrt();
00291   ok &= VerifyVectorValue(v,pattern,gVerbose,EPSILON);
00292   v1.Abs();
00293   ok &= VerifyVectorValue(v1,pattern,gVerbose,EPSILON);
00294   ok &= ( v == v1 ) ? kTRUE : kFALSE;
00295 
00296   {
00297     if (gVerbose)
00298       cout << "\nCheck out to see that sin^2(x) + cos^2(x) = 1" << endl;
00299     for (Int_t i = v.GetLwb(); i <= v.GetUpb(); i++)
00300       v(i) = 2*TMath::Pi()/v.GetNoElements()*i;
00301 #ifndef __CINT__
00302     SinAction s;
00303     v.Apply(s);
00304     CosAction c(v.GetNoElements());
00305     v1.Apply(c);
00306 #else
00307     for (Int_t i = v.GetLwb(); i <= v.GetUpb(); i++) {
00308       v(i)  = TMath::Sin(v(i));
00309       v1(i) = TMath::Cos(2*TMath::Pi()/v1.GetNrows()*i);
00310     }
00311 #endif
00312     TVectorD v2 = v;
00313     TVectorD v3 = v1;
00314     v.Sqr();
00315     v1.Sqr();
00316     v += v1;
00317     ok &= VerifyVectorValue(v,1.,gVerbose,EPSILON);
00318   }
00319 
00320   if (gVerbose)
00321     cout << "\nVerify constructor with initialization" << endl;
00322 #ifndef __CINT__
00323   TVectorD vi(0,4,0.0,1.0,2.0,3.0,4.0,"END");
00324 #else
00325   Double_t vval[] = {0.0,1.0,2.0,3.0,4.0};
00326   TVectorD vi(5,vval);
00327 #endif
00328   TVectorD vit(5);
00329   {
00330     for (Int_t i = vit.GetLwb(); i <= vit.GetUpb(); i++)
00331       vit(i) = Double_t(i);
00332     ok &= VerifyVectorIdentity(vi,vit,gVerbose,EPSILON);
00333   }
00334 
00335   if (gVerbose)
00336     cout << "\nDone\n" << endl;
00337   StatusPrint(2,"Uniform vector operations",ok);
00338 }
00339 
00340 //
00341 //------------------------------------------------------------------------
00342 //                 Test binary vector operations
00343 //
00344 void stress_binary_op(Int_t vsize)
00345 {
00346   if (gVerbose)
00347     cout << "\n---> Test Binary Vector operations" << endl;
00348 
00349   Bool_t ok = kTRUE;
00350   const double pattern = TMath::Pi();
00351 
00352   const Double_t epsilon = EPSILON*vsize/10;
00353 
00354   TVectorD v(2,vsize+1);
00355   TVectorD v1(v);
00356 
00357   if (gVerbose)
00358     cout << "\nVerify assignment of a vector to the vector" << endl;
00359   v = pattern;
00360   v1.Zero();
00361   v1 = v;
00362   ok &= VerifyVectorValue(v1,pattern,gVerbose,EPSILON);
00363   ok &= ( v1 == v ) ? kTRUE : kFALSE;
00364 
00365   if (gVerbose)
00366     cout << "\nAdding one vector to itself, uniform pattern " << pattern << endl;
00367   v.Zero(); v = pattern;
00368   v1 = v; v1 += v1;
00369   ok &= VerifyVectorValue(v1,2*pattern,gVerbose,EPSILON);
00370   if (gVerbose)
00371     cout << "  subtracting two vectors ..." << endl;
00372   v1 -= v;
00373   ok &= VerifyVectorValue(v1,pattern,gVerbose,EPSILON);
00374   if (gVerbose)
00375     cout << "  subtracting the vector from itself" << endl;
00376   v1 -= v1;
00377   ok &= VerifyVectorValue(v1,0.,gVerbose,EPSILON);
00378   if (gVerbose)
00379     cout << "  adding two vectors together" << endl;
00380   v1 += v;
00381   ok &= VerifyVectorValue(v1,pattern,gVerbose,EPSILON);
00382 
00383   TVectorD vp(2,vsize+1);
00384   {
00385     for (Int_t i = vp.GetLwb(); i <= vp.GetUpb(); i++)
00386       vp(i) = (i-vp.GetNoElements()/2.)*pattern;
00387   }
00388 
00389   if (gVerbose) {
00390     cout << "\nArithmetic operations on vectors with not the same elements" << endl;
00391     cout << "   adding vp to the zero vector..." << endl;
00392   }
00393   v.Zero();
00394   ok &= ( v == 0.0 ) ? kTRUE : kFALSE;
00395   v += vp;
00396   ok &= VerifyVectorIdentity(v,vp,gVerbose,epsilon);
00397 //  ok &= ( v == vp ) ? kTRUE : kFALSE;
00398   v1 = v;
00399   if (gVerbose)
00400     cout << "   making v = 3*vp and v1 = 3*vp, via add() and succesive mult" << endl;
00401   Add(v,2.,vp);
00402   v1 += v1; v1 += vp;
00403   ok &= VerifyVectorIdentity(v,v1,gVerbose,epsilon);
00404   if (gVerbose)
00405     cout << "   clear both v and v1, by subtracting from itself and via add()" << endl;
00406   v1 -= v1;
00407   Add(v,-3.,vp);
00408   ok &= VerifyVectorIdentity(v,v1,gVerbose,epsilon);
00409 
00410   if (gVerbose) {
00411     cout << "\nTesting element-by-element multiplications and divisions" << endl;
00412     cout << "   squaring each element with sqr() and via multiplication" << endl;
00413   }
00414   v = vp; v1 = vp;
00415   v.Sqr();
00416   ElementMult(v1,v1);
00417   ok &= VerifyVectorIdentity(v,v1,gVerbose,epsilon);
00418   if (gVerbose)
00419     cout << "   compare (v = pattern^2)/pattern with pattern" << endl;
00420   v = pattern; v1 = pattern;
00421   v.Sqr();
00422   ElementDiv(v,v1);
00423   ok &= VerifyVectorValue(v,pattern,gVerbose,epsilon);
00424   if (gVerbose)
00425    Compare(v1,v);
00426 
00427   if (gVerbose)
00428     cout << "\nDone\n" << endl;
00429   StatusPrint(3,"Binary vector element-by-element operations",ok);
00430 }
00431 
00432 //
00433 //------------------------------------------------------------------------
00434 //               Verify the norm calculation
00435 //
00436 void stress_norms(Int_t vsize)
00437 {
00438   if (gVerbose)
00439     cout << "\n---> Verify norm calculations" << endl;
00440 
00441   Bool_t ok = kTRUE;
00442   const double pattern = 10.25;
00443 
00444   if ( vsize % 2 == 1 )
00445     Fatal("stress_norms", "size of the vector to test must be even for this test\n");
00446 
00447   TVectorD v(vsize);
00448   TVectorD v1(v);
00449 
00450   if (gVerbose)
00451     cout << "\nAssign " << pattern << " to all the elements and check norms" << endl;
00452   v = pattern;
00453   if (gVerbose)
00454     cout << "  1. norm should be pattern*no_elems" << endl;
00455   ok &= ( v.Norm1() == pattern*v.GetNoElements() ) ? kTRUE : kFALSE;
00456   if (gVerbose)
00457     cout << "  Square of the 2. norm has got to be pattern^2 * no_elems" << endl;
00458   ok &= ( v.Norm2Sqr() == (pattern*pattern)*v.GetNoElements() ) ? kTRUE : kFALSE;
00459   if (gVerbose)
00460     cout << "  Inf norm should be pattern itself" << endl;
00461   ok &= ( v.NormInf() == pattern ) ? kTRUE : kFALSE;
00462   if (gVerbose)
00463     cout << "  Scalar product of vector by itself is the sqr(2. vector norm)" << endl;
00464   ok &= ( v.Norm2Sqr() == v*v ) ? kTRUE : kFALSE;
00465 
00466   Double_t ap_step = 1;
00467   Double_t ap_a0   = -pattern;
00468   Int_t n = v.GetNoElements();
00469   if (gVerbose) {
00470     cout << "\nAssign the arithm progression with 1. term " << ap_a0 <<
00471             "\nand the difference " << ap_step << endl;
00472   }
00473   {
00474     for (Int_t i = v.GetLwb(); i <= v.GetUpb(); i++)
00475       v(i) = (i-v.GetLwb())*ap_step + ap_a0;
00476   }
00477   Int_t l = TMath::Min(TMath::Max((int)TMath::Ceil(-ap_a0/ap_step),0),n);
00478   Double_t norm = (2*ap_a0+(l+n-1)*ap_step)/2*(n-l) +
00479                   (-2*ap_a0-(l-1)*ap_step)/2*l;
00480   if (gVerbose)
00481     cout << "  1. norm should be " << norm << endl;
00482   ok &= ( v.Norm1() == norm ) ? kTRUE : kFALSE;
00483   norm = n*( (ap_a0*ap_a0)+ap_a0*ap_step*(n-1)+(ap_step*ap_step)*(n-1)*(2*n-1)/6);
00484   if (gVerbose) {
00485     cout << "  Square of the 2. norm has got to be "
00486             "n*[ a0^2 + a0*q*(n-1) + q^2/6*(n-1)*(2n-1) ], or " << norm << endl;
00487   }
00488   ok &= ( TMath::Abs( (v.Norm2Sqr()-norm)/norm ) < 1e-15 ) ? kTRUE : kFALSE;
00489 
00490   norm = TMath::Max(TMath::Abs(v(v.GetLwb())),TMath::Abs(v(v.GetUpb())));
00491   if (gVerbose)
00492     cout << "  Inf norm should be max(abs(a0),abs(a0+(n-1)*q)), ie " << norm << endl;
00493   ok &= ( v.NormInf() == norm ) ? kTRUE : kFALSE;
00494   if (gVerbose)
00495     cout << "  Scalar product of vector by itself is the sqr(2. vector norm)" << endl;
00496   ok &= ( v.Norm2Sqr() == v*v ) ? kTRUE : kFALSE;
00497 
00498 #if 0
00499   v1.Zero();
00500   Compare(v,v1);  // they are not equal (of course)
00501 #endif
00502 
00503   if (gVerbose)
00504     cout << "\nConstruct v1 to be orthogonal to v as v(n), -v(n-1), v(n-2)..." << endl;
00505   {
00506     for (Int_t i = 0; i < v1.GetNoElements(); i++)
00507       v1(i+v1.GetLwb()) = v(v.GetUpb()-i) * ( i % 2 == 1 ? -1 : 1 );
00508   }
00509   if (gVerbose)
00510     cout << "||v1|| has got to be equal ||v|| regardless of the norm def" << endl;
00511   ok &= ( v1.Norm1()    == v.Norm1() ) ? kTRUE : kFALSE;
00512   ok &= ( v1.Norm2Sqr() == v.Norm2Sqr() ) ? kTRUE : kFALSE;
00513   ok &= ( v1.NormInf()  == v.NormInf() ) ? kTRUE : kFALSE;
00514   if (gVerbose)
00515     cout << "But the scalar product has to be zero" << endl;
00516   ok &= ( v1 * v == 0 ) ? kTRUE : kFALSE;
00517 
00518   if (gVerbose)
00519     cout << "\nDone\n" << endl;
00520   StatusPrint(4,"Vector Norms",ok);
00521 }
00522 
00523 //
00524 //------------------------------------------------------------------------
00525 //           Test operations with vectors and matrix slices
00526 //
00527 void stress_matrix_slices(Int_t vsize)
00528 {
00529   if (gVerbose)
00530     cout << "\n---> Test operations with vectors and matrix slices" << endl;
00531 
00532   Bool_t ok = kTRUE;
00533   const Double_t pattern = 8.625;
00534 
00535   TVectorD vc(0,vsize);
00536   TVectorD vr(0,vsize+1);
00537   TMatrixD m(0,vsize,0,vsize+1);
00538 
00539   Int_t i,j;
00540   if (gVerbose)
00541     cout << "\nCheck modifying the matrix column-by-column" << endl;
00542   m = pattern;
00543   ok &= ( m == pattern ) ? kTRUE : kFALSE;
00544   for (i = m.GetColLwb(); i <= m.GetColUpb(); i++) {
00545     TMatrixDColumn(m,i) = pattern-1;
00546     ok &= ( !( m == pattern ) && !( m != pattern ) ) ? kTRUE : kFALSE;
00547     TMatrixDColumn(m,i) *= 2;
00548     vc = TMatrixDColumn(m,i);
00549     ok &= VerifyVectorValue(vc,2*(pattern-1),gVerbose);
00550     vc = TMatrixDColumn(m,i+1 > m.GetColUpb() ? m.GetColLwb() : i+1);
00551     ok &= VerifyVectorValue(vc,pattern,gVerbose,EPSILON);
00552     TMatrixDColumn(m,i) *= 0.5;
00553     TMatrixDColumn(m,i) += 1;
00554     ok &= ( m == pattern ) ? kTRUE : kFALSE;
00555   }
00556 
00557   ok &= ( m == pattern ) ? kTRUE : kFALSE;
00558   for (i = m.GetColLwb(); i <= m.GetColUpb(); i++) {
00559     vc = pattern+1;
00560     TMatrixDColumn(m,i) = vc;
00561     ok &= ( !( m == pattern ) && !( m != pattern ) ) ? kTRUE : kFALSE;
00562     {
00563       TMatrixDColumn mc(m,i);
00564       for (j = m.GetRowLwb(); j <= m.GetRowUpb(); j++)
00565         mc(j) *= 4;
00566     }
00567     vc = TMatrixDColumn(m,i);
00568     ok &= VerifyVectorValue(vc,4*(pattern+1),gVerbose,EPSILON);
00569     TMatrixDColumn(m,i) *= 0.25;
00570     TMatrixDColumn(m,i) += -1;
00571     vc = TMatrixDColumn(m,i);
00572     ok &= VerifyVectorValue(vc,pattern,gVerbose,EPSILON);
00573     ok &= ( m == pattern ) ? kTRUE : kFALSE;
00574   }
00575 
00576   if (gVerbose)
00577     cout << "\nCheck modifying the matrix row-by-row" << endl;
00578   m = pattern;
00579   ok &= ( m == pattern ) ? kTRUE : kFALSE;
00580   for (i = m.GetRowLwb(); i <= m.GetRowUpb(); i++) {
00581     TMatrixDRow(m,i) = pattern+2;
00582     ok &= ( !( m == pattern ) && !( m != pattern ) ) ? kTRUE : kFALSE;
00583     vr = TMatrixDRow(m,i);
00584     ok &= VerifyVectorValue(vr,pattern+2,gVerbose,EPSILON);
00585     vr = TMatrixDRow(m,i+1 > m.GetRowUpb() ? m.GetRowLwb() : i+1);
00586     ok &= VerifyVectorValue(vr,pattern,gVerbose,EPSILON);
00587     TMatrixDRow(m,i) += -2;
00588     ok &= ( m == pattern ) ? kTRUE : kFALSE;
00589   }
00590 
00591   ok &= ( m == pattern ) ? kTRUE : kFALSE;
00592   for (i = m.GetRowLwb(); i <= m.GetRowUpb(); i++) {
00593     vr = pattern-2;
00594     TMatrixDRow(m,i) = vr;
00595     ok &= ( !( m == pattern ) && !( m != pattern ) ) ? kTRUE : kFALSE;
00596     {
00597       TMatrixDRow mr(m,i);
00598       for (j = m.GetColLwb(); j <= m.GetColUpb(); j++)
00599         mr(j) *= 8;
00600     }
00601     vr = TMatrixDRow(m,i);
00602     ok &= VerifyVectorValue(vr,8*(pattern-2),gVerbose,EPSILON);
00603     TMatrixDRow(m,i) *= 1./8;
00604     TMatrixDRow(m,i) += 2;
00605     vr = TMatrixDRow(m,i);
00606     ok &= VerifyVectorValue(vr,pattern,gVerbose,EPSILON);
00607     ok &= ( m == pattern ) ? kTRUE : kFALSE;
00608   }
00609 
00610   if (gVerbose)
00611     cout << "\nCheck modifying the matrix diagonal" << endl;
00612   m = pattern;
00613   TMatrixDDiag td = m;
00614   td = pattern-3;
00615   ok &= ( !( m == pattern ) && !( m != pattern ) ) ? kTRUE : kFALSE;
00616   vc = TMatrixDDiag(m);
00617   ok &= VerifyVectorValue(vc,pattern-3,gVerbose,EPSILON);
00618   td += 3;
00619   ok &= ( m == pattern ) ? kTRUE : kFALSE;
00620   vc = pattern+3;
00621   td = vc;
00622   ok &= ( !( m == pattern ) && !( m != pattern ) ) ? kTRUE : kFALSE;
00623   {
00624     TMatrixDDiag md(m);
00625     for (j = 0; j < md.GetNdiags(); j++)
00626       md(j) /= 1.5;
00627   }
00628   vc = TMatrixDDiag(m);
00629   ok &= VerifyVectorValue(vc,(pattern+3)/1.5,gVerbose,EPSILON);
00630   TMatrixDDiag(m) *= 1.5;
00631   TMatrixDDiag(m) += -3;
00632   vc = TMatrixDDiag(m);
00633   ok &= VerifyVectorValue(vc,pattern,gVerbose,EPSILON);
00634   ok &= ( m == pattern ) ? kTRUE : kFALSE;
00635 
00636   if (gVerbose) {
00637     cout << "\nCheck out to see that multiplying by diagonal is column-wise"
00638             "\nmatrix multiplication" << endl;
00639   }
00640   TMatrixD mm(m);
00641   TMatrixD m1(m.GetRowLwb(),TMath::Max(m.GetRowUpb(),m.GetColUpb()),
00642               m.GetColLwb(),TMath::Max(m.GetRowUpb(),m.GetColUpb()));
00643   TVectorD vc1(vc),vc2(vc);
00644   for (i = m.GetRowLwb(); i < m.GetRowUpb(); i++)
00645     TMatrixDRow(m,i) = pattern+i;      // Make a multiplicand
00646   mm = m;                          // Save it
00647 
00648   m1 = pattern+10;
00649   for (i = vr.GetLwb(); i <= vr.GetUpb(); i++)
00650     vr(i) = i+2;
00651   TMatrixDDiag td2 = m1;
00652   td2 = vr;
00653   ok &= ( !(m1 == pattern+10) ) ? kTRUE : kFALSE;
00654 
00655   m *= TMatrixDDiag(m1);
00656   for (i = m.GetColLwb(); i <= m.GetColUpb(); i++) {
00657     vc1 = TMatrixDColumn(mm,i);
00658     vc1 *= vr(i);                    // Do a column-wise multiplication
00659     vc2 = TMatrixDColumn(m,i);
00660     ok &= VerifyVectorIdentity(vc1,vc2,gVerbose,EPSILON);
00661   }
00662 
00663   if (gVerbose)
00664     cout << "\nDone\n" << endl;
00665   StatusPrint(5,"Matrix Slices to Vectors",ok);
00666 }
00667 
00668 //
00669 //------------------------------------------------------------------------
00670 //           Test vector I/O
00671 //
00672 void stress_vector_io()
00673 {
00674   if (gVerbose)
00675     cout << "\n---> Test vector I/O" << endl;
00676 
00677   Bool_t ok = kTRUE;
00678   const double pattern = TMath::Pi();
00679 
00680   TVectorD v(40);
00681   v = pattern;
00682 
00683   if (gVerbose)
00684     cout << "\nWrite vector v to database" << endl;
00685 
00686   TFile *f = new TFile("vvector.root","RECREATE");
00687 
00688   v.Write("v");
00689 
00690   if (gVerbose)
00691     cout << "\nClose database" << endl;
00692   delete f;
00693 
00694   if (gVerbose)
00695     cout << "\nOpen database in read-only mode and read vector" << endl;
00696   TFile *f1 = new TFile("vvector.root");
00697 
00698   TVectorD *vr = (TVectorD*) f1->Get("v");
00699 
00700   if (gVerbose)
00701     cout << "\nRead vector should be same as original still in memory" << endl;
00702   ok &= ((*vr) == v) ? kTRUE : kFALSE;
00703 
00704   delete f1;
00705 
00706   if (gVerbose)
00707     cout << "\nDone\n" << endl;
00708   StatusPrint(6,"Vector Persistence",ok);
00709 }

Generated on Tue Jul 5 15:16:36 2011 for ROOT_528-00b_version by  doxygen 1.5.1