00001 namespace icp {
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00020
00021
00022
00023
00024 #include <math.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027
00028
00029
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
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
00095
00096
00097
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
00127
00128
00129
00130 model = mxGetPr(prhs[1]);
00131 M = mxGetM(prhs[1]);
00132
00133
00134 if (!model && !M) {
00135
00136
00137 SkipQueries=1;
00138
00139 } else {
00140
00141
00142
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
00232
00233 void kdtree_main() {
00234 }
00235
00236 }