kDTreeTest.cxx

Go to the documentation of this file.
00001 /*
00002   Test macro for TKDTree
00003 
00004   TestBuild();       // test build function of kdTree for memory leaks
00005   TestSpeed();       // test the CPU consumption to build kdTree
00006   TestkdtreeIF();    // test functionality of the kdTree
00007   TestSizeIF();      // test the size of kdtree - search application - Alice TPC tracker situation
00008   //
00009 */
00010 
00011 //#include <malloc.h>
00012 #include "TSystem.h"
00013 #include "TMatrixD.h"
00014 #include "TRandom.h"
00015 #include "TGraph.h"
00016 #include "TStopwatch.h"
00017 #include "TKDTree.h"
00018 
00019 
00020 
00021 
00022 void TestBuild(const Int_t npoints = 1000000, const Int_t bsize = 100);
00023 void TestConstr(const Int_t npoints = 1000000, const Int_t bsize = 100);
00024 void TestSpeed(Int_t npower2 = 20, Int_t bsize = 10);
00025 
00026 //void TestkdtreeIF(Int_t npoints=1000, Int_t bsize=9, Int_t nloop=1000, Int_t mode = 2);
00027 //void TestSizeIF(Int_t nsec=36, Int_t nrows=159, Int_t npoints=1000,  Int_t bsize=10, Int_t mode=1);
00028 
00029 
00030 
00031 Float_t Mem()
00032 {
00033   // get mem info
00034   ProcInfo_t procInfo;
00035   gSystem->GetProcInfo(&procInfo);
00036   return procInfo.fMemVirtual;
00037 }
00038 
00039 //______________________________________________________________________
00040 void kDTreeTest()
00041 {
00042   //
00043   //
00044   //
00045   printf("\n\tTesting kDTree memory usage ...\n");
00046   TestBuild();  
00047   printf("\n\tTesting kDTree speed ...\n");
00048   TestSpeed();
00049 }
00050 
00051 //______________________________________________________________________
00052 void TestBuild(const Int_t npoints, const Int_t bsize){  
00053   //
00054   // Test kdTree for memory leaks
00055   //
00056    Float_t *data0 =  new Float_t[npoints*2];
00057    Float_t *data[2];
00058    data[0] = &data0[0];
00059    data[1] = &data0[npoints];
00060    for (Int_t i=0;i<npoints;i++) {
00061       data[1][i]= gRandom->Rndm();
00062       data[0][i]= gRandom->Rndm();
00063    }
00064    Float_t before =Mem();
00065    TKDTreeIF *kdtree = new TKDTreeIF(npoints, 2, bsize, data);
00066    kdtree->Build();
00067    Float_t after = Mem();
00068    printf("Memory usage %f KB\n",after-before);
00069    delete kdtree;
00070    Float_t end = Mem();
00071    printf("Memory leak %f KB\n", end-before);
00072    return;      
00073 }
00074 
00075 //______________________________________________________________________
00076 void TestMembers()
00077 {
00078    //This is not really a test, it's a function that illustrates the internal
00079    //behaviour of the kd-tree.
00080    //
00081    //Print out the internal kd-tree data-members, like fCrossNode, for 
00082    //better understading
00083  
00084 
00085    TKDTreeIF *kdtree = 0x0;
00086    Int_t npoints = 33; 
00087    Int_t bsize = 10;
00088    Float_t *data0 =  new Float_t[200]; //not to reallocate each time
00089    Float_t *data1 = new Float_t[200];
00090    for (Int_t i=0;i<npoints;i++) {
00091       data0[i]= gRandom->Rndm();
00092       data1[i]= gRandom->Rndm();
00093    }
00094    
00095    kdtree = new TKDTreeIF(npoints, 2, bsize);
00096    kdtree->SetData(0, data0);
00097    kdtree->SetData(1, data1);
00098    kdtree->Build();
00099 
00100    printf("fNNodes %d, fRowT0 %d, fCrossNode %d, fOffset %d\n",kdtree->GetNNodes(), kdtree->GetRowT0(), kdtree->GetCrossNode(), kdtree->GetOffset());
00101    delete kdtree;
00102    npoints = 44;
00103    for (Int_t i=0;i<npoints;i++) {
00104       data0[i]= gRandom->Rndm();
00105       data1[i]= gRandom->Rndm();
00106    }
00107       kdtree = new TKDTreeIF(npoints, 2, bsize);
00108    kdtree->SetData(0, data0);
00109    kdtree->SetData(1, data1);
00110    kdtree->Build();
00111 
00112    printf("fNNodes %d, fRowT0 %d, fCrossNode %d, fOffset %d\n",kdtree->GetNNodes(), kdtree->GetRowT0(), kdtree->GetCrossNode(), kdtree->GetOffset());
00113    delete kdtree;
00114    npoints = 55;
00115    for (Int_t i=0;i<npoints;i++) {
00116       data0[i]= gRandom->Rndm();
00117       data1[i]= gRandom->Rndm();
00118    }
00119    kdtree = new TKDTreeIF(npoints, 2, bsize);
00120    kdtree->SetData(0, data0);
00121    kdtree->SetData(1, data1);
00122    kdtree->Build();
00123 
00124    printf("fNNodes %d, fRowT0 %d, fCrossNode %d, fOffset %d\n",kdtree->GetNNodes(), kdtree->GetRowT0(), kdtree->GetCrossNode(), kdtree->GetOffset());
00125    delete kdtree;
00126    npoints = 66;
00127    for (Int_t i=0;i<npoints;i++) {
00128       data0[i]= gRandom->Rndm();
00129       data1[i]= gRandom->Rndm();
00130    }
00131       kdtree = new TKDTreeIF(npoints, 2, bsize);
00132    kdtree->SetData(0, data0);
00133    kdtree->SetData(1, data1);
00134    kdtree->Build();
00135 
00136    printf("fNNodes %d, fRowT0 %d, fCrossNode %d, fOffset %d\n",kdtree->GetNNodes(), kdtree->GetRowT0(), kdtree->GetCrossNode(), kdtree->GetOffset());
00137    delete kdtree;
00138    npoints = 77;
00139    for (Int_t i=0;i<npoints;i++) {
00140       data0[i]= gRandom->Rndm();
00141       data1[i]= gRandom->Rndm();
00142    }
00143    kdtree = new TKDTreeIF(npoints, 2, bsize);
00144    kdtree->SetData(0, data0);
00145    kdtree->SetData(1, data1);
00146    kdtree->Build();
00147 
00148    printf("fNNodes %d, fRowT0 %d, fCrossNode %d, fOffset %d\n",kdtree->GetNNodes(), kdtree->GetRowT0(), kdtree->GetCrossNode(), kdtree->GetOffset());
00149    delete kdtree;
00150    npoints = 88;
00151    for (Int_t i=0;i<npoints;i++) {
00152       data0[i]= gRandom->Rndm();
00153       data1[i]= gRandom->Rndm();
00154    }
00155    kdtree = new TKDTreeIF(npoints, 2, bsize);
00156    kdtree->SetData(0, data0);
00157    kdtree->SetData(1, data1);
00158    kdtree->Build();
00159 
00160    printf("fNNodes %d, fRowT0 %d, fCrossNode %d, fOffset %d\n",kdtree->GetNNodes(), kdtree->GetRowT0(), kdtree->GetCrossNode(), kdtree->GetOffset());
00161    delete kdtree;
00162 
00163 
00164 
00165    delete data0;
00166    delete data1;
00167 }
00168 
00169 
00170 
00171 //______________________________________________________________________
00172 void TestConstr(const Int_t npoints, const Int_t bsize)
00173 {
00174 //
00175 //compare the results of different data setting functions
00176 //nothing printed - all works correctly
00177 
00178    Float_t *data0 =  new Float_t[npoints*2];
00179    Float_t *data[2];
00180    data[0] = &data0[0];
00181    data[1] = &data0[npoints];
00182    for (Int_t i=0;i<npoints;i++) {
00183       data[1][i]= gRandom->Rndm();
00184       data[0][i]= gRandom->Rndm();
00185    }
00186    Float_t before =Mem();
00187    TKDTreeIF *kdtree1 = new TKDTreeIF(npoints, 2, bsize, data);
00188    kdtree1->Build();
00189    TKDTreeIF *kdtree2 = new TKDTreeIF(npoints, 2, bsize);
00190    kdtree2->SetData(0, data[0]);
00191    kdtree2->SetData(1, data[1]);
00192    kdtree2->Build();
00193    Int_t nnodes = kdtree1->GetNNodes();
00194    if (nnodes - kdtree2->GetNNodes()>1){
00195       printf("different number of nodes\n");
00196       return;
00197    }
00198    for (Int_t inode=0; inode<nnodes; inode++){
00199       Float_t value1 = kdtree1->GetNodeValue(inode);
00200       Float_t value2 = kdtree2->GetNodeValue(inode);
00201       if (TMath::Abs(value1-value2 > 0.001)){
00202          printf("node %d value: %f %f\n", inode, kdtree1->GetNodeValue(inode), kdtree2->GetNodeValue(inode));
00203       }
00204    }
00205    delete kdtree1;
00206    delete kdtree2;
00207    Float_t end = Mem();
00208    printf("Memory leak %f KB\n", end-before);
00209    return;
00210 }
00211 
00212 
00213 //______________________________________________________________________
00214 void TestSpeed(Int_t npower2, Int_t bsize)
00215 {
00216   //
00217   // Test of building time of kdTree
00218   //
00219   if(npower2 < 10){
00220     printf("Please specify a power of 2 greater than 10\n");
00221     return;
00222   }
00223   
00224   Int_t npoints = Int_t(pow(2., npower2))*bsize;
00225   Float_t *data0 =  new Float_t[npoints*2];
00226   Float_t *data[2];
00227   data[0] = &data0[0];
00228   data[1] = &data0[npoints];
00229   for (Int_t i=0;i<npoints;i++) {
00230     data[1][i]= gRandom->Rndm();
00231     data[0][i]= gRandom->Rndm();
00232   }
00233   
00234   TGraph *g = new TGraph(npower2-10);
00235   g->SetMarkerStyle(7);
00236   TStopwatch timer;
00237   Int_t tpoints;
00238   TKDTreeIF *kdtree = 0x0;
00239   for(int i=10; i<npower2; i++){
00240     tpoints = Int_t(pow(2., i))*bsize;
00241     timer.Start(kTRUE);
00242     kdtree = new TKDTreeIF(tpoints, 2, bsize, data);
00243     kdtree->Build();
00244     timer.Stop();
00245     g->SetPoint(i-10, i, timer.CpuTime());
00246     printf("npoints [%d] nodes [%d] cpu time %f [s]\n", tpoints, kdtree->GetNNodes(), timer.CpuTime());
00247     //timer.Print("u");
00248     delete kdtree;
00249   }
00250   g->Draw("apl");
00251   return;
00252 }
00253 
00254 /*
00255 //______________________________________________________________________
00256 void TestSizeIF(Int_t nsec, Int_t nrows, Int_t npoints,  Int_t bsize, Int_t mode)
00257 {
00258   //
00259   // Test size to build kdtree
00260   //
00261   Float_t before =Mem();
00262   for (Int_t isec=0; isec<nsec;isec++)
00263     for (Int_t irow=0;irow<nrows;irow++){
00264       TestkdtreeIF(npoints,1,mode,bsize);
00265     }
00266   Float_t after = Mem();
00267   printf("Memory usage %f\n",after-before);
00268 }
00269 */
00270 
00271 /*
00272 //______________________________________________________________________
00273 void  TestkdtreeIF(Int_t npoints, Int_t bsize, Int_t nloop, Int_t mode)
00274 {
00275 //
00276 // Test speed and functionality of 2D kdtree.
00277 // Input parametrs:
00278 // npoints - number of data points
00279 // bsize   - bucket size
00280 // nloop   - number of loops
00281 // mode    - tasks to be performed by the kdTree
00282 //         - 0  : time building the tree
00283 //
00284 
00285  
00286   Float_t rangey  = 100;
00287   Float_t rangez  = 100;
00288   Float_t drangey = 0.1;
00289   Float_t drangez = 0.1;
00290 
00291   //
00292   Float_t *data0 =  new Float_t[npoints*2];
00293   Float_t *data[2];
00294   data[0] = &data0[0];
00295   data[1] = &data0[npoints];
00296   //Int_t i;   
00297   for (Int_t i=0; i<npoints; i++){
00298     data[0][i]          = gRandom->Uniform(-rangey, rangey);
00299     data[1][i]          = gRandom->Uniform(-rangez, rangez);
00300   }
00301   TStopwatch timer;
00302   
00303   // check time build
00304   printf("building kdTree ...\n");
00305   timer.Start(kTRUE);
00306   TKDTreeIF *kdtree = new TKDTreeIF(npoints, 2, bsize, data);
00307   kdtree->Build();
00308   timer.Stop();
00309   timer.Print();
00310   if(mode == 0) return;
00311   
00312   Float_t countern=0;
00313   Float_t counteriter  = 0;
00314   Float_t counterfound = 0;
00315   
00316   if (mode ==2){
00317     if (nloop) timer.Start(kTRUE);
00318     Int_t *res = new Int_t[npoints];
00319     Int_t nfound = 0;
00320     for (Int_t kloop = 0;kloop<nloop;kloop++){
00321       if (kloop==0){
00322         counteriter = 0;
00323         counterfound= 0;
00324         countern    = 0;
00325       }
00326       for (Int_t i=0;i<npoints;i++){
00327         Float_t point[2]={data[0][i],data[1][i]};
00328         Float_t delta[2]={drangey,drangez};
00329         Int_t iter  =0;
00330         nfound =0;
00331         Int_t bnode =0;
00332         //kdtree->FindBNode(point,delta, bnode);
00333         //continue;
00334         kdtree->FindInRangeA(point,delta,res,nfound,iter,bnode);
00335         if (kloop==0){
00336           //Bool_t isOK = kTRUE;
00337           Bool_t isOK = kFALSE;
00338           for (Int_t ipoint=0;ipoint<nfound;ipoint++)
00339             if (res[ipoint]==i) isOK =kTRUE;
00340           counteriter+=iter;
00341           counterfound+=nfound;
00342           if (isOK) {
00343             countern++;
00344           }else{
00345             printf("Bug\n");
00346           }
00347         }
00348       }
00349     }
00350     
00351     if (nloop){
00352       timer.Stop();
00353       timer.Print();
00354     }
00355 
00356     delete [] res; 
00357   }
00358   delete [] data0;
00359   
00360   counteriter/=npoints;
00361   counterfound/=npoints;
00362   if (nloop) printf("Find nearest point:\t%f\t%f\t%f\n",countern, counteriter, counterfound);
00363 }
00364 */
00365 
00366 //______________________________________________________________________
00367 void TestNeighbors()
00368 {
00369 //Test TKDTree::FindNearestNeighbors() function
00370 
00371 //Generate some 3d points
00372    Int_t npoints = 10000;
00373    Int_t nn = 100;
00374    Int_t ntimes = 100;
00375    Int_t bsize = 10; //bucket size of the kd-tree
00376 
00377    Double_t *x = new Double_t[npoints];
00378    Double_t *y = new Double_t[npoints];
00379    Double_t *z = new Double_t[npoints];
00380    for (Int_t i=0; i<npoints; i++){
00381       x[i] = gRandom->Uniform(-100, 100);
00382       y[i] = gRandom->Uniform(-100, 100);
00383       z[i] = gRandom->Uniform(-100, 100);
00384    }
00385 
00386    Int_t diff1=0;
00387 
00388 //for the distances brute-force:
00389    Double_t *dist = new Double_t[npoints];
00390    Int_t *index = new Int_t[npoints];
00391       
00392 //Build the tree
00393    TKDTreeID *kdtree = new TKDTreeID(npoints, 3, bsize);
00394    kdtree->SetData(0, x);
00395    kdtree->SetData(1, y);
00396    kdtree->SetData(2, z);
00397    kdtree->Build();
00398    Int_t *index2 = new Int_t[nn];
00399    Double_t *dist2 = new Double_t[nn];
00400    Double_t point[3];
00401 //Select a random point
00402    for (Int_t itime=0; itime<ntimes; itime++){
00403       Int_t ipoint = Int_t(gRandom->Uniform(0, npoints));
00404 
00405       for (Int_t i=0; i<npoints; i++){
00406          dist[i]=0;
00407 
00408          dist[i]+=(x[i]-x[ipoint])*(x[i]-x[ipoint]);
00409          dist[i]+=(y[i]-y[ipoint])*(y[i]-y[ipoint]);
00410          dist[i]+=(z[i]-z[ipoint])*(z[i]-z[ipoint]);
00411          dist[i]=TMath::Sqrt(dist[i]);
00412 
00413       }
00414       TMath::Sort(npoints, dist, index, kFALSE);
00415 
00416       point[0]=x[ipoint];
00417       point[1]=y[ipoint];
00418       point[2]=z[ipoint];
00419 
00420       kdtree->FindNearestNeighbors(point, nn, index2, dist2);
00421       
00422 
00423       for (Int_t inn=0; inn<nn; inn++){
00424          if (TMath::Abs(dist2[inn]-dist[index[inn]])>1E-8) {
00425             diff1++;
00426             // printf("dist1=%f, dist2=%f, in1=%lld, in2=%d\n", dist[index[inn]], dist2[inn], index[inn], index2[inn]);
00427          }
00428 
00429 
00430       }
00431    }
00432 
00433    printf("Nearest neighbors found for %d random points\n", ntimes);
00434    printf("%d neighbors are wrong compared to \"brute force\" method\n", diff1);
00435 //   printf("Old: %d neighbors are wrong compared to brute-force method\n", diff2);
00436 
00437 //    printf("\n");
00438 //    for (Int_t i=0; i<nn; i++){
00439 //       printf("ind[%d]=%d, dist[%d]=%f\n", i, index2[i], i, dist2[i]);
00440 //    }
00441       
00442       
00443       
00444 
00445    delete [] x;
00446    delete [] y;
00447    delete [] z;
00448    delete [] index;
00449    delete [] dist;
00450    delete [] index2;
00451    delete [] dist2;
00452 }
00453 
00454 //______________________________________________________________________
00455 void TestRange()
00456 {
00457 
00458 //Test TKDTree::FindInRange() function
00459 
00460    Int_t npoints = Int_t(gRandom->Uniform(0, 100000));
00461    Double_t range = gRandom->Uniform(20, 100);
00462 
00463    printf("%d points, range=%f\n", npoints, range);
00464    Int_t ntimes = 10;
00465    Double_t *x = new Double_t[npoints];
00466    Double_t *y = new Double_t[npoints];
00467    Double_t *z = new Double_t[npoints];
00468    for (Int_t i=0; i<npoints; i++){
00469       x[i] = gRandom->Uniform(-100, 100);
00470       y[i] = gRandom->Uniform(-100, 100);
00471       z[i] = gRandom->Uniform(-100, 100);
00472    }
00473 
00474    Int_t *results1 = new Int_t[npoints];
00475    std::vector<Int_t> results2;
00476    Int_t np1;
00477 
00478 //Compute with the kd-tree
00479    Int_t bsize = 10;
00480    TKDTreeID *kdtree = new TKDTreeID(npoints, 3, bsize);
00481    kdtree->SetData(0, x);
00482    kdtree->SetData(1, y);
00483    kdtree->SetData(2, z);
00484    kdtree->Build();
00485    Double_t *dist = new Double_t[npoints];
00486    Int_t *index = new Int_t[npoints];
00487    Int_t ndiff = 0;
00488    for (Int_t itime=0; itime<ntimes; itime++){
00489       Double_t point[3];
00490       point[0]=gRandom->Uniform(-90, 90);
00491       point[1]=gRandom->Uniform(-90, 90);
00492       point[2]=gRandom->Uniform(-90, 90);
00493 
00494       //printf("point: (%f, %f, %f)\n\n", point[0], point[1], point[2]);
00495       for (Int_t ipoint=0; ipoint<npoints; ipoint++){
00496          dist[ipoint]=0;
00497          dist[ipoint]+=(x[ipoint]-point[0])*(x[ipoint]-point[0]);
00498          dist[ipoint]+=(y[ipoint]-point[1])*(y[ipoint]-point[1]);
00499          dist[ipoint]+=(z[ipoint]-point[2])*(z[ipoint]-point[2]);
00500          dist[ipoint]=TMath::Sqrt(dist[ipoint]);
00501          index[ipoint]=ipoint;
00502       }
00503       TMath::Sort(npoints, dist, index, kFALSE);
00504       np1=0;
00505       while (np1<npoints && dist[index[np1]]<=range){
00506          results1[np1]=index[np1];
00507          np1++;
00508       }
00509       results2.clear();
00510       kdtree->FindInRange(point, range, results2);
00511 
00512       if (TMath::Abs(np1 - Int_t(results2.size()))>0.1) {
00513          ndiff++;
00514          printf("different numbers of points found, %d %d\n", np1, Int_t(results2.size()));
00515          continue;
00516       } 
00517 
00518       //have to sort the results, as they are in different order
00519       TMath::Sort(np1, results1, index, kFALSE);
00520       std::sort(results2.begin(), results2.end());
00521 
00522       for (Int_t i=0; i<np1; i++){
00523          if (TMath::Abs(results1[index[i]]-results2[i])>1E-8) ndiff++;
00524       }
00525    }
00526    printf("%d  differences found between \"brute force\" method and kd-tree\n", ndiff);
00527 
00528    delete [] x;
00529    delete [] y;
00530    delete [] z;
00531    delete [] index;
00532    delete [] dist;
00533    delete [] results1;
00534    delete kdtree;
00535 }
00536 
00537 
00538 
00539 
00540 //______________________________________________________________________
00541 int main() { 
00542    kDTreeTest();
00543    return 0; 
00544 }

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