Skip to content

Optimise RotationAnalyser permutation loop#12

Merged
bjmorgan merged 6 commits into
mainfrom
optimise-rotation-analyser
Mar 2, 2026
Merged

Optimise RotationAnalyser permutation loop#12
bjmorgan merged 6 commits into
mainfrom
optimise-rotation-analyser

Conversation

@bjmorgan

Copy link
Copy Markdown
Owner

Summary

  • Replace the N! brute-force permutation loop in RotationAnalyser.discrete_orientation with a two-phase composition approach: find the best vertex alignment using symmetry-reduced permutations (via bsym), then compose the best-fit Procrustes rotation with the point group's proper rotation matrices to recover all orientation candidates.
  • A single PointGroupAnalyzer call provides both the reduced permutations and the 3x3 rotation matrices, cached lazily on first access.
  • ~50x speedup for octahedral geometries (15 CSM evaluations instead of 720).
  • Fix OrientationDict.all_rotational_distances type annotation (np.ndarray, not float).
  • Add functional tests for discrete_orientation covering correct reference identification, inverted reference, and perfect geometry.
  • Remove redundant assert isinstance checks across the codebase.

… approach

Use bsym to reduce vertex permutations to symmetry-inequivalent
representatives, then compose the best-fit Procrustes rotation with
the point group's proper rotation matrices to recover all orientation
candidates. A single PointGroupAnalyzer call provides both the reduced
permutations and the 3x3 rotation matrices.

Gives ~50x speedup for octahedral geometries (15 CSM evaluations
instead of 720). The composition is exact for undistorted geometries
and numerically indistinguishable from brute force for moderate
distortions. The docstring documents an orbit-expansion alternative
for cases requiring exact rotation matrices.

Also fixes the OrientationDict type annotation for
all_rotational_distances (np.ndarray, not float).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes RotationAnalyser.discrete_orientation by replacing the factorial permutation search with a symmetry-reduced, two-phase approach that uses point-group analysis to drastically reduce CSM evaluations while still enumerating orientation candidates.

Changes:

  • Add a lazy, cached point-group analysis step that yields symmetry-reduced permutations and proper rotation matrices.
  • Rework discrete_orientation to use reduced permutations for best alignment, then compose the best-fit rotation with proper symmetry rotations to generate orientation candidates.
  • Add functional tests for discrete_orientation and fix OrientationDict.all_rotational_distances typing to np.ndarray.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
polyhedral_analysis/rotation_analyser.py Implements symmetry-analysis caching and the new two-phase discrete orientation algorithm; updates type annotation.
tests/test_rotation_analyser.py Adds functional tests covering correct reference detection, inverted reference, and perfect-geometry behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread polyhedral_analysis/rotation_analyser.py Outdated
Comment thread polyhedral_analysis/rotation_analyser.py
Comment thread polyhedral_analysis/rotation_analyser.py Outdated
Comment thread polyhedral_analysis/rotation_analyser.py Outdated
Comment thread polyhedral_analysis/rotation_analyser.py Outdated
bjmorgan added 4 commits March 2, 2026 07:12
Remove repeated feature description from intro paragraph and correct
"stereographic projection plotting" to "orientation distribution
plotting" (the plotting module uses a KDE contour plot, not a
stereographic projection).
- Track per-reference CSM so returned symmetry_measure matches the
  chosen reference geometry, not the global best.
- Fix docstring array shapes: Mx3xN -> MxNx3, 3xN -> Nx3, etc.
- Document that all reference orientations must share the same point
  group (symmetry analysis is performed once from the first).
- Simplify Phase 2 loop by storing per-reference best rotations in
  Phase 1.
- Validate coord_list_mapping produces a bijection
- Guard against empty proper_rotations array
- Use det > 0.5 tolerance for proper rotation filtering
- Fix list aliasing in best_rotation_per_ref initialisation
- Bundle lazy cache into single _symmetry_data tuple field
- Add PEP 8 blank line between OrientationDict and RotationAnalyser
- Add tests for _analyse_point_group outputs
- Add brute-force equivalence regression test
- Add tests for output shape, index consistency, input mutation
- Add known-rotation test
- Replace deprecated np.random.RandomState with default_rng
- Add Google-style docstring to polyhedron_orientation
- Validate points shape in discrete_orientation
- Add test for mismatched vertex count
@bjmorgan bjmorgan merged commit 2d720c7 into main Mar 2, 2026
6 checks passed
@bjmorgan bjmorgan deleted the optimise-rotation-analyser branch March 2, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants