Skip to content

Commit

Permalink
Deprecate ps/pw.hamiltonian, pauli.simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
mudit2812 committed Oct 2, 2024
1 parent b3f9e38 commit ee7d0ad
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 10 deletions.
11 changes: 11 additions & 0 deletions doc/development/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ raise a deprecation warning when used:
- Deprecated in v0.39
- Will be removed in v0.40

* :meth:`~pennylane.pauli.PauliSentence.hamiltonian` and :meth:`~pennylane.pauli.PauliWord.hamiltonian` are deprecated. Instead, please use
:meth:`~pennylane.pauli.PauliSentence.operation` and :meth:`~pennylane.pauli.PauliWord.operation` respectively.

- Deprecated in v0.39
- Will be removed in v0.40

* :func:`pennylane.pauli.simplify` is deprecated. Instead, please use :func:`pennylane.simplify` or :meth:`~pennylane.operation.Operator.simplify`.

- Deprecated in v0.39
- Will be removed in v0.40

* ``op.ops`` and ``op.coeffs`` will be deprecated in the future. Use
:meth:`~.Operator.terms` instead.

Expand Down
7 changes: 7 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@
`qml.ops.LinearCombination`; this behaviour is not deprecated.
[(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287)

* `qml.pauli.PauliSentence.hamiltonian` and `qml.pauli.PauliWord.hamiltonian` are deprecated. Instead, please use
`qml.pauli.PauliSentence.operation` and `qml.pauli.PauliWord.operation` respectively.
[(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287)

* `qml.pauli.simplify()` is deprecated. Instead, please use `qml.simplify(op)` or `op.simplify()`.
[(#6287)](https://github.com/PennyLaneAI/pennylane/pull/6287)

* The `qml.BasisStatePreparation` template is deprecated.
Instead, use `qml.BasisState`.
[(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021)
Expand Down
31 changes: 28 additions & 3 deletions pennylane/pauli/pauli_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# pylint:disable=protected-access
from copy import copy
from functools import lru_cache, reduce
from warnings import warn

import numpy as np
from scipy import sparse
Expand Down Expand Up @@ -82,7 +83,7 @@ def _cached_sparse_data(op):
elif op == "Y":
data = np.array([-1.0j, 1.0j], dtype=np.complex128)
indices = np.array([1, 0], dtype=np.int64)
elif op == "Z":
else: # op == "Z"
data = np.array([1.0, -1.0], dtype=np.complex128)
indices = np.array([0, 1], dtype=np.int64)
return data, indices
Expand Down Expand Up @@ -518,7 +519,19 @@ def operation(self, wire_order=None, get_as_tensor=False):
return factors[0] if len(factors) == 1 else Prod(*factors, _pauli_rep=pauli_rep)

def hamiltonian(self, wire_order=None):
"""Return :class:`~pennylane.Hamiltonian` representing the PauliWord."""
"""Return :class:`~pennylane.Hamiltonian` representing the PauliWord.
.. warning::
:meth:`~pennylane.pauli.PauliWord.hamiltonian` is deprecated. Instead, please use
:meth:`~pennylane.pauli.PauliWord.operation`
"""
warn(
"PauliWord.hamiltonian() is deprecated. Please use PauliWord.operation() instead.",
qml.PennyLaneDeprecationWarning,
)

if len(self) == 0:
if wire_order in (None, [], Wires([])):
raise ValueError("Can't get the Hamiltonian for an empty PauliWord.")
Expand Down Expand Up @@ -1022,7 +1035,19 @@ def operation(self, wire_order=None):
return summands[0] if len(summands) == 1 else Sum(*summands, _pauli_rep=self)

def hamiltonian(self, wire_order=None):
"""Returns a native PennyLane :class:`~pennylane.Hamiltonian` representing the PauliSentence."""
"""Returns a native PennyLane :class:`~pennylane.Hamiltonian` representing the PauliSentence.
.. warning::
:meth:`~pennylane.pauli.PauliSentence.hamiltonian` is deprecated. Instead, please use
:meth:`~pennylane.pauli.PauliSentence.operation`
"""
warn(
"PauliSentence.hamiltonian() is deprecated. Please use PauliSentence.operation() instead.",
qml.PennyLaneDeprecationWarning,
)

if len(self) == 0:
if wire_order in (None, [], Wires([])):
raise ValueError("Can't get the Hamiltonian for an empty PauliSentence.")
Expand Down
11 changes: 11 additions & 0 deletions pennylane/pauli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from functools import lru_cache, singledispatch
from itertools import product
from typing import Union
from warnings import warn

import numpy as np

Expand Down Expand Up @@ -1211,6 +1212,11 @@ def simplify(h, cutoff=1.0e-12):
The Hamiltonian terms with identical Pauli words are added together and eliminated if the
overall coefficient is smaller than a cutoff value.
.. warning::
:func:`~pennylane.pauli.simplify` is deprecated. Instead, please use :func:`pennylane.simplify`
or :meth:`~pennylane.operation.Operator.simplify`.
Args:
h (Hamiltonian): PennyLane Hamiltonian
cutoff (float): cutoff value for discarding the negligible terms
Expand All @@ -1225,6 +1231,11 @@ def simplify(h, cutoff=1.0e-12):
>>> print(simplify(h))
(1.0) [X0 Y1]
"""
warn(
"qml.pauli.simplify() has been deprecated. Instead, please use "
"qml.simplify(op) or op.simplify().",
qml.PennyLaneDeprecationWarning,
)
wiremap = dict(zip(h.wires, range(len(h.wires) + 1)))

c, o = [], []
Expand Down
4 changes: 2 additions & 2 deletions pennylane/transforms/decompositions/clifford_t_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ def pauli_group(x):
qml.pauli.pauli_sentence(qml.prod(*pauli))
for pauli in product(*(pauli_group(idx) for idx in op.wires))
]
pauli_hams = (pauli_sen.hamiltonian(wire_order=op.wires) for pauli_sen in pauli_sens)
pauli_ops = (pauli_sen.operation(wire_order=op.wires) for pauli_sen in pauli_sens)

# Perform U@P@U^\dagger and check if the result exists in set P
for pauli_prod in product([pauli_terms], pauli_hams, [pauli_terms_adj]):
for pauli_prod in product([pauli_terms], pauli_ops, [pauli_terms_adj]):
# hopefully op_math.prod scales better than matrix multiplication, i.e., O((2^N)^3)
upu = qml.pauli.pauli_sentence(qml.prod(*pauli_prod))
upu.simplify()
Expand Down
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ def disable_opmath_if_requested(request):
# don't raise deprecation warnings
filterwarnings("ignore", "qml.ops.Hamiltonian", qml.PennyLaneDeprecationWarning)
filterwarnings("ignore", "qml.operation.Tensor", qml.PennyLaneDeprecationWarning)
filterwarnings("ignore", "qml.pauli.simplify", qml.PennyLaneDeprecationWarning)
filterwarnings("ignore", "PauliSentence.hamiltonian", qml.PennyLaneDeprecationWarning)
filterwarnings("ignore", "PauliWord.hamiltonian", qml.PennyLaneDeprecationWarning)


@pytest.fixture(params=[disable_new_opmath_cm, enable_new_opmath_cm], scope="function")
Expand Down
18 changes: 16 additions & 2 deletions tests/pauli/test_pauli_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,11 @@ def test_hamiltonian_empty_error(self):
with pytest.raises(ValueError, match="Can't get the Hamiltonian for an empty PauliWord."):
pw4.hamiltonian()

def test_hamiltonian_deprecation(self):
"""Test that the correct deprecation warning is raised when calling hamiltonian()"""
with pytest.warns(qml.PennyLaneDeprecationWarning, match="PauliWord.hamiltonian"):
_ = pw1.hamiltonian()

def test_pickling(self):
"""Check that pauliwords can be pickled and unpickled."""
pw = PauliWord({2: "X", 3: "Y", 4: "Z"})
Expand Down Expand Up @@ -1071,6 +1076,11 @@ def test_hamiltonian_wire_order(self):

qml.assert_equal(op, id)

def test_hamiltonian_deprecation(self):
"""Test that the correct deprecation warning is raised when calling hamiltonian()"""
with pytest.warns(qml.PennyLaneDeprecationWarning, match="PauliSentence.hamiltonian"):
_ = ps1.hamiltonian()

def test_pickling(self):
"""Check that paulisentences can be pickled and unpickled."""
word1 = PauliWord({2: "X", 3: "Y", 4: "Z"})
Expand Down Expand Up @@ -1416,7 +1426,9 @@ def test_pauli_word_private_commutator(self, op1, op2, true_word, true_coeff):
@pytest.mark.parametrize("convert1", [_id, _pw_to_ps])
@pytest.mark.parametrize("convert2", [_id, _pw_to_ps])
@pytest.mark.parametrize("op1, op2, true_res", data_pauli_relations_different_types)
def test_pauli_word_comm_different_types(self, op1, op2, true_res, convert1, convert2):
def test_pauli_word_comm_different_types(
self, op1, op2, true_res, convert1, convert2
): # pylint: disable=too-many-positional-arguments
"""Test native comm in between a PauliSentence and either of PauliWord, PauliSentence, Operator"""
op1 = convert1(op1)
op2 = convert2(op2)
Expand All @@ -1429,7 +1441,9 @@ def test_pauli_word_comm_different_types(self, op1, op2, true_res, convert1, con
@pytest.mark.parametrize("convert1", [_id, _pw_to_ps])
@pytest.mark.parametrize("convert2", [_pauli_to_op])
@pytest.mark.parametrize("op1, op2, true_res", data_pauli_relations_different_types)
def test_pauli_word_comm_different_types_with_ops(self, op1, op2, true_res, convert1, convert2):
def test_pauli_word_comm_different_types_with_ops(
self, op1, op2, true_res, convert1, convert2
): # pylint: disable=too-many-positional-arguments
"""Test native comm in between a PauliWord, PauliSentence and Operator"""
op1 = convert1(op1)
op2 = convert2(op2)
Expand Down
10 changes: 9 additions & 1 deletion tests/pauli/test_pauli_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,6 @@ def test_diagonalize_qwc_pauli_words_catch_invalid_type(self):
_ = diagonalize_qwc_pauli_words(invalid_ops)


@pytest.mark.usefixtures("legacy_opmath_only")
class TestObservableHF:

HAMILTONIAN_SIMPLIFY = [
Expand Down Expand Up @@ -1044,12 +1043,21 @@ class TestObservableHF:
),
]

@pytest.mark.usefixtures("legacy_opmath_only")
@pytest.mark.parametrize(("hamiltonian", "result"), HAMILTONIAN_SIMPLIFY)
def test_simplify(self, hamiltonian, result):
r"""Test that simplify returns the correct hamiltonian."""
h = simplify(hamiltonian)
assert h.compare(result)

def test_simplify_deprecation(self):
"""Test that a deprecation warning is raised when using simplify"""
with pytest.warns(qml.PennyLaneDeprecationWarning, match="qml.ops.Hamiltonian"):
h = qml.ops.Hamiltonian([1.5, 2.5], [qml.X(0), qml.Z(0)])

with pytest.warns(qml.PennyLaneDeprecationWarning, match="qml.pauli.simplify"):
_ = simplify(h)


@pytest.mark.usefixtures("legacy_opmath_only")
class TestTapering:
Expand Down
7 changes: 5 additions & 2 deletions tests/pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ filterwarnings =
ignore:Call to deprecated create function:DeprecationWarning
ignore:the imp module is deprecated:DeprecationWarning
error::pennylane.PennyLaneDeprecationWarning
ignore:qml.ops.Hamiltonian uses the old approach:pennylane.PennyLaneDeprecationWarning
ignore:qml.operation.Tensor uses the old approach:pennylane.PennyLaneDeprecationWarning
; ignore:qml.ops.Hamiltonian uses the old approach:pennylane.PennyLaneDeprecationWarning
; ignore:qml.operation.Tensor uses the old approach:pennylane.PennyLaneDeprecationWarning
; ignore:qml.pauli.simplify:pennylane.PennyLaneDeprecationWarning
; ignore:PauliSentence.hamiltonian:pennylane.PennyLaneDeprecationWarning
; ignore:PauliWord.hamiltonian:pennylane.PennyLaneDeprecationWarning
addopts = --benchmark-disable
xfail_strict=true

0 comments on commit ee7d0ad

Please sign in to comment.