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

Add H as an alias for Hadamard operator #6450

Merged
merged 14 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -189,6 +189,9 @@

<h4>Other Improvements</h4>

* Added `qml.H` as an alias for the Hadamard operator.
[(#6450)](https://github.com/PennyLaneAI/pennylane/pull/6450)

* Added `show_wire_labels` option to `draw` and `draw_mpl`, which hides wire labels when set to `False`.
Defaults to `True`.
[(#6410)](https://github.com/PennyLaneAI/pennylane/pull/6410)
Expand Down Expand Up @@ -496,5 +499,6 @@ Erick Ochoa Lopez,
Lee J. O'Riordan,
Mudit Pandey,
Andrija Paurevic,
Alex Preciado,
Ashish Kanwar Singh,
David Wierichs,
2 changes: 2 additions & 0 deletions pennylane/devices/tests/test_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"CH": qml.CH(wires=[0, 1]),
"DiagonalQubitUnitary": qml.DiagonalQubitUnitary(np.array([1, 1]), wires=[0]),
"Hadamard": qml.Hadamard(wires=[0]),
"H": qml.H(wires=[0]),
"MultiRZ": qml.MultiRZ(0, wires=[0]),
"PauliX": qml.X(0),
"PauliY": qml.Y(0),
Expand Down Expand Up @@ -281,6 +282,7 @@ def adjoint_tuple(op, orig_mat):
(qml.Y, Y),
(qml.Z, Z),
(qml.Hadamard, H),
(qml.H, H),
(qml.S, S),
(qml.T, T),
(qml.SX, SX),
Expand Down
1 change: 1 addition & 0 deletions pennylane/devices/tests/test_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
obs = {
"Identity": qml.Identity(wires=[0]),
"Hadamard": qml.Hadamard(wires=[0]),
"H": qml.H(wires=[0]),
"Hermitian": qml.Hermitian(np.eye(2), wires=[0]),
"PauliX": qml.PauliX(0),
"PauliY": qml.PauliY(0),
Expand Down
2 changes: 2 additions & 0 deletions pennylane/ops/qubit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"Identity",
"Snapshot",
"Hadamard",
"H",
"PauliX",
"X",
"PauliY",
Expand Down Expand Up @@ -106,6 +107,7 @@

__obs__ = {
"Hadamard",
"H",
"PauliX",
"X",
"PauliY",
Expand Down
31 changes: 31 additions & 0 deletions pennylane/ops/qubit/non_parametric_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class Hadamard(Observable, Operation):

.. math:: H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1\\ 1 & -1\end{bmatrix}.

.. seealso:: The equivalent short-form alias :class:`~H`

**Details:**

* Number of wires: 1
Expand All @@ -64,6 +66,17 @@ def label(
) -> str:
return base_label or "H"

def __repr__(self) -> str:
"""String representation."""
wire = self.wires[0]
if isinstance(wire, str):
return f"H('{wire}')"
return f"H({wire})"

@property
def name(self) -> str:
return "Hadamard"

@staticmethod
@lru_cache()
def compute_matrix() -> np.ndarray: # pylint: disable=arguments-differ
Expand Down Expand Up @@ -182,6 +195,24 @@ def pow(self, z: Union[int, float]):
return super().pow(z % 2)


H = Hadamard
r"""H(wires)
The Hadamard operator

.. math:: H = \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1\\ 1 & -1\end{bmatrix}.

.. seealso:: The equivalent long-form alias :class:`~Hadamard`

**Details:**

* Number of wires: 1
* Number of parameters: 0

Args:
wires (Sequence[int] or int): the wire the operation acts on
"""


class PauliX(Observable, Operation):
r"""
The Pauli X operator
Expand Down
2 changes: 1 addition & 1 deletion tests/circuit_graph/test_circuit_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def test_print_contents(self):
circuit_w_wires.print_contents()
out = f.getvalue().strip()

expected = """Operations\n==========\nHadamard(wires=[0])\nCNOT(wires=[0, 1])\n\nObservables\n===========\nsample(wires=[0, 1, 2])"""
expected = """Operations\n==========\nH(0)\nCNOT(wires=[0, 1])\n\nObservables\n===========\nsample(wires=[0, 1, 2])"""
assert out == expected

tape_depth = (
Expand Down
2 changes: 1 addition & 1 deletion tests/ops/op_math/test_composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
)

ops_rep = (
"X(0) # Z(0) # Hadamard(wires=[0])",
"X(0) # Z(0) # H(0)",
"(CNOT(wires=[0, 1])) # RX(1.23, wires=[1]) # I(0)",
"IsingXX(4.56, wires=[2, 3]) # (Toffoli(wires=[1, 2, 3])) # Rot(0.34, 1.0, 0, wires=[0])",
)
Expand Down
2 changes: 1 addition & 1 deletion tests/ops/op_math/test_sprod.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
ops_rep = (
"1.0 * X(0)",
"0.0 * Z(0)",
"1j * Hadamard(wires=[0])",
"1j * H(0)",
"1.23 * CNOT(wires=[0, 1])",
"4.56 * RX(1.23, wires=[1])",
"(1+2j) * I(0)",
Expand Down
25 changes: 25 additions & 0 deletions tests/ops/qubit/test_non_parametric_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,22 @@

STRING_REPR = (
(qml.Identity(0), "I(0)"),
(qml.Hadamard(0), "H(0)"),
(qml.PauliX(0), "X(0)"),
(qml.PauliY(0), "Y(0)"),
(qml.PauliZ(0), "Z(0)"),
(qml.Identity("a"), "I('a')"),
(qml.Identity(10), "I(10)"),
(qml.Identity(), "I()"),
(qml.Hadamard("a"), "H('a')"),
(qml.PauliX("a"), "X('a')"),
(qml.PauliY("a"), "Y('a')"),
(qml.PauliZ("a"), "Z('a')"),
(qml.H("a"), "H('a')"),
(qml.X("a"), "X('a')"),
(qml.Y("a"), "Y('a')"),
(qml.Z("a"), "Z('a')"),
(qml.H(0), "H(0)"),
(qml.X(1), "X(1)"),
(qml.Y(2), "Y(2)"),
(qml.Z(3), "Z(3)"),
Expand All @@ -92,6 +96,7 @@ def test_alias_XYZI(wire):
assert qml.PauliY(wire) == qml.Y(wire)
assert qml.PauliZ(wire) == qml.Z(wire)
assert qml.Identity(wire) == qml.I(wire)
assert qml.Hadamard(wire) == qml.H(wire)


class TestOperations:
Expand Down Expand Up @@ -1288,3 +1293,23 @@ def test_Z_class_name(self):

assert qml.Z(0).name == "PauliZ"
assert qml.PauliZ(0).name == "PauliZ"


class TestHadamardAlias:
def test_H_class_name(self):
"""Test the class name of H is by default correct"""
assert qml.H.__name__ == "Hadamard"
assert qml.Hadamard.__name__ == "Hadamard"

assert qml.H(0).name == "Hadamard"
assert qml.Hadamard(0).name == "Hadamard"

def test_hadamard_alias(self):
"""Test that qml.H is an alias for qml.Hadamard."""
# Verify that qml.H is the same as qml.Hadamard
assert qml.H is qml.Hadamard, "qml.H should be an alias for qml.Hadamard"

# Verify that an instance of qml.H is treated as qml.Hadamard
assert isinstance(
qml.H(0), qml.Hadamard
), "qml.H(0) should create an instance of qml.Hadamard"