(distances, k, n_iter=64, local_connectivity=1.0, bandwidth=1.0)
return result, rho
Compute a continuous version of the distance to the kth nearest
    neighbor. That is, this is similar to knn-distance but allows continuous
    k values rather than requiring an integral k. In essence we are simply
    computing the distance such that the cardinality of fuzzy set we generate
    is k.

    Parameters
    ----------
    distances: array of shape (n_samples, n_neighbors)
        Distances to nearest neighbors for each samples. Each row should be a
        sorted list of distances to a given samples nearest neighbors.

    k: float
        The number of nearest neighbors to approximate for.

    n_iter: int (optional, default 64)
        We need to binary search for the correct distance value. This is the
        max number of iterations to use in such a search.

    local_connectivity: int (optional, default 1)
        The local connectivity required -- i.e. the number of nearest
        neighbors that should be assumed to be connected at a local level.
        The higher this value the more connected the manifold becomes
        locally. In practice this should be not more than the local intrinsic
        dimension of the manifold.

    bandwidth: float (optional, default 1)
        The target bandwidth of the kernel, larger values will produce
        larger return values.

    Returns
    -------
    knn_dist: array of shape (n_samples,)
        The distance to kth nearest neighbor, as suitably approximated.

    nn_dist: array of shape (n_samples,)
        The distance to the 1st nearest neighbor for each point.
Compute a continuous version of the distance to the kth nearest
    neighbor. That is, this is similar to knn-distance but allows continuous
    k values rather than requiring an integral k. In essence we are simply
    computing the distance such that the cardinality of fuzzy set we generate
    is k.
Compute a continuous version of the distance to the kth nearest neighbor . That is this is similar to knn - distance but allows continuous k values rather than requiring an integral k . In essence we are simply computing the distance such that the cardinality of fuzzy set we generate is k .
def smooth_knn_dist(distances, k, n_iter=64, local_connectivity=1.0, bandwidth=1.0):
    """Compute a continuous version of the distance to the kth nearest
    neighbor. That is, this is similar to knn-distance but allows continuous
    k values rather than requiring an integral k. In essence we are simply
    computing the distance such that the cardinality of fuzzy set we generate
    is k.

    Parameters
    ----------
    distances: array of shape (n_samples, n_neighbors)
        Distances to nearest neighbors for each samples. Each row should be a
        sorted list of distances to a given samples nearest neighbors.

    k: float
        The number of nearest neighbors to approximate for.

    n_iter: int (optional, default 64)
        We need to binary search for the correct distance value. This is the
        max number of iterations to use in such a search.

    local_connectivity: int (optional, default 1)
        The local connectivity required -- i.e. the number of nearest
        neighbors that should be assumed to be connected at a local level.
        The higher this value the more connected the manifold becomes
        locally. In practice this should be not more than the local intrinsic
        dimension of the manifold.

    bandwidth: float (optional, default 1)
        The target bandwidth of the kernel, larger values will produce
        larger return values.

    Returns
    -------
    knn_dist: array of shape (n_samples,)
        The distance to kth nearest neighbor, as suitably approximated.

    nn_dist: array of shape (n_samples,)
        The distance to the 1st nearest neighbor for each point.
    """
    target = np.log2(k) * bandwidth
    rho = np.zeros(distances.shape[0], dtype=np.float32)
    result = np.zeros(distances.shape[0], dtype=np.float32)

    mean_distances = np.mean(distances)

    for i in range(distances.shape[0]):
        lo = 0.0
        hi = NPY_INFINITY
        mid = 1.0

        # TODO: This is very inefficient, but will do for now. FIXME
        ith_distances = distances[i]
        non_zero_dists = ith_distances[ith_distances > 0.0]
        if non_zero_dists.shape[0] >= local_connectivity:
            index = int(np.floor(local_connectivity))
            interpolation = local_connectivity - index
            if index > 0:
                rho[i] = non_zero_dists[index - 1]
                if interpolation > SMOOTH_K_TOLERANCE:
                    rho[i] += interpolation * (
                        non_zero_dists[index] - non_zero_dists[index - 1]
                    )
            else:
                rho[i] = interpolation * non_zero_dists[0]
        elif non_zero_dists.shape[0] > 0:
            rho[i] = np.max(non_zero_dists)

        for n in range(n_iter):

            psum = 0.0
            for j in range(1, distances.shape[1]):
                d = distances[i, j] - rho[i]
                if d > 0:
                    psum += np.exp(-(d / mid))
                else:
                    psum += 1.0

            if np.fabs(psum - target) < SMOOTH_K_TOLERANCE:
                break

            if psum > target:
                hi = mid
                mid = (lo + hi) / 2.0
            else:
                lo = mid
                if hi == NPY_INFINITY:
                    mid *= 2
                else:
                    mid = (lo + hi) / 2.0

        result[i] = mid

        # TODO: This is very inefficient, but will do for now. FIXME
        if rho[i] > 0.0:
            mean_ith_distances = np.mean(ith_distances)
            if result[i] < MIN_K_DIST_SCALE * mean_ith_distances:
                result[i] = MIN_K_DIST_SCALE * mean_ith_distances
        else:
            if result[i] < MIN_K_DIST_SCALE * mean_distances:
                result[i] = MIN_K_DIST_SCALE * mean_distances

    return result, rho
def smooth_knn_dist ( distances , k , n_iter = 64 , local_connectivity = 1.0 , bandwidth = 1.0 ) : target = np . log2 ( k ) * bandwidth rho = np . zeros ( distances . shape [ 0 ] , dtype = np . float32 ) result = np . zeros ( distances . shape [ 0 ] , dtype = np . float32 ) mean_distances = np . mean ( distances ) for i in range ( distances . shape [ 0 ] ) : lo = 0.0 hi = NPY_INFINITY mid = 1.0 # TODO: This is very inefficient, but will do for now. FIXME ith_distances = distances [ i ] non_zero_dists = ith_distances [ ith_distances > 0.0 ] if non_zero_dists . shape [ 0 ] >= local_connectivity : index = int ( np . floor ( local_connectivity ) ) interpolation = local_connectivity - index if index > 0 : rho [ i ] = non_zero_dists [ index - 1 ] if interpolation > SMOOTH_K_TOLERANCE : rho [ i ] += interpolation * ( non_zero_dists [ index ] - non_zero_dists [ index - 1 ] ) else : rho [ i ] = interpolation * non_zero_dists [ 0 ] elif non_zero_dists . shape [ 0 ] > 0 : rho [ i ] = np . max ( non_zero_dists ) for n in range ( n_iter ) : psum = 0.0 for j in range ( 1 , distances . shape [ 1 ] ) : d = distances [ i , j ] - rho [ i ] if d > 0 : psum += np . exp ( - ( d / mid ) ) else : psum += 1.0 if np . fabs ( psum - target ) < SMOOTH_K_TOLERANCE : break if psum > target : hi = mid mid = ( lo + hi ) / 2.0 else : lo = mid if hi == NPY_INFINITY : mid *= 2 else : mid = ( lo + hi ) / 2.0 result [ i ] = mid # TODO: This is very inefficient, but will do for now. FIXME if rho [ i ] > 0.0 : mean_ith_distances = np . mean ( ith_distances ) if result [ i ] < MIN_K_DIST_SCALE * mean_ith_distances : result [ i ] = MIN_K_DIST_SCALE * mean_ith_distances else : if result [ i ] < MIN_K_DIST_SCALE * mean_distances : result [ i ] = MIN_K_DIST_SCALE * mean_distances return result , rho