Exemple #1
0
void kd_tree::nn_srch(double *v, int kk, int *neigh, double *dd){

   int i,j,k,l,node,where,behind,*inn;
   double ddnode,ddtry;
  
 // printf("in nnsrch %e %e %d\n",v[0],v[1],masterparent);
  
   node=find_node(v);
   //printf("found node %d %d %d %d\n",\
   node,tree[node][1],tree[node][2],tree[node][3]);
  /* for(i=0;i<dim;i++){
     printf("%e %e\n",v[i],data[node][i]);
   }*/
   
   ddnode=distance(v,data[node]);
   
   //printf("got distance %e %d\n",ddnode,node);
   dd[0]=ddnode;
   neigh[0]=node;
   
   //printf("node is %d dd %e\n",node,ddnode);
   //printf("%e %e\n",v[0],v[1]);
   //printf("%e %e\n",data[node][0],data[node][1]);
   
   for(i=1;i<kk;i++){
     dd[i]=dd[0]+double(i)*1.0e6;
     neigh[i]=-1;
   }
   
   /*j=1;
   for(i=0;j<kk;i++){
     
     l=1;
     for(k=0;k<j;k++){
       if(neigh[k]==i)l=0;
     }
     if(l==1){
       dd[j]=distance(data[i],v);
       neigh[j]=i;
       j++;
     }
     
   }*/
   
   
  // sort(dd,neigh,kk);
   
   
   
   if(tree[node][3]>=0)neigh_check(v,kk,neigh,dd,tree[node][3],node);
   if(tree[node][1]>=0)neigh_check(v,kk,neigh,dd,tree[node][1],node);
   if(tree[node][2]>=0)neigh_check(v,kk,neigh,dd,tree[node][2],node);
  
}
Exemple #2
0
void kd_tree::neigh_check(double *v, int kk, int *neigh, double *dd,\
 int where, int wherefrom){

   int i,j,k,l,side;
   double dtry,dwhere;
   
   if(v[tree[where][0]]<data[where][tree[where][0]])side=1;
   else side=2;
   
   dtry=fabs((v[tree[where][0]]-data[where][tree[where][0]])/\
   (maxs[tree[where][0]]-mins[tree[where][0]]));
   
   
   if(dtry<=dd[kk-1]){
   
     dwhere=distance(data[where],v);
     if(dwhere<dd[kk-1]){
        for(i=kk-2;i>=0 && dd[i]>dwhere;i--){
           dd[i+1]=dd[i];
	   neigh[i+1]=neigh[i];
	}
	i++;
	
	
	dd[i]=dwhere;
	neigh[i]=where;
     }
     
     if(wherefrom==tree[where][3] || wherefrom==tree[where][side]){
      if(tree[where][3-side]>-1){
       neigh_check(v,kk,neigh,dd,tree[where][3-side],where);
       //check the other side of this node
      }
     }
     
   }
   
   if(wherefrom==tree[where][3]){
     if(tree[where][side]>-1){
       neigh_check(v,kk,neigh,dd,tree[where][side],where);
       //check the side of this node I am naturally on
     } 
   }
   else{
     if(tree[where][3]>-1){
       neigh_check(v,kk,neigh,dd,tree[where][3],where);
       //check the parent of this node, if that is not where I came from
     }
   }
    

}
Exemple #3
0
void kd_tree::nn_srch(array_1d<double> &v, int kk, array_1d<int> &neigh, 
array_1d<double> &dd){
    
    /*
    Find the nearest neighbors of the point specified by v.
    
    kk is the number of nearest neighbors to find.
    
    neigh will store the indices of the nearest neighbors.
    
    dd will store the (normalized) parameter space distances from v to its
    nearest neighbors
    */
    
    double before=double(time(NULL));
    
    int i,j,k,l,node,where,behind;
    double ddnode,ddtry;
   
    neigh.set_dim(kk);
    dd.set_dim(kk);
   
    array_1d<int> inn;
    inn.set_name("kd_tree_nn_srch_inn");
    
    /*first, find the node in the tree where you would add v, were you adding
    v to the tree*/
    node=find_node(v);
    
    /*what is the distance from v to that node*/
    ddnode=distance(v,node);
    
    /*set this node as the nearest neighbor (this is just a guess, not
    a final answer*/
    dd.set(0,ddnode);
    neigh.set(0,node);
    
    /*arbitrarily set the first kk-1 nodes as the rest of the nearest neighbors
    (again, just a guess to get things going)*/
    j=1;
    for(i=0;j<kk;i++){
     
        l=1;
        for(k=0;k<j;k++){
            if(neigh.get_data(k)==i)l=0;
        }
        if(l==1){
            dd.set(j,distance(i,v));
            neigh.set(j,i);   
            j++;
        }
    }

    array_1d<double> ddstore;
    ddstore.set_name("kd_tree_nn_srch_ddstore");
   
    for(i=0;i<kk;i++){
        ddstore.set(i,dd.get_data(i));
    }
    
    /*arrange dd so that it is in ascending order of parameter space distance*/
    sort_and_check(ddstore,dd,neigh);
    
    /*
    Check the three subdivisions of the tree defined by node:
    node's ancestors
    node's left hand side daughters
    node's right hand side daughters
    */
    if(tree.get_data(node,3)>=0)neigh_check(v,kk,neigh,dd,tree.get_data(node,3),node);
    if(tree.get_data(node,1)>=0)neigh_check(v,kk,neigh,dd,tree.get_data(node,1),node);
    if(tree.get_data(node,2)>=0)neigh_check(v,kk,neigh,dd,tree.get_data(node,2),node);
    
    if(kk>1){
        search_time+=double(time(NULL))-before;
        search_ct++;
    }
    else{
        search_time_solo+=double(time(NULL))-before;
        search_ct_solo++;
    }
}
Exemple #4
0
void kd_tree::neigh_check(array_1d<double> &v, int kk, 
array_1d<int> &neigh, array_1d<double> &dd, int where, int wherefrom){
    
    /*
    This routine provides the backend for nn_srch
    
    v is the point for which we are trying to find nearest neighbors
    
    kk is the number of nearest neighbors we are trying to find
    
    neigh stores the indices of the nearest neighbors
    
    dd stores the (normalized) parameter space distances from v to the nearest neighbors
    
    where indicates what node we are examining now
    
    wherefrom indicates what node we just came from (so this search does not backtrack)
    
    This routine will call itself such that it walks through the tree until all possible
    steps are ruled out (by being obviously farther away than the kkth nearest neighbor
    discovered so far).
    */
    
    int i,j,k,l,side,goon;
    double dtry,dwhere;
    
    /*on what side of where does v belong?*/
    if(v.get_data(tree.get_data(where,0))<data.get_data(where,tree.get_data(where,0)))side=1;
    else side=2;
    
    /*
    the parameter space distance between v and where in the dimension on which where splits
    the tree; if this is longer than the distance to the kkth nearest neighbor, there is no
    point in calculating the full parameter space distance bewtween v and where
    */
    dtry=fabs((v.get_data(tree.get_data(where,0))-data.get_data(where,tree.get_data(where,0)))/\
    (maxs.get_data(tree.get_data(where,0))-mins.get_data(tree.get_data(where,0))));
   
   
    if(dtry<=dd.get_data(kk-1)){
          
        dwhere=distance(where,v);
     
        goon=0;
        if(dwhere<dd.get_data(kk-1)){
            goon=1;
            //make sure that where isn't already one of the nearest neighbors
            for(k=0;k<kk;k++)if(neigh.get_data(k)==where)goon=0;
        }
     
        if(goon==1){
            //add where to the list of nearest neighbors
            for(i=kk-2;i>=0 && dd.get_data(i)>dwhere;i--){
                dd.set(i+1,dd.get_data(i));
                neigh.set(i+1,neigh.get_data(i));
            }
            i++;
        
            dd.set(i,dwhere);
            neigh.set(i,where);
        }
     
        if(wherefrom==tree.get_data(where,3) || wherefrom==tree.get_data(where,side)){
            /*inspect the other side of the tree as split by where (assuming we did not just
            come from there)*/
            if(tree.get_data(where,3-side)>-1){
                neigh_check(v,kk,neigh,dd,tree.get_data(where,3-side),where);
            }
        }
     
    }
   
    if(wherefrom==tree.get_data(where,3)){
        if(tree.get_data(where,side)>-1){
            //check the side of this node v is naturally on
            neigh_check(v,kk,neigh,dd,tree.get_data(where,side),where);
        } 
    }
    else{
        if(tree.get_data(where,3)>-1){
            //check the parent of this node, if that is not where I came from
            neigh_check(v,kk,neigh,dd,tree.get_data(where,3),where);
        }
    }
}