예제 #1
0
파일: kd_util.cpp 프로젝트: EricDoug/queso
void annPlaneSplit(				// split points by a plane
	ANNpointArray		pa,				// points to split
	ANNidxArray			pidx,			// point indices
	int					n,				// number of points
	int					d,				// dimension along which to split
	ANNcoord			cv,				// cutting value
	int					&br1,			// first break (values < cv)
	int					&br2)			// second break (values == cv)
{
	int l = 0;
	int r = n-1;
	for(;;) {							// partition pa[0..n-1] about cv
		while (l < n && PA(l,d) < cv) l++;
		while (r >= 0 && PA(r,d) >= cv) r--;
		if (l > r) break;
		PASWAP(l,r);
		l++; r--;
	}
	br1 = l;					// now: pa[0..br1-1] < cv <= pa[br1..n-1]
	r = n-1;
	for(;;) {							// partition pa[br1..n-1] about cv
		while (l < n && PA(l,d) <= cv) l++;
		while (r >= br1 && PA(r,d) > cv) r--;
		if (l > r) break;
		PASWAP(l,r);
		l++; r--;
	}
	br2 = l;					// now: pa[br1..br2-1] == cv < pa[br2..n-1]
}
예제 #2
0
파일: kd_util.cpp 프로젝트: EricDoug/queso
void annMedianSplit(
	ANNpointArray		pa,				// points to split
	ANNidxArray			pidx,			// point indices
	int					n,				// number of points
	int					d,				// dimension along which to split
	ANNcoord			&cv,			// cutting value
	int					n_lo)			// split into n_lo and n-n_lo
{
	int l = 0;							// left end of current subarray
	int r = n-1;						// right end of current subarray
	while (l < r) {
		register int i = (r+l)/2;		// select middle as pivot
		register int k;

		if (PA(i,d) > PA(r,d))			// make sure last > pivot
			PASWAP(i,r)
		PASWAP(l,i);					// move pivot to first position

		ANNcoord c = PA(l,d);			// pivot value
		i = l;
		k = r;
		for(;;) {						// pivot about c
			while (PA(++i,d) < c) ;
			while (PA(--k,d) > c) ;
			if (i < k) PASWAP(i,k) else break;
		}
		PASWAP(l,k);					// pivot winds up in location k

		if (k > n_lo)	   r = k-1;		// recurse on proper subarray
		else if (k < n_lo) l = k+1;
		else break;						// got the median exactly
	}
	if (n_lo > 0) {						// search for next smaller item
		ANNcoord c = PA(0,d);			// candidate for max
		int k = 0;						// candidate's index
		for (int i = 1; i < n_lo; i++) {
			if (PA(i,d) > c) {
				c = PA(i,d);
				k = i;
			}
		}
		PASWAP(n_lo-1, k);				// max among pa[0..n_lo-1] to pa[n_lo-1]
	}
										// cut value is midpoint value
	cv = (PA(n_lo-1,d) + PA(n_lo,d))/2.0;
}
예제 #3
0
파일: kd_util.cpp 프로젝트: EricDoug/queso
void annBoxSplit(				// split points by a box
	ANNpointArray		pa,				// points to split
	ANNidxArray			pidx,			// point indices
	int					n,				// number of points
	int					dim,			// dimension of space
	ANNorthRect			&box,			// the box
	int					&n_in)			// number of points inside (returned)
{
	int l = 0;
	int r = n-1;
	for(;;) {							// partition pa[0..n-1] about box
		while (l < n && box.inside(dim, PP(l))) l++;
		while (r >= 0 && !box.inside(dim, PP(r))) r--;
		if (l > r) break;
		PASWAP(l,r);
		l++; r--;
	}
	n_in = l;					// now: pa[0..n_in-1] inside and rest outside
}
예제 #4
0
파일: kd_util.cpp 프로젝트: saubcy/ANN_ES
void annPlaneSplit(				// split points by a plane
		ES_INFO*			es_info,
		ANNpointArray		pa,				// points to split
		ANNidxArray			pidx,			// point indices
		int					n,				// number of points
		int					d,				// dimension along which to split
		ANNcoord			cv,				// cutting value
		int					&br1,			// first break (values < cv)
		int					&br2)			// second break (values == cv)
{
	int l = 0;
	int r = n-1;
	for(;;) {							// partition pa[0..n-1] about cv
#if 1 // es code
		es_info->get_value_by_index(pidx[l]);
#endif
		while (l < n && PA(l,d) < cv) {
			l++;
#if 1 // es code
			es_info->get_value_by_index(pidx[l]);
#endif
		}
#if 1 // es code
		es_info->get_value_by_index(pidx[r]);
#endif
		while (r >= 0 && PA(r,d) >= cv) {
			r--;
#if 1 // es code
			es_info->get_value_by_index(pidx[r]);
#endif
		}
		if (l > r) break;
		PASWAP(l,r);
		l++; r--;
	}
	br1 = l;					// now: pa[0..br1-1] < cv <= pa[br1..n-1]
	r = n-1;
	for(;;) {							// partition pa[br1..n-1] about cv
#if 1 // es code
		es_info->get_value_by_index(pidx[l]);
#endif
		while (l < n && PA(l,d) <= cv) {
			l++;
#if 1 // es code
			es_info->get_value_by_index(pidx[l]);
#endif
		}
#if 1 // es code
		es_info->get_value_by_index(pidx[r]);
#endif
		while (r >= br1 && PA(r,d) > cv) {
			r--;
#if 1 // es code
			es_info->get_value_by_index(pidx[r]);
#endif
		}
		if (l > r) break;
		PASWAP(l,r);
		l++; r--;
	}
	br2 = l;					// now: pa[br1..br2-1] == cv < pa[br2..n-1]
}
예제 #5
0
/************************************************
Partition a range of data points by manipulation the permutation index.
The sliding midpoint rule is used for the partitioning.
Params:
    pa : data points
    pidx : permutation index of data points
    no_dims: number of dimensions
    start_idx : index of first data point to use
    n :  number of data points
    bbox : bounding box of data points
    cut_dim : dimension used for partition (return)
    cut_val : value of cutting point (return)
    n_lo : number of point below cutting plane (return)    
************************************************/
int partition_float(float *pa, uint32_t *pidx, int8_t no_dims, uint32_t start_idx, uint32_t n, float *bbox, int8_t *cut_dim, float *cut_val, uint32_t *n_lo)
{
    int8_t dim = 0, i;
    uint32_t p, q, i2;
    float size = 0, min_val, max_val, split, side_len, cur_val;
    uint32_t end_idx = start_idx + n - 1;
    
    /* Find largest bounding box side */
    for (i = 0; i < no_dims; i++)
    {
        side_len = bbox[2 * i + 1] - bbox[2 * i];
        if (side_len > size)
        {
            dim = i;
            size = side_len;
        }
    }
    
    min_val = bbox[2 * dim];
    max_val = bbox[2 * dim + 1];
    
    /* Check for zero length or inconsistent */
    if (min_val >= max_val)
        return 1;
    
    /* Use middle for splitting */    
    split = (min_val + max_val) / 2;
    
    /* Partition all data points around middle */
    p = start_idx;
    q = end_idx;
    while (p <= q)
    {
        if (PA(p, dim) < split)
        {
            p++;
        }
        else if (PA(q, dim) >= split)
        {
            /* Guard for underflow */
            if (q > 0) 
            {
                q--;
            }
            else
            {
                break; 
            }   
        }
        else
        {
            PASWAP(p, q);
            p++;
            q--;    
        } 
    }

    /* Check for empty splits */
    if (p == start_idx)
    {
        /* No points less than split. 
           Split at lowest point instead.
           Minimum 1 point will be in lower box.
        */
        
        uint32_t j = start_idx;
        split = PA(j, dim);
        for (i2 = start_idx + 1; i2 <= end_idx; i2++) 
        {
            /* Find lowest point */
            cur_val = PA(i2, dim); 
            if (cur_val < split)
            {
                j = i2;
                split = cur_val;
            }
        }
        PASWAP(j, start_idx);
        p = start_idx + 1;
    }
    else if (p == end_idx + 1)
    {
        /* No points greater than split. 
           Split at highest point instead.
           Minimum 1 point will be in higher box.
        */
        
        uint32_t j = end_idx;
        split = PA(j, dim);
        for (i2 = start_idx; i2 < end_idx; i2++)
        {
            /* Find highest point */
            cur_val = PA(i2, dim);
            if (cur_val > split)
            {
                j = i2;
                split = cur_val;
            }    
        }
        PASWAP(j, end_idx);
        p = end_idx;    
    }
    
    /* Set return values */
    *cut_dim = dim;
    *cut_val = split;
    *n_lo = p - start_idx;
    return 0;
}