mod shape¶
- module shape¶
pyo3 module entry point exposed as
anneal._core. Shape matching through the IRA library, behind theirafeature.crate::bias::BasinBiasasks whether two states are the same basin, andcrate::bias::SortedPairsanswers with a descriptor whose threshold has to be found empirically and does not transfer between system sizes. For point sets there is an exact answer: the optimal permutation and rigid motion between them, and the Hausdorff distance under that match.IRA computes it (Gunde, Salles, Hemeryck and Martin-Samos, Comput Phys Commun 280, 108431, 2022). Its threshold is a length rather than a tuned number in descriptor space, so the same value works whatever the system: measured on a 38-point Lennard-Jones cluster, a permuted and rotated copy returns 0.0, the same basin jittered by 0.02 returns 0.054, and a different basin returns 1.58.
The library is Fortran with a C-bound interface, linked here as
libira. Build it and pointIRA_LIB_DIRat the result, or leave the feature off.Functions
- fn axis_deviation(coords: ArrayView1<f64>, axis: [f64; 3], order: usize) -> Result<f64, ShapeError>¶
Smallest deviation over the rotations of an
order-fold axis.A structure is scored against a symmetry it need not possess, so the result is a distance from that symmetry rather than a test for it. Minimising over the non-trivial powers keeps the quantity a property of the axis rather than of which power happens to be tried.
- fn match_shapes(a: ArrayView1<f64>, b: ArrayView1<f64>, kmax_factor: f64) -> Result<Match, ShapeError>¶
Optimal match between two flattened
(n, 3)point sets.kmax_factorbounds how far IRA searches for candidate frames; 1.8 is the value the library’s examples use for equal-sized structures.
- fn rotation_matrix(axis: [f64; 3], angle: f64) -> [f64; 9]¶
Rotation by
angleabout a unitaxis, row-major, forsymmetry_deviation.
- fn symmetry_deviation(coords: ArrayView1<f64>, matrix: &[f64; 9]) -> Result<f64, ShapeError>¶
Deviation of a structure from invariance under one operation.
matrixis a three by three orthogonal operation in row-major order. Returns the Hausdorff distance between the structure and its image, which is zero when the operation is an exact symmetry and grows smoothly with the departure from it.The continuous quantity is the useful one. A point group is a discrete answer that reads C1 for every structure a search on this landscape visits, so a bias on it deposits on a constant; the deviation under a chosen operation separates structures that no group label distinguishes.
- fn symmetry_pair(coords: ArrayView1<f64>, matrix: &[f64; 9]) -> Result<(f64, Vec<usize>), ShapeError>¶
Hausdorff deviation and the permutation realising the image.
perm[i]is the point thatmatrixsends ontoiwhen the library returns a bijection. The residualx[i] − R x[perm[i]]is the Cartesian leftover of that symmetry.
Enums
- enum ShapeError¶
Error from the shape-matching library.
- NonBijectivePermutation¶
The library returned success with a permutation that is not a bijection, so the correspondence it reports cannot be used.
Observed against libira at 3cb0c29: matching a twelve-point structure to a relabelled copy of itself returns
cerr = 0, the correct distance of zero and the correct identity rotation, with the permutation[4,5,6,7,8,9,10,0,0,1,2,3], where index 0 is assigned twice and index 11 never. The distance is computed inside the library and is right; the correspondence is not.Reported rather than repaired: a permutation with a duplicate has no unique completion, and guessing one would put points in each other’s places silently. Callers that only need the distance are unaffected.
- SizeMismatch(usize, usize)¶
Structures hold different numbers of points, so no permutation exists.
- Library(i32)¶
IRA reported a non-zero status.
- NotThreeDimensional(usize)¶
A coordinate buffer whose length is not a multiple of three.
- Empty¶
An empty structure, which has no symmetry to measure.
Traits implemented
- impl std::fmt::Display for ShapeError¶
- impl std::error::Error for ShapeError¶
Structs and Unions
- struct CanonicalOrder¶
A canonical atom order and frame, taken against a fixed reference.
Keying basins on shape has been priced out by the comparison, not by the descriptor. A shape distance between two structures costs an IRA call, so a bias holding a few thousand basins pays one call per comparison and a run that does a hundred thousand hops cannot finish.
The permutation IRA already returns is what removes that cost, and it was being discarded. Matching each structure once against a single reference gives an ordering and a frame in which corresponding points occupy corresponding slots; after that, comparing two structures is Euclidean distance on the aligned coordinates. One call per hop rather than one per basin.
The idea is the one
readconuses for atom identity: the.conformat groups atoms by element and so reorders them, and rather than pretending order does not matter it stores the pre-grouping index “so the original sequence can be reconstructed after any number of read/write cycles”. Carry the permutation; do not quotient it away.What this buys over sorting
A sorted descriptor destroys correspondence: it says which values occur, not which point holds which. Two structures with the same multiset of site energies and a different arrangement are identical to it. Under a canonical order the arrangement survives, so the descriptor separates them, and the merge radius becomes a root-mean-square displacement, which is a length and transfers between sizes.
- kmax_factor: f64¶
Search breadth passed to IRA.
Implementations
- impl CanonicalOrder¶
Functions
- fn canonicalise(&self, x: ArrayView1<f64>) -> Option<Array1<f64>>¶
xreordered and rigidly moved onto the reference frame.Nonewhen IRA cannot match, which for equal-sized structures means the call failed rather than that no match exists; the caller should fall back to an order-free descriptor rather than treat it as a new basin.
- fn n_points(&self) -> usize¶
Points the reference holds.
- fn new(reference: Array1<f64>, kmax_factor: f64) -> Self¶
A canonicaliser against
reference, which fixes the frame for the run.Any structure of the right size will do; what matters is that it does not change, since the ordering is only canonical relative to it.
- struct IraMetric¶
Distance between two states under optimal permutation and rigid motion.
- kmax_factor: f64¶
Search breadth passed to IRA.
Implementations
- impl IraMetric¶
Functions
- fn distance(&self, a: ArrayView1<f64>, b: ArrayView1<f64>) -> f64¶
Distance, or
f64::INFINITYwhen the structures cannot be matched.
Traits implemented
- struct IraPassthrough¶
Fingerprint that defers to shape matching.
Fingerprintreturns a vector andcrate::bias::BasinBiascompares those by euclidean distance, which cannot express “optimal over all permutations”. The state is therefore passed through unchanged andIraMetricis used where a metric is wanted instead.
- struct Match¶
Result of matching two point sets.
- distance: f64¶
Hausdorff distance under the optimal permutation and rigid motion.
- rotation: [f64; 9]¶
Row-major 3x3 rotation taking the second structure onto the first.
- translation: [f64; 3]¶
Translation applied after the rotation.
- permutation: Option<Vec<usize>>¶
Permutation carrying the second structure’s points onto the first’s, when the library returns a usable one.
Nonewhen what came back is not a bijection. The distance and the rigid motion are computed inside the library and stay trustworthy in that case; only the correspondence is lost, so a caller that needs the distance is unaffected and a caller that needs the ordering finds out rather than being handed a mapping that puts points in each other’s places.