kdtree.cc
Go to the documentation of this file.
00001 namespace icp {
00002 
00003 // Guy Shechter
00004 // June 2004
00005 
00006 // ********
00007 // Edit kdtree_common.h to set architecture specific pathnames.
00008 // ********
00009 
00010 //
00011 // You can turn on some of the following definitions to debug this file.
00012 //
00013 #undef DEBUG            //General input-output debugging information
00014 #undef DEBUG_BUILD_TREE  //Follow how the k-D tree is being built.
00015 #undef DISPLAY_TREE      //Output the tree in a depth first traversal
00016 #undef DEBUG_RUN_QUERIES //Follow the tree querying process
00017 
00018 #undef TIME             //Find out how long it takes to build the k-D tree
00019                          //and to perform queries.
00020 
00021 //
00022 // Standard includes 
00023 //
00024 #include <math.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 
00028 //
00029 // Core functions are located in the following files
00030 //
00031 #include "icp/kdtree_common.h"
00032 
00033 #define mxArray double
00034 #define mxREAL double
00035 #define mxCreateDoubleMatrix(n,m,t) malloc(sizeof(t)*n*m)
00036 
00037 void mexFunction( int nlhs, mxArray **plhs, int nrhs, const mxArray **prhs){
00038   Tree         *tree;
00039   double       *reference, *model;
00040   int          *index, i;
00041   unsigned int  N, D, M;
00042   double       *closest_pts, *distances, *pointer_to_tree;
00043   int          SkipQueries=0;
00044   
00045   if (nrhs <2 ){
00046     fprintf(stderr,"Must have at least two input arrays.");
00047   }
00048   
00049 #ifdef DEBUG
00050   mexPrintf("Mex function called with %d inputs and %d explicit outputs\n",nrhs,nlhs);
00051 #endif
00052   
00053   reference = mxGetPr(prhs[0]);
00054   N = mxGetM(prhs[0]);
00055   D = mxGetN(prhs[0]);
00056   
00057   if ((!N || !D ) && ( nrhs < 3) )
00058     fprintf(stderr,"You have to supply some reference points to build a k-D tree.");
00059   
00060 #ifdef TIME
00061   gettimeofday(&tv1,&tz);
00062 #endif
00063   
00064   //
00065   //
00066   // If the tree is not passed in as a third input, we must build it
00067   //
00068   //
00069   if (nrhs < 3 ){   
00070     
00071 #ifdef DEBUG
00072     mexPrintf("----------------------\n");
00073     mexPrintf("Building k-D Tree ...\n");
00074 #endif
00075     
00076     index = (int*) malloc( sizeof(int) * N);
00077     for (i=0; i < N; i++) index[i]=i;  
00078     if ( (tree = build_kdtree(reference,N,D,index,N,0))==NULL ){
00079       free(index);
00080       fprintf(stderr,"Not enough free memory to build k-D tree\n");
00081     } else {
00082       tree->dims = D;
00083       free(index);
00084     }
00085 
00086 #ifdef DEBUG
00087     mexPrintf("Done Building k-D Tree\n");
00088     mexPrintf("----------------------\n");
00089 #endif
00090     
00091   } else {
00092     
00093     //
00094     // The tree was built previously, and is now being passed in to the function.
00095     //
00096     //
00097     // The tree was built previously, and is now being passed in to the function.
00098     //
00099     if (   (pointer_to_tree = mxGetPr(prhs[2])) == NULL )
00100       fprintf(stderr,"Third argument is not a valid pointer to a k-D tree\n");
00101 
00102     if ( (tree = (Tree *) ((long) pointer_to_tree[0]))== NULL )
00103       fprintf(stderr,"Third argument is not a valid pointer to a k-D tree\n");
00104     
00105   }
00106   
00107 #ifdef TIME
00108   gettimeofday(&tv2,&tz);
00109   if (tv2.tv_usec - tv1.tv_usec < 0) {
00110     tv2.tv_sec--;
00111     tv2.tv_usec += 1000000;
00112   }    
00113   mexPrintf("Time to Build Tree : %f\n", tv2.tv_sec -tv1.tv_sec+(tv2.tv_usec-tv1.tv_usec)/1000000.0);
00114 #endif
00115   
00116 
00117 #ifdef DISPLAY_TREE
00118   mexPrintf("\nDepth first traversal of the k-D tree\n");
00119   mexPrintf("-------------------------------------\n");
00120   display_tree(tree->rootptr,D);
00121   mexPrintf("-------------------------------------\n");
00122 #endif
00123 
00124   
00125   //
00126   //  Query section
00127   //
00128   //
00129   
00130   model = mxGetPr(prhs[1]);
00131   M = mxGetM(prhs[1]);
00132 
00133 
00134   if (!model && !M) { 
00135 
00136     // There are no points to query
00137     SkipQueries=1;
00138 
00139   } else {
00140 
00141     // Check that the model points are of the same dimension as the 
00142     // reference points in the k-d tree.
00143     if (mxGetN(prhs[1]) != tree->dims)
00144       fprintf(stderr,"Reference and Model Vectors must be of the same dimension");
00145   }
00146 
00147   if (nlhs >=0){
00148     plhs[0] = mxCreateDoubleMatrix(M, tree->dims,mxREAL);
00149     closest_pts = mxGetPr(plhs[0]);
00150   }
00151   else{ 
00152     closest_pts = (double *) malloc (sizeof(double) *M* (tree->dims));
00153   }
00154 
00155   if (nlhs >=2) {
00156     plhs[1] = mxCreateDoubleMatrix(M,1,mxREAL);
00157     distances = mxGetPr(plhs[1]);
00158   }
00159   else {
00160     distances = (double *) malloc (sizeof(double)*M);
00161   }
00162 
00163   if (nlhs >=3) {
00164     plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL);
00165     pointer_to_tree = mxGetPr(plhs[2]);
00166     pointer_to_tree[0] = (long) tree;
00167   }
00168   
00169   if (!SkipQueries) {
00170 
00171 #ifdef TIME
00172     gettimeofday(&tv1,&tz);
00173 #endif  
00174   
00175 #ifdef DEBUG
00176     mexPrintf("--------------------\n");
00177     mexPrintf("Running Queries...\n");
00178 #endif
00179     
00180     run_queries(tree->rootptr, model, M, tree->dims, closest_pts,
00181                 distances, RETURN_POINTS);
00182 
00183 #ifdef DEBUG
00184     mexPrintf("Done Running Queries\n");
00185     mexPrintf("--------------------\n");
00186 #endif
00187 
00188 #ifdef TIME
00189     gettimeofday(&tv2,&tz);
00190     if (tv2.tv_usec - tv1.tv_usec < 0) {
00191       tv2.tv_sec--;
00192       tv2.tv_usec += 1000000;
00193     }    
00194     mexPrintf("Time per Search : %f\n", 
00195               (tv2.tv_sec - tv1.tv_sec + 
00196                (tv2.tv_usec-tv1.tv_usec) /1000000.0 )/(double)M);
00197 #endif
00198   }
00199 
00200   
00201   if (nlhs<3) {
00202 #ifdef DEBUG
00203     mexPrintf("-------------------------------------\n");
00204     mexPrintf("Removing k-D Tree from system memory.\n");
00205 #endif
00206     free_tree(tree->rootptr);
00207     free(tree);
00208 #ifdef DEBUG
00209     mexPrintf("Done.\n");
00210     mexPrintf("-------------------------------------\n");
00211 #endif
00212     if (nlhs < 2){
00213       free(distances);
00214     }
00215   } else{
00216 #ifdef DEBUG
00217     mexPrintf("--------------------------------\n");
00218     mexPrintf("k-D Tree saved in system memory.\n");
00219     mexPrintf("Don't forget to remove it later.\n");
00220     mexPrintf("--------------------------------\n");
00221 #endif
00222   }
00223 #ifdef DEBUG
00224   mexPrintf("Mex function has exited normally.\n");
00225 #endif
00226 }
00227 
00228 
00229 
00230 //
00231 //  k-D Tree main function 
00232 //
00233 void kdtree_main() {
00234 }
00235 
00236 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


icp
Author(s): Maintained by Juergen Sturm
autogenerated on Wed Dec 26 2012 15:34:47