rustcpd
Coherent Point Drift point-set registration — rigid, affine, deformable, constrained deformable, and statistical-shape-model/atlas — powered by a fast, deterministic, pure-Rust core (no BLAS, no compiled dependencies at install time: wheels ship for Linux, macOS, and Windows, CPython ≥ 3.9).
pip install rustcpd
import numpy as np
import rustcpd as cpd
# Rigid: recover the similarity transform mapping source onto target.
result = cpd.register_rigid(target, source) # (N,3)/(M,3) arrays
aligned = result.points # (M, 3)
R, t, s = result.rotation, result.translation, result.scale
# Deformable with landmark constraints and an exact full-rank solve.
result = cpd.register_deformable(
target, source,
alpha=2.0, beta=2.0, low_rank=None,
constraints=[(0, 0), (25, 25)],
)
# Large clouds: rank-300 kernel via pivoted Cholesky (much cheaper to
# build than the default "eigen" method as the source grows).
result = cpd.register_deformable(
target, source, low_rank=300, low_rank_method="pivoted_cholesky",
)
# Statistical shape model (atlas): modes is (M*3, rank), point-major.
result = cpd.register_atlas(target, mean, modes, eigenvalues)
b = result.coefficients
posed = result.scale * (mean @ result.rotation) + result.translation
# Global pose search for atlas initialization (3-D).
init = cpd.pose_initialize(source, target, modes, eigenvalues)
After a deformable fit, apply the learned continuous warp to points it was never trained on — drive a dense mesh from a coarse registration, or move landmarks:
fit = cpd.register_deformable(target_subsample, source_subsample, beta=2.0)
warped_full = fit.transform(full_resolution_points) # any (P, D) array
Read off soft correspondences from any registration — the best target match per source point and its confidence, plus the full posterior:
match = cpd.correspondences(target, result.points, result.sigma2)
match.matches # (M,) best target index per source point
match.probability # (M,) confidence in [0, 1]
match.posterior # (M, N) full soft assignment matrix
Complete a partial shape and get per-point uncertainty. The atlas is a linear-Gaussian shape model, so a partial observation yields a closed-form posterior over its coefficients:
fit = cpd.register_atlas(partial_target, mean, modes, eigenvalues)
post = fit.posterior(partial_target, mean, modes, eigenvalues, completeness=0.55)
completed = post.predict() # (M, D) filled-in shape
confidence = post.predictive_variance() # (M,) per-point uncertainty
ensemble = post.sample_shapes(200, seed=0) # plausible completions
Visibility is inferred from the fitted correspondence; the optional
completeness ∈ (0, 1] anchors it (roughly what fraction of the object was
observed). Calibrate the uncertainty to nominal coverage with the
rustcpd.calibration submodule (split-conformal). None of
this touches the complete-data registration paths.
Shared keyword arguments on every registration: sigma2 (initial
variance; estimated when omitted), max_iterations (default 100),
tolerance, outlier_weight (uniform-outlier mixture weight in [0, 1)),
k (k-nearest-neighbor sparse E-step; None = exact), parallel
(default True; results are bitwise-identical to serial execution), and
single_precision (opt-in f32 E-step, ~1e-7 accuracy, faster on large
2-D/3-D clouds).
Two more on rigid, affine, and deformable (atlas already had the first):
normalize=True conditions the fit in an internal unit-scale frame and
maps the result back to your coordinates — recommended for clouds in
large physical units, where the absolute beta/sigma2 defaults would
otherwise be mis-scaled. callback= is a per-iteration hook receiving
{"iteration", "sigma2", "difference", "points"}; return False to stop
early, True or None to continue:
result = cpd.register_deformable(
target, source, normalize=True,
callback=lambda s: s["sigma2"] > 1e-8, # custom stopping rule
)
The heavy lifting happens in Rust with the GIL released, so other Python
threads keep running. Invalid inputs raise ValueError. Bundled type
stubs give editors and type checkers full signatures.
Parameter-selection guidance: see docs/TUNING.md in the repository.
Source, benchmarks, and the Rust API: see the repository.
License: BSD 2-Clause.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rustcpd-3.0.0.tar.gz.
File metadata
- Download URL: rustcpd-3.0.0.tar.gz
- Upload date:
- Size: 116.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae2ca30de9ef292111947c1ef1344c0e50b2f41f2ac94204e82f767e85634b0e
|
|
| MD5 |
a51d4d9571c52fcedda435a47a94e86d
|
|
| BLAKE2b-256 |
813a1fe381cd3c38a46d386725c88eae0c02f13401789334631a1c0f4b6b8c97
|
Provenance
The following attestation bundles were made for rustcpd-3.0.0.tar.gz:
Publisher:
wheels.yml on agporto/rustcpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustcpd-3.0.0.tar.gz -
Subject digest:
ae2ca30de9ef292111947c1ef1344c0e50b2f41f2ac94204e82f767e85634b0e - Sigstore transparency entry: 2230382935
- Sigstore integration time:
-
Permalink:
agporto/rustcpd@b292d60896c1346d402f0870e431843ff594ece3 -
Branch / Tag:
refs/tags/v3.0.0 - Owner: https://github.com/agporto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b292d60896c1346d402f0870e431843ff594ece3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustcpd-3.0.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: rustcpd-3.0.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
876b7230f2f9d947238e6488799cc6faafc56414abfe6a4a048dce17234b9b98
|
|
| MD5 |
fcbbca9267ba50ef04a104d2606784af
|
|
| BLAKE2b-256 |
5080c4ad2905a979d3e42f64f1c41573a0cd097d39060201a2925ffddbb5ef21
|
Provenance
The following attestation bundles were made for rustcpd-3.0.0-cp39-abi3-win_amd64.whl:
Publisher:
wheels.yml on agporto/rustcpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustcpd-3.0.0-cp39-abi3-win_amd64.whl -
Subject digest:
876b7230f2f9d947238e6488799cc6faafc56414abfe6a4a048dce17234b9b98 - Sigstore transparency entry: 2230383298
- Sigstore integration time:
-
Permalink:
agporto/rustcpd@b292d60896c1346d402f0870e431843ff594ece3 -
Branch / Tag:
refs/tags/v3.0.0 - Owner: https://github.com/agporto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b292d60896c1346d402f0870e431843ff594ece3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustcpd-3.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: rustcpd-3.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ba37f2fbd1d0bd483938bce0b90a080978631b43fce3775cacb09669097379e
|
|
| MD5 |
4515498e5e028da0a572e117065a1cbb
|
|
| BLAKE2b-256 |
e8b05a3a2e4a2f42ad276f1bb2e8c6c02b8ec5cb2d49d2b500a25050be4ab13b
|
Provenance
The following attestation bundles were made for rustcpd-3.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
wheels.yml on agporto/rustcpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustcpd-3.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
8ba37f2fbd1d0bd483938bce0b90a080978631b43fce3775cacb09669097379e - Sigstore transparency entry: 2230383978
- Sigstore integration time:
-
Permalink:
agporto/rustcpd@b292d60896c1346d402f0870e431843ff594ece3 -
Branch / Tag:
refs/tags/v3.0.0 - Owner: https://github.com/agporto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b292d60896c1346d402f0870e431843ff594ece3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustcpd-3.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: rustcpd-3.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 911.2 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65e949b2a308b9c0002a9ed43f1042fb77fd021053e3ffb4f61313dae76c4fa2
|
|
| MD5 |
c3fe48a96099614987e9379c2ed053ce
|
|
| BLAKE2b-256 |
3a92636c48dead0e559b5bd78cda0c7d08e896ad884ea7bca9924ef1a04ce147
|
Provenance
The following attestation bundles were made for rustcpd-3.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
wheels.yml on agporto/rustcpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustcpd-3.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
65e949b2a308b9c0002a9ed43f1042fb77fd021053e3ffb4f61313dae76c4fa2 - Sigstore transparency entry: 2230384564
- Sigstore integration time:
-
Permalink:
agporto/rustcpd@b292d60896c1346d402f0870e431843ff594ece3 -
Branch / Tag:
refs/tags/v3.0.0 - Owner: https://github.com/agporto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b292d60896c1346d402f0870e431843ff594ece3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustcpd-3.0.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: rustcpd-3.0.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 1.9 MB
- Tags: CPython 3.9+, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de91fbec12153e7a34a8a59630a72748ded799ffa533207a3de7443edfe5ed7a
|
|
| MD5 |
01a6333015039948fe4b1dc6bd1ae069
|
|
| BLAKE2b-256 |
ed0931db1659a044c231f2e8db8ef78d41082f9a3cb4379bf358d2305894080e
|
Provenance
The following attestation bundles were made for rustcpd-3.0.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:
Publisher:
wheels.yml on agporto/rustcpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustcpd-3.0.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl -
Subject digest:
de91fbec12153e7a34a8a59630a72748ded799ffa533207a3de7443edfe5ed7a - Sigstore transparency entry: 2230385353
- Sigstore integration time:
-
Permalink:
agporto/rustcpd@b292d60896c1346d402f0870e431843ff594ece3 -
Branch / Tag:
refs/tags/v3.0.0 - Owner: https://github.com/agporto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b292d60896c1346d402f0870e431843ff594ece3 -
Trigger Event:
push
-
Statement type: