void kd_tree::build_tree(array_2d<double> &mm){ array_1d<double> i_min,i_max; int i; for(i=0;i<mm.get_cols();i++){ i_min.set(i,0.0); i_max.set(i,1.0); } build_tree(mm,i_min,i_max); }
void kd_tree::build_tree(array_2d<double> &mm, array_1d<double> &nmin, array_1d<double> &nmax){ if(nmin.get_dim()!=mm.get_cols()){ printf("WARNING nimin dim %d cols %d\n",nmin.get_dim(),mm.get_cols()); throw -1; } if(nmax.get_dim()!=mm.get_cols()){ printf("WARNING nmax dim %d cols %d\n",nmax.get_dim(),mm.get_cols()); throw -1; } search_time=0.0; search_ct=0; search_ct_solo=0; search_time_solo=0.0; data.reset(); tree.reset(); array_1d<int> inn,use_left,use_right; array_1d<double> tosort,sorted; int i,j,k,l,inp; tol=1.0e-7; diagnostic=1; tree.set_dim(mm.get_rows(),4); data.set_dim(mm.get_rows(),mm.get_cols()); use_left.set_name("kd_tree_constructor_use_left"); use_right.set_name("kd_tree_constructor_use_right"); tree.set_name("kd_tree_tree"); data.set_name("kd_tree_data"); //tree[i][0] will be the dimension being split //tree[i][1] will be left hand node (so, lt) //tree[i][2] will be right hand node (so, ge) //tree[i][3] will be parent mins.set_name("kd_tree_mins"); maxs.set_name("kd_tree_maxs"); for(i=0;i<data.get_cols();i++){ mins.set(i,nmin.get_data(i)); maxs.set(i,nmax.get_data(i)); } array_1d<double> vector; for(i=0;i<data.get_rows();i++){ data.set_row(i,(*mm(i))); } sorted.set_name("kd_tree_constructor_sorted"); tosort.set_name("kd_tree_constructor_tosort"); inn.set_name("kd_tree_constructor_inn"); /*sort the data points by their 0th dimension component*/ for(i=0;i<data.get_rows();i++){ tosort.set(i,data.get_data(i,0)); inn.set(i,i); } sort_and_check(tosort,sorted,inn); /*try to pick the median value as the first node in the tree (the masterparent)*/ inp=data.get_rows()/2; while(inp>0 && sorted.get_data(inp)-sorted.get_data(inp-1)<tol){ /*make sure that the division doesn't come in the middle of a bunch of identical points*/ inp--; } masterparent=inn.get_data(inp); /*assign the remaining points to either the left branch or the right branch of the masterparent*/ for(j=0;j<data.get_rows();j++){ if(masterparent!=j){ if(data.get_data(j,0)<sorted.get_data(inp)){ use_left.add(j); } else{ use_right.add(j); } } } /*organize all of the points on the left branch of the masterparent*/ if(use_left.get_dim()>0){ organize(use_left,0,masterparent,1,use_left.get_dim(),1); } else tree.set(masterparent,1,-1); /*organize all of the points on the right branch of the masterparent*/ if(use_right.get_dim()>0){ organize(use_right,0,masterparent,1,use_right.get_dim(),2); } else tree.set(masterparent,2,-1); tree.set(masterparent,3,-1);/*masterparent has no parent of its own*/ tree.set(masterparent,0,0);/*masterparent split on the 0th dimension*/ /*check to make sure everything has the dimensions that it should*/ if(mins.get_dim()!=maxs.get_dim() || mins.get_dim()!=data.get_cols() || tree.get_rows()!=data.get_rows()){ printf("WARNING tried to make tree but\n"); printf("nmax %d\n",maxs.get_dim()); printf("nmin %d\n",mins.get_dim()); printf("tree %d %d data %d %d\n",tree.get_rows(),tree.get_cols(), data.get_rows(),data.get_cols()); exit(1); } }