Skip to content

A slightly more specific alternative: Fix Pauli ordering return type and Y-branch handling#34

Open
AlbertLee125 wants to merge 14 commits into
mainfrom
improve_ordering
Open

A slightly more specific alternative: Fix Pauli ordering return type and Y-branch handling#34
AlbertLee125 wants to merge 14 commits into
mainfrom
improve_ordering

Conversation

@AlbertLee125

Copy link
Copy Markdown
Collaborator

Summary

This PR stabilizes analysis/ordering.py by making reorder_paulis behave consistently across the default and empty-input paths, and by fixing a typo in the group_evolve_xyz ordering method.

The changes are intentionally small and focused. They repair the current ordering behavior without redesigning the broader Pauli-term representation.

What changed

 def reorder_paulis(pauli_strings, ordering_method):
+    """
+    Reorder Pauli-string terms for Trotterized time evolution.
+
+    The input is expected to be a mapping from dense Pauli strings to
+    coefficients. The returned dictionary contains the same Pauli terms and
+    coefficients, but inserted in the order selected by ordering_method.
+
+    If ordering_method is None, the original input order is preserved.
+    """

     pauli_string_list = list(pauli_strings.items())

+    # Nothing to reorder; return an empty mapping so callers can still use .items().
+    if not pauli_string_list:
+        return {}
+
     if not isinstance(pauli_string_list[0][0], str):
         raise Exception(
             "This method currently only accepts pauli strings written in "
             "'string' format (e.g. XIIYZIX)"
         )

-    if ordering_method == None:
-        return pauli_string_list
+    if ordering_method is None:
+        return dict(pauli_string_list)
-    elif pauli_types == "Y":
+    elif pauli_type == "Y":
         Ys.append(term)

Why

reorder_paulis is used before building the Trotterized unitary. The caller expects the returned object to support .items(), so the default None ordering path should preserve the original Pauli-term order while still returning a dictionary.

This PR fixes three small issues:

  1. The default None ordering path returned a list, while the other ordering methods returned dictionaries.
  2. Empty Pauli input could reach pauli_string_list[0][0] and fail with an unclear IndexError.
  3. The group_evolve_xyz Y branch compared pauli_types, a set, against the string "Y" instead of comparing pauli_type.

Tests

Didn't add the test file yet but will add it later.

Scope

This PR does not fully resolve the broader TODO in ordering.py about Pauli-term representation, generator/list design, or tuple-format support. It only stabilizes the current dictionary-based behavior so future Trotter-ordering methods can be added more safely.

Copilot AI review requested due to automatic review settings June 17, 2026 16:10
@AlbertLee125 AlbertLee125 requested a review from reuben-tate June 17, 2026 16:11

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 aims to stabilize Pauli-term ordering for Trotterized time evolution by making reorder_paulis return a consistent mapping type (including for ordering_method=None and empty input) and fixing the Y-branch selection logic in group_evolve_xyz.

Changes:

  • Added a docstring and an empty-input fast path to reorder_paulis to avoid IndexError and ensure callers can always use .items().
  • Changed the ordering_method=None path to return a dict (preserving insertion order).
  • Fixed a typo in group_evolve_xyz so the Y-branch checks pauli_type rather than pauli_types.

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

Comment thread analysis/ordering.py
Comment thread analysis/ordering.py Outdated
Comment thread analysis/ordering.py Outdated
Comment thread analysis/ordering.py
@AlbertLee125

Copy link
Copy Markdown
Collaborator Author

Added ordering.py tests

I added a dedicated test file for analysis/ordering.py:

analysis/tests/test_ordering.py

The tests cover the small stabilization changes made to reorder_paulis and group_evolve_xyz:

  1. Default ordering with ordering_method=None preserves the input Pauli-term order and returns a dictionary.
  2. Empty Pauli-string input returns an empty dictionary instead of indexing into an empty list.
  3. group_evolve_xyz correctly handles Y-only Pauli terms.
  4. group_evolve_xyz still rejects mixed Pauli terms, such as terms containing X, Y, and Z together.

I verified the new tests locally with:

python -m pytest analysis/tests/test_ordering.py -q

The results was given as 4 passed.

Comment thread analysis/ordering.py

if ordering_method == None:
return pauli_string_list
if ordering_method is None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe I've just forgotten some of the details here, but this is specifically talking about ordering terms, but then the comments say that the return type should be a dictionary which is unordered? Or maybe dictionaries are ordered and I'm remembering outdated information or a different language?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good point. In older Python versions, dictionaries were commonly treated as unordered, but in Python 3.7+ insertion order is guaranteed. Since QHAT uses Python 3.11, returning dict(pauli_string_list) preserves the selected Pauli-term order while keeping the return type compatible with downstream code that calls .items().

Comment thread analysis/ordering.py Outdated
pauli_string = term[0]
pauli_types = set(pauli_string) #throw out duplicates to see which pauli types exist (I, X, Y, Z)
pauli_types.discard("I") #throw out the identity I if it exists in the string
pauli_types = set(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You have a lot of reformatting mixed in with actual changes. Generally you don't change formatting at the same time as you change functionality (unless it's a line you're editing anyway as part of changing the functionality). It's much better to push formatting changes to its own merge request, to make it easier to review merge requests.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I have a question, I did Python Black Formatting. So, is there a formatting rule that I need to be aware of?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

On other projects I've pushed for automated formatting, but on this project I'm trying to keep process pretty minimal. You're welcome to run a formatting tool if you like (I don't have enough experience with Python to pick the "best" formatting tool or options), just run it as a separate merge request.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I restored the original formatting.

@AlbertLee125

Copy link
Copy Markdown
Collaborator Author

I ran driver.py with the Be-H example using four ordering methods: None, magnitude, lexicographical, and group_evolve_xyz. The runs with None, magnitude, and lexicographical completed successfully. The run with group_evolve_xyz did not complete for the Be-H example and raised an error on the Pauli string XZXIII. So from these driver runs, the ordering changes look good for None, magnitude, and lexicographical. For group_evolve_xyz, I saw that it does not run with this Be-H input, so I wanted to note that separately rather than treating it as part of the successful cases.

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.

3 participants