Skip to content

Improve performance of graph automorphism via faster refinement and r…#38

Open
SebastianGitt wants to merge 1 commit intodwavesystems:mainfrom
SebastianGitt:main
Open

Improve performance of graph automorphism via faster refinement and r…#38
SebastianGitt wants to merge 1 commit intodwavesystems:mainfrom
SebastianGitt:main

Conversation

@SebastianGitt
Copy link
Contributor

…emoval of change_base()

  • uses an optimized colour refinement algorithm
  • more efficiently handles graphs with disjoint components
  • fixes issue where automorphisms could be missed if coset representatives could belong to multiple left transversals
  • supports canonical labelling
  • faster graph comparison using refinement trace
  • no longer relies on change_base() to perform pruning by automorphism
  • uses more efficient data structures
  • now returns mapping to original graph labelling
  • improves test coverage of edge cases

for u_i in self._u_vector:
for h in u_i:
f = mult(g, h)
if (f == self._identity).all():
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For large graphs this short-circuit takes longer to check than it ends up saving, hence its removal.

Copy link
Member

@randomir randomir left a comment

Choose a reason for hiding this comment

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

Looks good, just a few minor suggestions.

I'll defer the algorithm validation to @jackraymond.

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 98.33333% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.93%. Comparing base (2f81808) to head (7806d8c).
⚠️ Report is 32 commits behind head on main.

Files with missing lines Patch % Lines
...perimental/automorphism/automorphism_generation.py 98.33% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #38      +/-   ##
==========================================
+ Coverage   88.42%   93.93%   +5.51%     
==========================================
  Files          12       12              
  Lines         570      709     +139     
==========================================
+ Hits          504      666     +162     
+ Misses         66       43      -23     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why is github marking these files as changed? Shouldn't be touched, maybe a technicality?

Copy link
Contributor

@jackraymond jackraymond left a comment

Choose a reason for hiding this comment

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

Changes look good to me.

There is some issue with the file-comparison here. It marks almost all files as new, but I know only .

I've functionally tested this in the context of AutomorphismComposite with O(10) embeddings each of size 128 (periodic embedded cubic lattices) in Advantage2 and Advantage systems, seeing a significant jump in performance.

trace: The number of vertices belonging to each color, ordered by color.
color: A map from each vertex to its color.
num_colors: The number of unique colors, equivalent to the number
of cells in the partition.
Copy link
Contributor

Choose a reason for hiding this comment

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

indent.

Suggested change
of cells in the partition.
of cells in the partition.

@SebastianGitt SebastianGitt force-pushed the main branch 3 times, most recently from c56e1d9 to 401c050 Compare February 5, 2026 22:48
color class containing that vertex needs to be placed on the refinement
stack initially, since only colors adjacent to that color can be affected.

For performance reasons, `num_colors` is passed as a single-element list to
Copy link

Choose a reason for hiding this comment

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

Suggested change
For performance reasons, `num_colors` is passed as a single-element list to
For performance reasons, ``num_colors`` is passed as a single-element list to

stack initially, since only colors adjacent to that color can be affected.

For performance reasons, `num_colors` is passed as a single-element list to
`_split_up_color()` so that updates to the number of colors persist across
Copy link

Choose a reason for hiding this comment

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

Generally, I would try not to refer to hidden methods in docstrings, but this is also in a hidden method so not that important here. Still, I think it's better to update this reference.

in_refine_stack: bytearray,
num_colors: list[int],
) -> None:
"""A subroutine of ``_refine()`` that splits a color class into subcells
Copy link

Choose a reason for hiding this comment

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

Same here w.r.t. hidden method reference.

Comment on lines 458 to 463
self,
partition: list[set[int]],
trace: NDArray[np.integer],
color: NDArray[np.integer],
num_colors: int,
individualized_vertex: Optional[int] = None,
Copy link

Choose a reason for hiding this comment

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

Suggested change
self,
partition: list[set[int]],
trace: NDArray[np.integer],
color: NDArray[np.integer],
num_colors: int,
individualized_vertex: Optional[int] = None,
self,
partition: list[set[int]],
trace: NDArray[np.integer],
color: NDArray[np.integer],
num_colors: int,
individualized_vertex: Optional[int] = None,

Copy link

Choose a reason for hiding this comment

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

We can also start using int | None instead of Optional[int] if we'd like. IMO slightly cleaner, and I think we're leaning towards that elsewhere.

…e()``

- uses an optimized colour refinement algorithm
- more efficiently handles graphs with disjoint components
- fixes issue where automorphisms could be missed if coset representatives could belong to multiple left transversals
- supports canonical labelling
- faster graph comparison using refinement trace
- no longer relies on ``change_base()`` to perform pruning by automorphism
- uses more efficient data structures
- now returns mapping to original graph labelling
- improves test coverage of edge cases
- caches coset representative inverses
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.

5 participants