Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to lie_closure #6023

Merged
merged 22 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@
* `qml.AmplitudeEmbedding` has better support for features using low precision integer data types.
[(#5969)](https://github.com/PennyLaneAI/pennylane/pull/5969)

* `qml.lie_closure` works with sums of Paulis.
[(#6023)](https://github.com/PennyLaneAI/pennylane/pull/6023)


<h3>Contributors ✍️</h3>

Expand All @@ -160,6 +163,7 @@ Pietropaolo Frisoni,
Emiliano Godinez,
Renke Huang,
Soran Jahangiri,
Korbinian Kottmann,
Christina Lee,
Austin Huang,
Christina Lee,
Expand Down
8 changes: 8 additions & 0 deletions pennylane/pauli/dla/lie_closure.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""A function to compute the Lie closure of a set of operators"""
# pylint: disable=too-many-arguments
import itertools
import warnings
from copy import copy
from functools import reduce
from typing import Iterable, Union
Expand Down Expand Up @@ -134,22 +135,29 @@ def lie_closure(
while (new_length > old_length) and (epoch < max_iterations):
if verbose:
print(f"epoch {epoch+1} of lie_closure, DLA size is {new_length}")

for ps1, ps2 in itertools.combinations(vspace.basis, 2):
com = ps1.commutator(ps2)
com.simplify()
Qottmann marked this conversation as resolved.
Show resolved Hide resolved

if len(com) == 0: # skip because operators commute
continue

# result is always purely imaginary
# remove common factor 2 with Pauli commutators
for pw, val in com.items():
com[pw] = val.imag / 2

vspace.add(com, tol=tol)

# Updated number of linearly independent PauliSentences from previous and current step
old_length = new_length
new_length = len(vspace)
epoch += 1

if epoch == max_iterations:
warnings.warn(f"reached the maximum number of iterations {max_iterations}", UserWarning)
Qottmann marked this conversation as resolved.
Show resolved Hide resolved

trbromley marked this conversation as resolved.
Show resolved Hide resolved
if verbose > 0:
print(f"After {epoch} epochs, reached a DLA size of {new_length}")

Expand Down
15 changes: 14 additions & 1 deletion tests/pauli/dla/test_lie_closure.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ def test_max_iterations(self, capsys):
PauliSentence({PauliWord({i: "X", (i + 1) % n: "Z"}): 1.0}) for i in range(n - 1)
]

res = qml.pauli.lie_closure(generators, verbose=True, max_iterations=1)
with pytest.warns(UserWarning, match="reached the maximum number of iterations"):
res = qml.pauli.lie_closure(generators, verbose=True, max_iterations=1)

captured = capsys.readouterr()
assert (
captured.out
Expand Down Expand Up @@ -501,6 +503,17 @@ def test_lie_closure_heisenberg_generators_even(self):
res = qml.pauli.lie_closure(generators)
assert len(res) == 4 * ((2 ** (n - 2)) ** 2 - 1)

@pytest.mark.parametrize("n, res", [(3, 4), (4, 12)])
def test_lie_closure_heisenberg(self, n, res):
"""Test the resulting DLA from Heisenberg model with summed generators"""
Qottmann marked this conversation as resolved.
Show resolved Hide resolved
genXX = [X(i) @ X(i + 1) for i in range(n - 1)]
genYY = [Y(i) @ Y(i + 1) for i in range(n - 1)]
genZZ = [Z(i) @ Z(i + 1) for i in range(n - 1)]

generators = [qml.sum(XX + YY + ZZ) for XX, YY, ZZ in zip(genXX, genYY, genZZ)]
g = qml.lie_closure(generators)
assert len(g) == res

def test_universal_gate_set(self):
"""Test universal gate set"""
n = 3
Expand Down
Loading