cluster
Neighbor search and grouping: kNN, FPS, radius queries, local grids, decimation, and kNN interpolation.
Functions:
-
knnβFind the \(k\) nearest neighbors in \(x\) for each point in \(y\).
-
knn_graphβCompute the kNN graph of \(x\).
-
fpsβA sampling algorithm from the paper [PointNet++: Deep Hierarchical Feature
-
local_gridβApplies local grid quantization to the source tensor as explained in the paper
-
radiusβtorch_geometric.nn.pool.radiuswrapper with an optional sort-by-source-index tie-breaker. -
groupβPartition a packed point cloud into local groups with FPS centers and a \(k\)-NN neighborhood.
-
knn_interpolateβk-NN interpolation with inverse-distance weighting.
-
dense_neighborsβPad a
[source, target]edge list into a dense \((N_t, k)\) neighbor table. -
gather_neighborsβGather source features along a
dense_neighborstable, zero where the table is padded.
knn [source] ΒΆ
knn(
x: Tensor,
y: Tensor,
k: int,
batch_x: OptTensor = None,
batch_y: OptTensor = None,
cosine: bool = False,
num_workers: int = 1,
batch_size: Optional[int] = None,
) -> Tensor
Find the \(k\) nearest neighbors in \(x\) for each point in \(y\).
A wrapper around torch_geometric.nn.pool.knn that checks its inputs.
Important
If provided, the batch_x and batch_y tensors must be sorted in non-decreasing order; unsorted batches raise a ValueError.
Note
When a point of \(y\) coincides with a point of \(x\) (e.g. knn(pos, pos, k)), the query point itself counts among the \(k\) neighbors, matching torch_geometric.nn.pool.knn.
Parameters:
-
x(Tensor) βThe source tensor to find the nearest neighbors of shape \((N, *)\).
-
y(Tensor) βThe target tensor to find the nearest neighbors of shape \((M, *)\).
-
k(int) βThe number of nearest neighbors to find.
-
batch_x(OptTensor, default:None) βThe batch tensor of the source tensor of shape \((N,)\).
-
batch_y(OptTensor, default:None) βThe batch tensor of the target tensor of shape \((M,)\).
-
cosine(bool, default:False) βWhether to use cosine distance.
-
num_workers(int, default:1) βThe number of workers to use for the computation.
-
batch_size(Optional[int], default:None) βThe batch size to use for the computation.
Returns:
-
TensorβThe nearest neighbors of shape \((2, M \cdot k)\).
knn_graph [source] ΒΆ
knn_graph(
x: Tensor,
k: int,
batch: OptTensor = None,
loop: bool = False,
flow: str = "source_to_target",
cosine: bool = False,
num_workers: int = 1,
batch_size: Optional[int] = None,
) -> Tensor
Compute the kNN graph of \(x\).
A wrapper around torch_geometric.nn.pool.knn_graph that checks its inputs.
Important
If provided, the batch tensor must be sorted in non-decreasing order; an unsorted batch raises a ValueError.
Parameters:
-
x(Tensor) βThe input tensor of shape \((N, *)\).
-
k(int) βThe number of nearest neighbors to find. When
loop=False, the self-edge is excluded from the result. -
batch(OptTensor, default:None) βThe batch tensor of shape \((N,)\).
-
loop(bool, default:False) βWhether to include self-edges.
-
flow(str, default:'source_to_target') βEither
"source_to_target"(PyG default,edge_index = (src, dst)wheresrcis the neighbor anddstis the central point) or"target_to_source". -
cosine(bool, default:False) βWhether to use cosine distance.
-
num_workers(int, default:1) βThe number of workers to use for the computation.
-
batch_size(Optional[int], default:None) βThe batch size to use for the computation.
Returns:
-
TensorβEdge index of shape \((2, k \cdot N)\).
fps [source] ΒΆ
fps(
src: Tensor,
batch: Optional[Tensor] = None,
ratio: Optional[Union[Tensor, float]] = None,
num_nodes: Optional[Union[Tensor, float]] = None,
random_start: bool = True,
batch_size: Optional[int] = None,
ptr: Optional[Union[Tensor, List[int]]] = None,
) -> Tensor
A sampling algorithm from the paper PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space by Qi et al., which iteratively samples the most distant point with regard to the rest points.
This function wraps torch_geometric.nn.pool.fps and supports sampling a fixed number of nodes per sample with the num_nodes argument.
Important
If provided, the batch tensor is expected to be sorted.
Parameters:
-
src(Tensor) βThe source tensor to sample from of shape \((N, *)\).
-
batch(Optional[Tensor], default:None) βThe batch tensor to sample from of shape \((N,)\).
-
ratio(Optional[Union[Tensor, float]], default:None) βThe sampling ratio.
-
num_nodes(Optional[Union[Tensor, float]], default:None) βThe number of nodes to sample. When a sample holds fewer than
num_nodespoints, indices repeat (sampling with replacement, matching the reference CUDA FPS), so the output always holdsnum_nodesindices per sample and downstream shapes stay stable. -
random_start(bool, default:True) βWhether to start the sampling randomly.
-
batch_size(Optional[int], default:None) βThe batch size.
-
ptr(Optional[Union[Tensor, List[int]]], default:None) βThe pointer tensor to sample from.
Returns:
-
TensorβThe sampled indices of shape \((M,)\).
Examples:
local_grid [source] ΒΆ
Applies local grid quantization to the source tensor as explained in the paper TorchSparse++: Efficient Point Cloud Engine by Tang et al., which quantizes the source tensor to a local grid.
Note
If a batch tensor is provided, the quantization is applied to each sample separately, so the grid of every sample starts at its own minimum cell.
Parameters:
-
src(Tensor) βThe source tensor to quantize of shape \((N, *)\).
-
size(float) βThe quantization size.
-
batch(Tensor | None, default:None) βThe associated batch tensor of shape \((N,)\).
Returns:
-
TensorβThe quantized source tensor of shape \((N, *)\).
Examples:
radius [source] ΒΆ
radius(
x: Tensor,
y: Tensor,
r: float,
batch_x: OptTensor = None,
batch_y: OptTensor = None,
max_num_neighbors: int = 32,
sort: bool = False,
) -> tuple[Tensor, Tensor]
torch_geometric.nn.pool.radius wrapper with an optional sort-by-source-index tie-breaker.
With sort=False (default) this just delegates to torch_geometric.nn.pool.radius and returns edges in kernel-traversal order. With sort=True, when more than max_num_neighbors source points lie inside a ball, the \(k\) smallest source indices are kept (PointNet++'s reference query_ball_point behavior). Pretrained PointNet++ checkpoints from yanx27 / charlesq34 overfit to this selection rule, so reproducing their accuracy requires sort=True.
Important
If provided, the batch_x and batch_y tensors must be sorted in non-decreasing order (torch_geometric.nn.pool.radius requires it); unsorted batches raise a ValueError.
Parameters:
-
x(Tensor) βSource positions, shape \((N_x, d)\).
-
y(Tensor) βQuery positions, shape \((N_y, d)\).
-
r(float) βBall radius.
-
batch_x(OptTensor, default:None) βBatch index for \(x\), shape \((N_x,)\).
Nonefor a single batch. -
batch_y(OptTensor, default:None) βBatch index for \(y\), shape \((N_y,)\).
Nonefor a single batch. -
max_num_neighbors(int, default:32) βMax neighbors \(k\) kept per query.
-
sort(bool, default:False) βSort in-ball source indices ascending and keep the first \(k\).
Returns:
-
Tensorβ(row, col)edges.rowis the query index,colis the source index. -
TensorβCentroids with no in-ball neighbors emit zero edges; pooling leaves those
-
tuple[Tensor, Tensor]βrows at the reduction identity.
group [source] ΒΆ
group(
pos: Tensor,
batch: Tensor,
num_groups: int,
group_size: int,
random_start: bool = False,
*,
return_indices: bool = False,
) -> Union[
Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]
]
Partition a packed point cloud into local groups with FPS centers and a \(k\)-NN neighborhood.
Farthest point sampling selects num_groups centers per sample, then \(k\)-NN gathers the group_size nearest neighbors of each center, and each neighborhood is recentered on its center. Because num_groups is fixed per sample, the packed result densifies to a regular \((B, G, k, 3)\) batch without padding.
Parameters:
-
pos(Tensor) βPacked point coordinates of shape \((N, 3)\).
-
batch(Tensor) βPer-point batch index of shape \((N,)\).
-
num_groups(int) βNumber of groups (FPS centers) \(G\) per sample.
-
group_size(int) βNumber of neighbors \(k\) per group.
-
random_start(bool, default:False) βWhether to start farthest point sampling from a random point.
-
return_indices(bool, default:False) βIf
True, also return the flat neighbor index into the packed input.
Returns:
-
Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]]β(neighborhood, center), or(neighborhood, center, idx)whenreturn_indicesisTrue. -
Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]]βneighborhoodhas shape \((B, G, k, 3)\) recentered on each center,centerhas shape -
Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]]β\((B, G, 3)\), and
idxhas shape \((B \cdot G \cdot k,)\) indexing the packed input.
Shape
- Input: \((N, 3)\) and \((N,)\).
- Output: \((B, G, k, 3)\) and \((B, G, 3)\) (plus \((B \cdot G \cdot k,)\) when
return_indices).
knn_interpolate [source] ΒΆ
knn_interpolate(
x: Tensor,
pos_x: Tensor,
pos_y: Tensor,
batch_x: OptTensor = None,
batch_y: OptTensor = None,
k: int = 3,
num_workers: int = 1,
weighting: Literal["squared", "inverse"] = "squared",
eps: float = 1e-16,
) -> Tensor
k-NN interpolation with inverse-distance weighting.
From PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space.
For each point \(y\) with position \(\mathbf{p}(y)\), its interpolated features \(\mathbf{f}(y)\) are given by
where \(\{ x_1, \ldots, x_k \}\) are the \(k\) nearest points to \(y\) and the weights \(w(x_i)\) depend on the chosen weighting scheme:
"squared"(default,torch_geometricconvention): \(w(x_i) = 1 / d(\mathbf{p}(y), \mathbf{p}(x_i))^2\)"inverse"(PointNet++three_interpolationconvention): \(w(x_i) = 1 / d(\mathbf{p}(y), \mathbf{p}(x_i))\)
Note
Adapted from the torch_geometric package.
Parameters:
-
x(Tensor) βNode feature matrix \(\mathbf{X} \in \mathbb{R}^{N \times F}\).
-
pos_x(Tensor) βNode position matrix \(\in \mathbb{R}^{N \times d}\).
-
pos_y(Tensor) βUpsampled node position matrix \(\in \mathbb{R}^{M \times d}\).
-
batch_x(OptTensor, default:None) βBatch vector \(\mathbf{b_x} \in \{ 0, \ldots, B-1 \}^N\), assigning each node from \(\mathbf{X}\) to a specific example.
-
batch_y(OptTensor, default:None) βBatch vector \(\mathbf{b_y} \in \{ 0, \ldots, B-1 \}^M\), assigning each node from \(\mathbf{Y}\) to a specific example.
-
k(int, default:3) βNumber of neighbors.
-
num_workers(int, default:1) βNumber of workers for computation. Has no effect when
batch_xorbatch_yis notNone, or the input lies on GPU. -
weighting(Literal['squared', 'inverse'], default:'squared') βWeighting scheme for neighbors.
"squared"for \(1/d^2\) weights (torch_geometricdefault) or"inverse"for \(1/d\) weights (PointNet++ convention). -
eps(float, default:1e-16) βSmall value to avoid division by zero.
Returns:
-
TensorβInterpolated features \(\in \mathbb{R}^{M \times F}\).
dense_neighbors [source] ΒΆ
dense_neighbors(
edge_index: Tensor,
num_sources: int,
num_targets: int,
max_num_neighbors: Optional[int] = None,
) -> Tuple[Tensor, Tensor]
Pad a [source, target] edge list into a dense \((N_t, k)\) neighbor table.
\(k\) is the largest target degree unless max_num_neighbors is given (the cap of the search that produced the edges, which skips the device read). Rows are filled in edge order and padded with the shadow index num_sources, so gather_neighbors needs no mask. The second output is the slot of every edge in its target's row, so per-edge values scatter into the table as values_table[target, slot] = values. Edges grouped by target, which knn and radius return, are consumed as they are; any other order is sorted first.
Parameters:
-
edge_index(Tensor) βEdges as
[source, target], shape \((2, E)\). -
num_sources(int) βNumber of source points \(N_s\), the shadow index of the padding.
-
num_targets(int) βNumber of target points \(N_t\).
-
max_num_neighbors(Optional[int], default:None) βRow width \(k\); must be at least the largest target degree.
Returns:
-
Tuple[Tensor, Tensor]βThe \((N_t, k)\) table of source indices and the \((E,)\) slot of every edge.
Shape
Input: \((2, E)\) Output: \((N_t, k)\) and \((E,)\)
Example
gather_neighbors [source] ΒΆ
Gather source features along a dense_neighbors table, zero where the table is padded.
Parameters:
-
x(Tensor) βSource features, shape \((N_s, C)\).
-
table(Tensor) βNeighbor table, shape \((N_t, k)\), padded with the shadow index \(N_s\).
Returns:
-
TensorβThe neighbor features, shape \((N_t, k, C)\).
Shape
Input: \((N_s, C)\) and \((N_t, k)\) Output: \((N_t, k, C)\)