def process_node(node, point, tree_points, distances, indices):
    i = cuda.grid(1)
    n_points = tree_points.shape[0]
    n_neighbors = distances.shape[1]

    start = node_range_start(node, n_points)
    end = node_range_end(node, n_points)

    for j in range(start, end):
        tree_point = tree_points[j]

        dist = vincenty(point[0], point[1], tree_point[0], tree_point[1])

        if distances[i][0] > dist:
            # replace farthest neighbor with current point
            distances[i][0] = dist
            indices[i][0] = j

            # bubble sort neighbors
            for k in range(1, n_neighbors):
                if distances[i][k - 1] < distances[i][k]:

                    # swap distances
                    temp = distances[i][k]
                    distances[i][k] = distances[i][k - 1]
                    distances[i][k - 1] = temp

                    # swap indices
                    temp = indices[i][k]
                    indices[i][k] = indices[i][k - 1]
                    indices[i][k - 1] = temp
def distance_to_node(point, node, centroids, radiuses):
    distance = vincenty(point[0], point[1], centroids[node][0],
                        centroids[node][1])

    distance = distance - radiuses[node]

    # 1e-4 meters is less than Vincenty's formula accuracy
    return distance if distance > 1e-4 else 0
Ejemplo n.º 3
0
def find_all(arr, res):
    x, y = cuda.grid(2)

    if x > y and (x < res.shape[0]) and (y < res.shape[0]):
        dist = vincenty(arr[x, 0], arr[x, 1], arr[y, 0], arr[y, 1])

        cuda.atomic.min(res, x, dist)
        cuda.atomic.min(res, y, dist)
def query(points, centroids, radiuses, distances, indices):
    i = cuda.grid(1)

    if i >= points.shape[0]:
        return

    point = points[i]
    n_nodes = centroids.shape[0]
    n_points = points.shape[0]
    n_neighbors = distances.shape[1]

    home_node = point_id_to_node(i, n_points, n_nodes)
    node = home_node

    while True:
        distance = distance_to_node(point, node, centroids, radiuses)
        left_child = node * 2 + 1

        if distance > distances[i][0]:
            node = next_right(node)

        elif left_child < n_nodes:
            node = left_child

        else:
            start = node_range_start(node, n_points)
            end = node_range_end(node, n_points)

            for j in range(start, end):
                p1 = points[i]
                p2 = points[j]

                dist = vincenty(p1[0], p1[1], p2[0], p2[1])

                if distances[i][0] > dist:
                    distances[i][0] = dist
                    indices[i][0] = j

                    for k in range(1, n_neighbors):
                        if distances[i][k - 1] < distances[i][k]:
                            temp = distances[i][k]
                            distances[i][k] = distances[i][k - 1]
                            distances[i][k - 1] = temp

                            temp = indices[i][k]
                            indices[i][k] = indices[i][k - 1]
                            indices[i][k - 1] = temp

            node = next_right(node)

        if node == home_node or node >= n_nodes:
            break
Ejemplo n.º 5
0
def stupid_cpu(points):
    l = len(points)
    result = np.zeros(l, dtype=np.float32)
    result[:] = np.inf

    for x in range(l):
        for y in range(l):
            distance = vincenty(points[x, 0], points[x, 1], points[y, 0],
                                points[y, 1])

            if (distance < result[x]):
                result[x] = distance

    return result
def recursive_build(i_node, data, node_centroids, node_radius, idx_array,
                    node_idx, n_nodes, leaf_size):
    idx_start, idx_end = node_id_to_range(i_node, data.shape[0])

    # determine Node centroid
    node_centroids[i_node] = [0, 0]

    for i in range(idx_start, idx_end):
        node_centroids[i_node] += data[idx_array[i]]

    node_centroids[i_node] /= (idx_end - idx_start)

    # determine Node radius
    radius = 0.0

    for i in range(idx_start, idx_end):
        dist = vincenty(node_centroids[i_node][0],
                        node_centroids[i_node][1],
                        data[idx_array[i]][0],
                        data[idx_array[i]][1])
        if dist > radius:
            radius = dist

    # set node properties
    node_radius[i_node] = radius
    node_idx[i_node] = idx_start, idx_end

    i_child = 2 * i_node + 1

    # recursively create subnodes
    if i_child + 1 >= n_nodes:
        if idx_end - idx_start > 2 * leaf_size:
            print('Memory layout is flawed: not enough nodes allocated')

    elif idx_end - idx_start < 2:
        print('Memory layout is flawed: not enough nodes allocated')

    else:
        partition_indices(data, idx_array, idx_start, idx_end)

        recursive_build(i_child, data, node_centroids, node_radius,
                        idx_array, node_idx, n_nodes, leaf_size)
        recursive_build(i_child + 1, data, node_centroids, node_radius,
                        idx_array, node_idx, n_nodes, leaf_size)
Ejemplo n.º 7
0
def brute_force(points, neighbors=None, n_neighbors=2):
    if neighbors is None:
        neighbors = points

    n = len(points)

    distances = np.zeros((n, n_neighbors), dtype=np.float32)
    distances[:] = np.inf

    indices = np.zeros((n, n_neighbors), dtype=np.int32)

    for i in range(n):
        for j in range(len(neighbors)):
            distance = vincenty(points[i, 0], points[i, 1], neighbors[j, 0],
                                neighbors[j, 1])

            if distance < distances[i][0]:
                distances[i][0] = distance
                indices[i][0] = j

                # bubble sort neighbors
                for k in range(1, n_neighbors):
                    if distances[i][k - 1] < distances[i][k]:

                        # swap distances
                        temp = distances[i][k]
                        distances[i][k] = distances[i][k - 1]
                        distances[i][k - 1] = temp

                        # swap indices
                        temp = indices[i][k]
                        indices[i][k] = indices[i][k - 1]
                        indices[i][k - 1] = temp

    distances = np.flip(distances, 1)
    indices = np.flip(indices, 1)
    return distances, indices
Ejemplo n.º 8
0
def plain_vincenty(point1, point2):
    return vincenty(point1[0], point1[1], point2[0], point2[1])
def distance_to_node(point, node, centroids, radiuses):
    distance = vincenty(point[0], point[1], centroids[node][0],
                        centroids[node][1])

    return max(0, distance - radiuses[node])