Skip to content

Commit

Permalink
add type hint for unimplemented operator function (#5490)
Browse files Browse the repository at this point in the history
### Before submitting

Please complete the following checklist when submitting a PR:

- [x] All new features must include a unit test.
If you've fixed a bug or added code that should be tested, add a test to
the
      test directory!

- [x] All new functions and code must be clearly commented and
documented.
If you do make documentation changes, make sure that the docs build and
      render correctly by running `make docs`.

- [x] Ensure that the test suite passes, by running `make test`.

- [x] Add a new entry to the `doc/releases/changelog-dev.md` file,
summarizing the
      change, and including a link back to the PR.

- [x] The PennyLane source code conforms to
      [PEP8 standards](https://www.python.org/dev/peps/pep-0008/).
We check all of our code against [Pylint](https://www.pylint.org/).
      To lint modified files, simply `pip install pylint`, and then
      run `pylint pennylane/path/to/file.py`.

When all the above are checked, delete everything above the dashed
line and fill in the pull request template.


------------------------------------------------------------------------------------------------------------

**Context:**
The abstract class Operator defines several methods that need to be
implemented in subclasses. While these methods are defined to raise
errors before implementation in the abstract class, this leads to
linting errors. Therefore, appropriate type hints were added after
implementation.

**Description of the Change:**
Add type hints to the following methods.
- `compute_matrix`
- `matrix`
- `compute_sparse_matrix`
- `sparse_matrix`
- `compute_eigvals`
- `decomposition`
- `compute_decomposition`
- `compute_diagonalizing_gates`
- `single_qubit_rot_angles`
- `compute_kraus_matrices`

**Benefits:**
Improve the interpretability of the linter

**Possible Drawbacks:**

**Related GitHub Issues:**
Add type hints to pennylane.operation.Operator #5398

---------

Co-authored-by: Christina Lee <christina@xanadu.ai>
  • Loading branch information
kenya-sk and albi3ro committed Apr 11, 2024
1 parent 803139d commit e761e18
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
4 changes: 4 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@
[(#5256)](https://github.com/PennyLaneAI/pennylane/pull/5256)
[(#5395)](https://github.com/PennyLaneAI/pennylane/pull/5395)

* Add type hints for unimplemented methods of the abstract class `Operator`.
[(#5490)](https://github.com/PennyLaneAI/pennylane/pull/5490)

* A clear error message is added in `KerasLayer` when using the newest version of TensorFlow with Keras 3
(which is not currently compatible with `KerasLayer`), linking to instructions to enable Keras 2.
[(#5488)](https://github.com/PennyLaneAI/pennylane/pull/5488)
Expand Down Expand Up @@ -411,6 +414,7 @@ Korbinian Kottmann,
Christina Lee,
Vincent Michaud-Rioux,
Mudit Pandey,
Kenya Sakka,
Jay Soni,
Matthew Silverman,
David Wierichs.
28 changes: 16 additions & 12 deletions pennylane/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,12 @@
import itertools
import warnings
from enum import IntEnum
from typing import List
from typing import List, Tuple
from contextlib import contextmanager

import numpy as np
from numpy.linalg import multi_dot
from scipy.sparse import coo_matrix, eye, kron
from scipy.sparse import coo_matrix, csr_matrix, eye, kron

import pennylane as qml
from pennylane.math import expand_matrix
Expand Down Expand Up @@ -748,7 +748,7 @@ def __hash__(self):
return self.hash

@staticmethod
def compute_matrix(*params, **hyperparams): # pylint:disable=unused-argument
def compute_matrix(*params, **hyperparams) -> TensorLike: # pylint:disable=unused-argument
r"""Representation of the operator as a canonical matrix in the computational basis (static method).
The canonical matrix is the textbook matrix representation that does not consider wires.
Expand All @@ -774,7 +774,7 @@ def has_matrix(cls):
"""
return cls.compute_matrix != Operator.compute_matrix or cls.matrix != Operator.matrix

def matrix(self, wire_order=None):
def matrix(self, wire_order=None) -> TensorLike:
r"""Representation of the operator as a matrix in the computational basis.
If ``wire_order`` is provided, the numerical representation considers the position of the
Expand Down Expand Up @@ -809,7 +809,9 @@ def matrix(self, wire_order=None):
return expand_matrix(canonical_matrix, wires=self.wires, wire_order=wire_order)

@staticmethod
def compute_sparse_matrix(*params, **hyperparams): # pylint:disable=unused-argument
def compute_sparse_matrix(
*params, **hyperparams
) -> csr_matrix: # pylint:disable=unused-argument
r"""Representation of the operator as a sparse matrix in the computational basis (static method).
The canonical matrix is the textbook matrix representation that does not consider wires.
Expand All @@ -827,7 +829,7 @@ def compute_sparse_matrix(*params, **hyperparams): # pylint:disable=unused-argu
"""
raise SparseMatrixUndefinedError

def sparse_matrix(self, wire_order=None):
def sparse_matrix(self, wire_order=None) -> csr_matrix:
r"""Representation of the operator as a sparse matrix in the computational basis.
If ``wire_order`` is provided, the numerical representation considers the position of the
Expand All @@ -852,7 +854,7 @@ def sparse_matrix(self, wire_order=None):
return expand_matrix(canonical_sparse_matrix, wires=self.wires, wire_order=wire_order)

@staticmethod
def compute_eigvals(*params, **hyperparams):
def compute_eigvals(*params, **hyperparams) -> TensorLike:
r"""Eigenvalues of the operator in the computational basis (static method).
If :attr:`diagonalizing_gates` are specified and implement a unitary :math:`U^{\dagger}`,
Expand Down Expand Up @@ -1268,7 +1270,7 @@ def has_decomposition(cls):
or cls.decomposition != Operator.decomposition
)

def decomposition(self):
def decomposition(self) -> List["Operator"]:
r"""Representation of the operator as a product of other operators.
.. math:: O = O_1 O_2 \dots O_n
Expand All @@ -1285,7 +1287,7 @@ def decomposition(self):
)

@staticmethod
def compute_decomposition(*params, wires=None, **hyperparameters):
def compute_decomposition(*params, wires=None, **hyperparameters) -> List["Operator"]:
r"""Representation of the operator as a product of other operators (static method).
.. math:: O = O_1 O_2 \dots O_n.
Expand Down Expand Up @@ -1324,7 +1326,7 @@ def has_diagonalizing_gates(cls):
@staticmethod
def compute_diagonalizing_gates(
*params, wires, **hyperparams
): # pylint: disable=unused-argument
) -> List["Operator"]: # pylint: disable=unused-argument
r"""Sequence of gates that diagonalize the operator in the computational basis (static method).
Given the eigendecomposition :math:`O = U \Sigma U^{\dagger}` where
Expand Down Expand Up @@ -1719,7 +1721,7 @@ def control_wires(self): # pragma: no cover
"""
return Wires([])

def single_qubit_rot_angles(self):
def single_qubit_rot_angles(self) -> Tuple[float, float, float]:
r"""The parameters required to implement a single-qubit gate as an
equivalent ``Rot`` gate, up to a global phase.
Expand Down Expand Up @@ -1814,7 +1816,9 @@ class Channel(Operation, abc.ABC):

@staticmethod
@abc.abstractmethod
def compute_kraus_matrices(*params, **hyperparams): # pylint:disable=unused-argument
def compute_kraus_matrices(
*params, **hyperparams
) -> List[np.ndarray]: # pylint:disable=unused-argument
"""Kraus matrices representing a quantum channel, specified in
the computational basis.
Expand Down

0 comments on commit e761e18

Please sign in to comment.