Repository: PennyLaneAI/pennylane
Pull request #4844 (2023-11-15 19:02:51)

`has_matrix` detects if `Operator.matrix` is overridden
Currently, `has_matrix` only is automatically `True` if `compute_matrix` is overridden.  If someone overrides `Operator.matrix` but not `Operator.compute_matrix`, they will have to manually set `has_matrix = True`.

This behaviour is a historical remnant from when `Operation` overrode the `Operator.matrix` method to include in-place inversion. As in-place inversion is no longer a thing, we no longer have any reason to keep that behaviour.

With this change, it will be easier for people to write their own custom operators.


This change is motivated by confusion over why an operator with a matrix wasn't supported by `default.qubit`.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/4844?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`aab9ed9`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/aab9ed91110ac95938fe2275625e1845970d5a9c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) 99.64% compared to head [(`3282e3c`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/4844?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) 99.64%.


<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff            @@
##           master    #4844    +/-   ##
========================================
  Coverage   99.64%   99.64%            
========================================
  Files         381      381            
  Lines       34346    34086   -260     
========================================
- Hits        34224    33965   -259     
+ Misses        122      121     -1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/4844?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).


Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 8fb42c8c3..0d832209c 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -33,6 +33,10 @@
 * `qml.draw` and `qml.draw_mpl` now render operator ids.
   [(#4749)](https://github.com/PennyLaneAI/pennylane/pull/4749)
 
+* `has_matrix` will now automatically be `True` if `Operator.matrix` is overridden, even if
+  `Operator.compute_matrix` is not.
+  [(#4844)](https://github.com/PennyLaneAI/pennylane/pull/4844)
+
 * Added `ops.functions.assert_valid` for checking if an `Operator` class is defined correctly.
   [(#4764)](https://github.com/PennyLaneAI/pennylane/pull/4764)
 
diff --git a/pennylane/operation.py b/pennylane/operation.py
index 34149a884..4987b4ff9 100644
--- a/pennylane/operation.py
+++ b/pennylane/operation.py
@@ -759,7 +759,7 @@ class Operator(abc.ABC):
 
         Note: Child classes may have this as an instance property instead of as a class property.
         """
-        return cls.compute_matrix != Operator.compute_matrix
+        return cls.compute_matrix != Operator.compute_matrix or cls.matrix != Operator.matrix
 
     def matrix(self, wire_order=None):
         r"""Representation of the operator as a matrix in the computational basis.


Test patch:
diff --git a/tests/test_operation.py b/tests/test_operation.py
index 383e9c47a..4f10c556b 100644
--- a/tests/test_operation.py
+++ b/tests/test_operation.py
@@ -470,6 +470,16 @@ class TestHasReprProperties:
         assert MyOp.has_matrix is True
         assert MyOp(wires=0).has_matrix is True
 
+    def test_has_matrix_true_overridden_matrix(self):
+        """Test has_matrix is true if `matrix` is overridden instead of `compute_matrix`."""
+
+        class MyOp(qml.operation.Operator):
+            def matrix(self, _=None):
+                return np.eye(2)
+
+        assert MyOp.has_matrix is True
+        assert MyOp(wires=0).has_matrix is True
+
     def test_has_matrix_false(self):
         """Test has_matrix property defaults to false if `compute_matrix` not overwritten."""