Ejemplo n.º 1
0
void findknnmtree(double *outknn, double *outdist, const double *pX,const double *pTESTX,const struct tree *t1,const int Ni,const int N,const int DIM, const int k){	
	int node;
 // here should be some checkups if all the variables have the right size//
 poppush_t stack=poppush();
 stack.init(t1->MAXTREE);

 double double_max=2147483647;
 double double_max2=double_max*2;
 while(double_max<double_max2){     
     double_max=double_max2;
     double_max2=double_max*2;     
 }
 
 // Init heaptree
 heaptree_t heap=heaptree();
 heap.initheaptree(N,k);
	
 for(int input=0;input<N;input++)	{	
 // initialize abstract datatype of stack
		int indim=input*DIM;

 stack.push(0,0); // push first tree onto stack
  while(1){
	double mindist;
	int fb;
	do{
	 fb=stack.pop(&node,&mindist);	 
     } while(heap.heapsize[input]==k && fb>=0 && mindist>heap.heapnodes[input][0]);
	if(fb==-1)	break;
	
	int kid1=(int) t1->pKIDS[node*2]-1;
	 
	
	if(kid1<0) { // leaf
		double thresh=heap.heapnodes[input][0]*heap.heapnodes[input][0]; // avoid some sqrt() operations
		if(heap.heapsize[input]<k) thresh=double_max;
		for(int i=(int) t1->pJI[node*2]-1;i<=(int) t1->pJI[node*2+1]-1;i++){
			double dist=distance(&pX[DIM*i],&pTESTX[indim],DIM,thresh);	
  			if(dist<thresh) {
					heap.heapupdate(input,sqrt(dist),i+1);
					thresh=heap.heapnodes[input][0]*heap.heapnodes[input][0];
					if(heap.heapsize[input]<k) thresh=double_max;
					}
		}
	}
	else
	{ // no leaf
	 int kid2=(int) t1->pKIDS[node*2+1]-1;		
 	 double d1=sqrt(distance(&t1->pPIVX[DIM*kid1],&pTESTX[indim],DIM));
	 double d2=sqrt(distance(&t1->pPIVX[DIM*kid2],&pTESTX[indim],DIM));
	
	 if(d1<d2) {	// if kid1 is the closer child
	  	 stack.push(kid2,max(d2-t1->pRADIUS[kid2],0));
	 	 stack.push(kid1,max(d1-t1->pRADIUS[kid1],0));
  	 } else{		// if kid2 is the closer child
		 stack.push(kid1,max(d1-t1->pRADIUS[kid1],0));
  	 	 stack.push(kid2,max(d2-t1->pRADIUS[kid2],0));	
	}
  }
  }
 }

 // go through heap trees and pop value by value
 int i=N*k-1;
 for(int n=N-1;n>=0;n--)
  for(int m=k-1;m>=0;m--){
   outknn[i]=heap.heapdata[n][0];
   outdist[i]=heap.heapnodes[n][0];
   heap.heappoproot(n);
   i--;
  }

 stack.cleanup();
 heap.cleanup(N);	
}
Ejemplo n.º 2
0
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
  /* Declare variables. */ 
  int DIM,N,Ni,MAXTREE,node,MAXIMPS;
  double *pX, *pTESTX, *pPIVX,*pRADI;
  double *pJI,*pKIDS, *pNITR, *pNITE;
  int oc=0;



  /* Check for proper number of input and output arguments. */    
  if (nrhs != EXACTINPUTS) {
	mexErrMsgTxt("Not the right number of inputs.\nPlease call findknnmtree(x,testx,k,tree.pivots,tree.radius,tree.jumpindex,tree.kids);");
  } 
  if (nlhs > 3) {
    mexErrMsgTxt("Too many output arguments.");
  }

  /* Get the data. */
  pX  		= (double *)mxGetPr(INPUTX);
  pTESTX  	= (double *)mxGetPr(TESTX);
  pPIVX  	= (double *)mxGetPr(PIVOTSX);
  pRADI  	= (double *)mxGetPr(RADIUS);
  pJI  		= (double *)mxGetPr(JUMPIND);
  pKIDS  	= (double *)mxGetData(KIDS);
  pNITR	  	= (double *)mxGetData(NITR);
  pNITE	  	= (double *)mxGetData(NITE);



//  printf("K=%i\n",k);

  /* Get the number of elements in the input argument. */
  DIM 		= mxGetM(INPUTX);
  N 		= mxGetN(TESTX);
  Ni 		= mxGetN(INPUTX);
  MAXTREE 	= mxGetN(PIVOTSX);



  if (mxGetN(NITE)!=mxGetN(TESTX)) {
    mexErrMsgTxt("There must be one cutoff value for each testpoint.");
  }
  if (mxGetN(NITR)!=mxGetN(INPUTX)) {
    mexErrMsgTxt("There must be one cutoff value for each trainingpoint.");
  }

 // define output matrix
 MAXIMPS=10*N*2;
 plhs[0]=mxCreateDoubleMatrix(2,MAXIMPS,mxREAL);
 double * po=mxGetPr(plhs[0]);


  // here should be some checkups if all the variables have the right size//
 poppush_t stack=poppush();
 stack.init(MAXTREE);

 
 // compute MAXNI 
 double* MAXNI = new double[MAXTREE];
 
 maxnirecurse(MAXNI,pKIDS, pJI, pNITR,0);

 double rejected=0,taken=0;
	
 for(int input=0;input<N;input++)	{	
 // initialize abstract datatype of stack
 int indim=input*DIM;
 double sni=pNITE[input];
 double sqni=sqrt(pNITE[input]);

 
// compute first radius
 double md0=max(sqrt(distance(&pPIVX[0],&pTESTX[indim],DIM))-pRADI[0],0);
 if(md0<sqni || (md0*md0)<MAXNI[0]){
  stack.push(0,0); // push first tree onto stack
  while(1){
	double mindist;
	int fb;
//	do{
  	  fb=stack.pop(&node,&mindist);	 
//     } while(fb>=0 && mindist>sqni && mindist>MAXNI[node]);
	if(fb==-1)	break;
	
	int kid1=(int) pKIDS[node*2]-1;
	 
	
	if(kid1<0) { // leaf
		for(int i=(int) pJI[node*2]-1;i<=(int) pJI[node*2+1]-1;i++){
			double cutoff=max(sni,pNITR[i]);
			double dist=distance(&pX[DIM*i],&pTESTX[indim],DIM,cutoff);		
  			if(dist<cutoff) {
						po[oc]=input+1;
						po[oc+1]=i+1;
						oc+=2;
                        if(oc>=MAXIMPS-1){      
							printf(".");
                            double *temp=po;
							MAXIMPS=(int) ceil((((double) MAXIMPS)/2)*(N+1)/(input+1)*1.1)*2;
							mxArray *mtemp=plhs[0];
							plhs[0]=mxCreateDoubleMatrix(2,MAXIMPS,mxREAL);                             
                            po=mxGetPr(plhs[0]);
                            memcpy(po,temp,oc*sizeof(double));                            
							mxDestroyArray(mtemp);
                        }
					}
		}
	}
	else
	{ // no leaf
	 int kid2=(int) pKIDS[node*2+1]-1;	
     
 	 double md1=max(sqrt(distance(&pPIVX[DIM*kid1],&pTESTX[indim],DIM))-pRADI[kid1],0);
	 if(md1<sqni || md1*md1<MAXNI[kid1]) stack.push(kid1,md1);
     
          
	 double md2=max(sqrt(distance(&pPIVX[DIM*kid2],&pTESTX[indim],DIM))-pRADI[kid2],0);	
	 // push children onto stack
 	 if(md2<sqni || md2*md2<MAXNI[kid2]) stack.push(kid2,md2);
    }
   }
  }
 }

 stack.cleanup();
 mxSetN(plhs[0],(int) ceil ((double)oc/2));  
}