Exemplo n.º 1
0
int	ahc_quantize(DyArray *ahct, float *v, int d){
	__assertinfo(ahct == NULL || v == NULL || d <= 0, "IPP");
	int		iclu;
	Cluster	*pclu;
	int		nchild = 0;
	int		*_vassign = ivec_new(1);
	float	*_vdis = fvec_new(1);

	iclu = 0;
	/* traverse all clusters */
	while(true){
		// locate at the i-th cluster
		pclu = (Cluster*)DyArray_get(ahct, iclu, 1);
		if(pclu->type != ClusterType_Leaf){
			// if a cluster is not leaf, extract all centroid of its children
			nchild = pclu->children.count;

			// linear_knn(pclu->cents, nchild, v, d, 1, _vassign, _vdis);
			knn_full(2, 1, nchild, d, 1, pclu->cents, v, NULL, _vassign, _vdis);

			iclu = *(int*)DyArray_get(&pclu->children, _vassign[0], 1);
		}else{
			break;
		}
	}
	FREE(_vassign);
	FREE(_vdis);
	return iclu;
}
Exemplo n.º 2
0
void mexFunction (int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray*prhs[])

{
  if (nrhs < 2 || nrhs > 4) 
    mexErrMsgTxt ("Invalid number of input arguments");
  
  if (nlhs != 2)
    mexErrMsgTxt ("2 output arguments required");

  int d = mxGetM (prhs[0]);
  int n = mxGetN (prhs[0]);
  int nq = mxGetN (prhs[1]);

  if (mxGetM (prhs[1]) != d)
      mexErrMsgTxt("Dimension of base and query vectors are not consistent");
  
  
  if (mxGetClassID(prhs[0]) != mxSINGLE_CLASS 
      || mxGetClassID(prhs[1]) != mxSINGLE_CLASS )
    mexErrMsgTxt ("need single precision array"); 


  float *b = (float*) mxGetPr (prhs[0]);  /* database vectors */
  float *v = (float*) mxGetPr (prhs[1]);  /* query vectors */
  int k = 1; 
  int distype = 2;

  if (nrhs >= 3)
    k = (int) mxGetScalar(prhs[2]);

  if (nrhs >= 4)
    distype = (int) mxGetScalar(prhs[3]);

  if (n < k) 
    mexErrMsgTxt("fewer vectors than number to be returned");    


  /* ouptut: centroids, assignment, distances */

  plhs[0] = mxCreateNumericMatrix (k, nq, mxINT32_CLASS, mxREAL);
  int *assign = (int*) mxGetPr (plhs[0]);
  
  plhs[1] = mxCreateNumericMatrix (k, nq, mxSINGLE_CLASS, mxREAL);
  float *dis = (float*) mxGetPr (plhs[1]);

  /* With Matlab, we have to avoid using threads for the L2 distance, 
     because this one makes a call to MKL, which is no thread-safe */
  knn_full (distype, nq, n, d, k, b, v, NULL, assign, dis);

  /* post-processing: convert to matlab indices, and enforce full sort */

  int i;

  for (i = 0 ; i < nq * k ; i++)
    assign[i]++;
}
Exemplo n.º 3
0
float *knn (int npt, int nclust, int d, int k,
	    const float *codebook, const float *coords, int *vw)
{
  /* The distances to centroids that will be returned */
  float *vwdis = fvec_new(npt * k);

  knn_full (2, npt, nclust, d, k, codebook, coords, NULL, vw, vwdis);
  return vwdis;
}
Exemplo n.º 4
0
static void nn_task (void *arg, int tid, int i)
{
  nn_input_t *t = arg;

  long n0 = t->npt * (long)i / t->n_thread;
  long n1 = t->npt * (long)(i + 1) / t->n_thread;

  knn_full (t->distance_type, n1 - n0, t->nclust, t->d, t->k, t->codebook,
			  t->points + n0 * t->d, t->vw_weights,
			  t->vw + n0 * t->k, t->vwdis + n0 * t->k);
}
Exemplo n.º 5
0
double nn (int npt, int nclust, int d,
	 const float *codebook, const float *coords, int *vw) 
{
  
  /* The distances to centroids that will be returned */
  float *vwdis = fvec_new(npt);
  
  knn_full (2, npt, nclust, d, 1, codebook, coords, NULL, vw, vwdis);
  
  double toterr = fvec_sum(vwdis, npt);
  free(vwdis);

  return toterr;
}
Exemplo n.º 6
0
void knn_full_thread (int distance_type, int npt, int nclust, int d, int k,
                                    const float *codebook, const float *coords,
                                    const float *vw_weights,
                                    int *vw, float *vwdis2,
                                    int n_thread) 
{
  if (npt < n_thread || n_thread == 1) {        /* too few pts */
    return knn_full (distance_type, npt, nclust, d, k, codebook, coords, vw_weights, 
                     vw, vwdis2);
  }

  nn_input_t task = { 
    distance_type,
    nclust, d, k, codebook, 
    npt, coords, vw_weights, vw, vwdis2,
    n_thread
  };

  compute_tasks (n_thread, n_thread, &nn_task, &task);

}