Skip to content

added Fermionic and Jordan-Wigner MPO encodings of 1D Fermi-Hubbard model#220

Merged
aaronleesander merged 22 commits into
munich-quantum-toolkit:mainfrom
thilomueller:1D_Fermi_Hubbard_MPO
May 15, 2026
Merged

added Fermionic and Jordan-Wigner MPO encodings of 1D Fermi-Hubbard model#220
aaronleesander merged 22 commits into
munich-quantum-toolkit:mainfrom
thilomueller:1D_Fermi_Hubbard_MPO

Conversation

@thilomueller
Copy link
Copy Markdown
Contributor

@thilomueller thilomueller commented Oct 16, 2025

Description

Implementation of a MPO construction for the one-dimensional Fermi-Hubbard model both in the fermionic space and in the qubit space after applying the Jordan-Wigner transformation.

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • [ x] I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

@codecov
Copy link
Copy Markdown

codecov Bot commented Oct 16, 2025

Codecov Report

❌ Patch coverage is 95.52239% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/mqt/yaqs/core/data_structures/networks.py 95.5% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@denialhaag denialhaag added the feature New feature or request label Nov 5, 2025
@aaronleesander aaronleesander self-requested a review May 15, 2026 11:50
@aaronleesander aaronleesander marked this pull request as ready for review May 15, 2026 11:51
@aaronleesander aaronleesander changed the title 1D Fermi-Hubbard MPO added Fermionic and Jordan-Wigner MPO encodings of 1D Fermi-Hubbard model May 15, 2026
@aaronleesander
Copy link
Copy Markdown
Member

@CodeRabbit full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added MPO.fermi_hubbard_1d() method to construct 1D Fermi–Hubbard Hamiltonians as matrix product operators in fermionic and Jordan–Wigner representations.
  • Documentation

    • Added example demonstrating Fermi–Hubbard MPO construction with runnable code and parameter descriptions.
  • Chores

    • Updated pre-commit hook configuration.

Walkthrough

This PR adds MPO.fermi_hubbard_1d() with fermionic and Jordan–Wigner builders, validates boundary-slicing for length==1, adds dense-reference tests covering both representations (including length=1 and cross-checks), adds a MyST-NB example and toctree entry, updates CHANGELOG, and changes the local pre-commit ty-check hook language to system.

Changes

Fermi-Hubbard MPO Feature

Layer / File(s) Summary
Core MPO factory & internal builders
src/mqt/yaqs/core/data_structures/networks.py
Public MPO.fermi_hubbard_1d(length, t, u, *, jordan_wigner=False) with input validation dispatches to _fermi_hubbard_1d_fermionic() (creation/annihilation, hopping, interaction channels, boundary slicing including length==1, and MPO validation) or _fermi_hubbard_1d_jordan_wigner() (Pauli-string assembly via from_pauli_sum).
Tests and dense reference builders
tests/core/data_structures/test_networks.py
Adds _embed_local_ops(), _fermi_hubbard_1d_fermionic_dense(), _fermi_hubbard_1d_jordan_wigner_dense() and tests verifying MPO metadata, bond-dimension bounds, dense-matrix equivalence, JW input validation, length=1 fermionic case, and cross-representation interaction checks.
Documentation example, index, and changelog
docs/examples/fermi_hubbard_mpo.md, docs/index.md, CHANGELOG.md
New MyST-NB example demonstrating both MPO representations with runnable code and MPO diagnostics; docs toctree updated to include the example; CHANGELOG updated with new MPO encodings and a minor formatting fix.
Pre-commit hook language update
.pre-commit-config.yaml
Local ty-check hook language changed from unsupported to system.

Sequence Diagram

sequenceDiagram
  participant Client
  participant MPO_factory as MPO.fermi_hubbard_1d
  participant FermionicBuilder as _fermi_hubbard_1d_fermionic
  participant JWBuilder as _fermi_hubbard_1d_jordan_wigner
  participant Validator as check_if_valid_mpo

  Client->>MPO_factory: call(length, t, u, jordan_wigner)
  MPO_factory->>MPO_factory: validate inputs (length / even check for JW)
  alt jordan_wigner == False
    MPO_factory->>FermionicBuilder: build fermionic MPO tensors
    FermionicBuilder->>Validator: check_if_valid_mpo(MPO)
    Validator-->>FermionicBuilder: valid/raise
  else jordan_wigner == True
    MPO_factory->>JWBuilder: build JW Pauli-string MPO via from_pauli_sum
  end
  MPO_factory-->>Client: return MPO
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

python

Suggested reviewers

  • aaronleesander

Poem

A Fermi dance, in tensors spun,
Jordan–Wigner threads the chain as one,
Hops and interactions softly play,
MPOs hum through night and day—🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description addresses the main change but is incomplete according to the template requirements. Add a summary section explaining the change and its motivation, include issue reference if applicable, document dependencies, and properly format the checklist with all items as specified in the template.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately and specifically describes the main change: adding Fermionic and Jordan-Wigner MPO encodings of the 1D Fermi-Hubbard model.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/examples/fermi_hubbard_mpo.md (1)

41-58: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider adding a trailing newline at end of file.

Most text files conventionally end with a newline character. While not critical, adding one would align with common style practices.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/examples/fermi_hubbard_mpo.md` around lines 41 - 58, Add a single
trailing newline character to the end of the Markdown file so it ends with a
newline (update docs/examples/fermi_hubbard_mpo.md); no content changes
needed—just ensure the file terminates with a newline after the final paragraph
referencing MPO.fermi_hubbard_1d and create_1d_fermi_hubbard_circuit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mqt/yaqs/core/data_structures/networks.py`:
- Around line 1559-1567: The outer method redundantly checks "length < 1" before
calling cls._fermi_hubbard_1d_fermionic, duplicating validation already done
inside that helper; remove the redundant block (the "if length < 1: ... raise
ValueError" and its message) so the public method only validates the
Jordan-Wigner-specific even/≥2 case and then delegates to
_fermi_hubbard_1d_fermionic (preserving that helper’s own length validation),
leaving _fermi_hubbard_1d_jordan_wigner and _fermi_hubbard_1d_fermionic as the
single sources of truth for input checks.
- Around line 1521-1558: The JW branch of fermi_hubbard_1d currently builds only
the (U/4) Z_up Z_down on each site and omits the constant and single-Z
chemical-potential pieces, so the JW MPO is not algebraically equivalent to U
n_up n_down; update the jordan_wigner=True construction in fermi_hubbard_1d to
expand U n_up n_down = (U/4)(I - Z_up - Z_down + Z_up Z_down) by adding per-site
(U/4)*I and single-site (-U/4)*Z_up and (-U/4)*Z_down terms alongside the
existing (U/4)*Z_up Z_down term (ensure the sign and prefactors match), and
adjust how those local operator terms are inserted into the MPO tensors so the
JW and non-JW branches represent the same Hamiltonian up to the JW mapping.
- Around line 1604-1613: The code creates tensors via a fresh transpose for
tensors[0] and tensors[-1], causing an overwrite when length == 1 and producing
incompatible leg shapes for to_matrix(); fix by reusing the already-transposed
slot and applying the left and right slices on the same array instead of
re-transposing: after building tensors (the list comp using tensor and
np.transpose), mutate tensors[0] in-place (e.g. tensors[0] =
tensors[0][:,:,0:1,:].astype(np.complex128)) and tensors[-1] =
tensors[-1][:,:,:,5:6].astype(np.complex128), and handle the length == 1 case by
chaining both slices on tensors[0] so it ends up with the correct
(bond,left,right) shapes; apply the same change in the bose_hubbard builder;
keep check_if_valid_mpo() and to_matrix() behavior unchanged.
- Around line 1575-1602: The builder labeled "fermionic" actually implements
two-species hardcore bosons because c_up/c_down lack Jordan-Wigner Z-strings;
fix by either (A) implementing proper JW signs: modify c_down and c_down_dag to
include the parity-string (Z) factor so {c_up,c_down}=0 (adjust the
onsite/tensor entries using c_up, c_down, c_up_dag, c_down_dag accordingly), or
(B) update the function/docstring for the fermi_hubbard builder (and the dense
reference _fermi_hubbard_1d_fermionic_dense) to state this is a non-JW
hardcore-boson convention and recommend using jordan_wigner=True for true
fermions; ensure tests reflect the chosen behavior.
- Around line 1521-1543: The raw docstring for the 1D Fermi-Hubbard MPO (the
r""" docstring in the function that constructs the Hamiltonian MPO) contains
doubled backslashes (e.g. \\rangle, \\sum, \\dagger, \\uparrow) which produces
literal double backslashes in Sphinx; either remove the leading r from the
docstring and keep the doubled backslashes, or keep the r prefix and change all
doubled backslashes to single backslashes (e.g. \rangle, \sum, \dagger,
\uparrow) so :math: directives render correctly; apply the same fix in
tests/core/data_structures/test_networks.py lines ~296–298 where the doubled
escapes appear.

In `@tests/core/data_structures/test_networks.py`:
- Around line 521-553: Add tests to cover the single-site fermionic case and the
fermion↔JW cross-representation equivalence: create a test named e.g.
test_fermi_hubbard_1d_length_one that calls MPO.fermi_hubbard_1d(1, t, u) and
compares mpo.to_matrix() to _fermi_hubbard_1d_fermionic_dense(1, t, u) with
np.testing.assert_allclose, and add a test (e.g.
test_fermi_hubbard_1d_cross_representation) that for small L compares
MPO.fermi_hubbard_1d(L, t, u).to_matrix() to MPO.fermi_hubbard_1d(2*L, t, u,
jordan_wigner=True).to_matrix() under the 4↔pair-of-qubits isomorphism (use the
existing dense builders _fermi_hubbard_1d_fermionic_dense and
_fermi_hubbard_1d_jordan_wigner_dense or compare via appropriate basis
reshaping) to catch the on-site U-term mismatch noted in networks.py.
- Around line 292-336: The test's dense reference
(_fermi_hubbard_1d_fermionic_dense) is recreating the same on-site tensor
construction as the MPO (c_up = kron(c,I), c_down = kron(I,c)) and therefore
cannot detect a missing Jordan–Wigner (JW) string in the MPO; replace the
reference construction with an independent JW-based one: build a length*2 chain
of spinless fermion creation/annihilation operators (single-qubit c, c_dag) with
proper JW Z-strings between them to implement fermionic anticommutation,
assemble the full 2^(2*L) dense Hamiltonian on the interleaved chain, then
group/site-pair the interleaved sites into local dimension-4 sites by
reshaping/partial tensoring to get a (4**L,4**L) matrix and compare that to
MPO.fermi_hubbard_1d (or to the current _fermi_hubbard_1d_fermionic_dense) via
unitary equivalence or norm difference; ensure the independent construction
references the single-site c/c_dag (not c_up/c_down) and explicitly includes JW
Z-strings so the test fails if the MPO omits them.

---

Outside diff comments:
In `@docs/examples/fermi_hubbard_mpo.md`:
- Around line 41-58: Add a single trailing newline character to the end of the
Markdown file so it ends with a newline (update
docs/examples/fermi_hubbard_mpo.md); no content changes needed—just ensure the
file terminates with a newline after the final paragraph referencing
MPO.fermi_hubbard_1d and create_1d_fermi_hubbard_circuit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 46ff4f13-969b-460e-a59b-e9c1cb4a9b8d

📥 Commits

Reviewing files that changed from the base of the PR and between cd2e050 and 61433ca.

📒 Files selected for processing (6)
  • .pre-commit-config.yaml
  • CHANGELOG.md
  • docs/examples/fermi_hubbard_mpo.md
  • docs/index.md
  • src/mqt/yaqs/core/data_structures/networks.py
  • tests/core/data_structures/test_networks.py

Comment thread src/mqt/yaqs/core/data_structures/networks.py
Comment thread src/mqt/yaqs/core/data_structures/networks.py
Comment thread src/mqt/yaqs/core/data_structures/networks.py
Comment thread src/mqt/yaqs/core/data_structures/networks.py
Comment thread src/mqt/yaqs/core/data_structures/networks.py
Comment thread tests/core/data_structures/test_networks.py
Comment thread tests/core/data_structures/test_networks.py
@aaronleesander
Copy link
Copy Markdown
Member

@CodeRabbit full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.pre-commit-config.yaml:
- Line 128: The pre-commit hook's language key was changed to "system" which is
not a recognized pre-commit language; revert the value for the YAML key
"language" from "system" back to "unsupported" (or document why "system" is
required) so the hook uses the supported "unsupported" language type; look for
the occurrence of the "language:" key with value "system" and update it to
"unsupported" (or add a comment explaining the deliberate deviation).

In `@CHANGELOG.md`:
- Around line 14-15: Add a missing PR reference definition for the tag [`#220`]
used in CHANGELOG.md: locate the PR links/references section in CHANGELOG.md and
add a reference entry for [`#220`] with the correct URL and optional author
attribution so the changelog link resolves (the tag to add is "[`#220`]" that
matches the entry "- added Fermionic and Jordan-Wigner MPO encodings...").
Ensure the reference uses the same markdown link style as the other PR
definitions in the file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 921633e6-af85-41a9-bf89-cdffc780b41d

📥 Commits

Reviewing files that changed from the base of the PR and between cd2e050 and f31733c.

📒 Files selected for processing (6)
  • .pre-commit-config.yaml
  • CHANGELOG.md
  • docs/examples/fermi_hubbard_mpo.md
  • docs/index.md
  • src/mqt/yaqs/core/data_structures/networks.py
  • tests/core/data_structures/test_networks.py

Comment thread .pre-commit-config.yaml Outdated
Comment thread CHANGELOG.md
@aaronleesander aaronleesander enabled auto-merge May 15, 2026 14:12
@aaronleesander aaronleesander merged commit 94994dc into munich-quantum-toolkit:main May 15, 2026
21 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants