Repository: PennyLaneAI/pennylane

Issue:
[BUG] qml.matrix(op) and op.matrix() are different for Barrier and WireCut
### Expected behavior

I expected them both to pass, or both to fail.

### Actual behavior

`qml.matrix(qml.Barrier(0))` passed, `qml.Barrier(0).matrix()` failed. Same for `qml.WireCut`.

### Additional information

Attached source code is for Barrier, but the same thing happens with WireCut.

### Source code

```shell
>>> import pennylane as qml
>>> op = qml.Barrier(0)
>>> qml.matrix(op)
array([[1.]])
>>> op.matrix()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/matthews/src/github.com/PennyLaneAI/pennylane/pennylane/operation.py", line 1405, in matrix
    canonical_matrix = self.compute_matrix(*self.parameters, **self.hyperparameters)
  File "/Users/matthews/src/github.com/PennyLaneAI/pennylane/pennylane/operation.py", line 446, in compute_matrix
    raise MatrixUndefinedError
pennylane.operation.MatrixUndefinedError
```


### Tracebacks

_No response_

### System information

```shell
Name: PennyLane
Version: 0.27.0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /Users/matthews/.pyenv/versions/3.9.13/envs/pennylane/lib/python3.9/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, retworkx, scipy, semantic-version, toml
Required-by: PennyLane-Lightning

Platform info:           macOS-12.6.1-arm64-arm-64bit
Python version:          3.9.13
Numpy version:           1.23.2
Scipy version:           1.9.0
Installed devices:
- default.gaussian (PennyLane-0.27.0)
- default.mixed (PennyLane-0.27.0)
- default.qubit (PennyLane-0.27.0)
- default.qubit.autograd (PennyLane-0.27.0)
- default.qubit.jax (PennyLane-0.27.0)
- default.qubit.tf (PennyLane-0.27.0)
- default.qubit.torch (PennyLane-0.27.0)
- default.qutrit (PennyLane-0.27.0)
- null.qubit (PennyLane-0.27.0)
- lightning.qubit (PennyLane-Lightning-0.26.1)
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.


Discussion:

Resolving patch:
diff --git a/pennylane/ops/functions/matrix.py b/pennylane/ops/functions/matrix.py
--- a/pennylane/ops/functions/matrix.py
+++ b/pennylane/ops/functions/matrix.py
@@ -130,6 +130,8 @@ def cost(theta):
 @matrix.tape_transform
 def _matrix(tape, wire_order=None):
     """Defines how matrix works if applied to a tape containing multiple operations."""
+    if not tape.wires:
+        raise qml.operation.MatrixUndefinedError
     params = tape.get_parameters(trainable_only=False)
     interface = qml.math.get_interface(*params)
 


Test patch:
diff --git a/tests/ops/functions/test_matrix.py b/tests/ops/functions/test_matrix.py
--- a/tests/ops/functions/test_matrix.py
+++ b/tests/ops/functions/test_matrix.py
@@ -689,3 +689,19 @@ def loss(theta):
         assert isinstance(matrix, qml.numpy.tensor)
         assert np.allclose(l, 2 * np.cos(v / 2))
         assert np.allclose(dl, -np.sin(v / 2))
+
+
+class TestMeasurements:
+    @pytest.mark.parametrize(
+        "measurements,N",
+        [
+            ([qml.expval(qml.PauliX(0))], 2),
+            ([qml.probs(qml.PauliX(0)), qml.probs(qml.PauliZ(1))], 4),
+            ([qml.probs(wires=[0, 1])], 4),
+            ([qml.counts(wires=[0, 1, 2])], 8),
+        ],
+    )
+    def test_all_measurement_matrices_are_identity(self, measurements, N):
+        """Test that the matrix of a script with only observables is Identity."""
+        qscript = qml.tape.QuantumScript(measurements=measurements)
+        assert np.array_equal(qml.matrix(qscript), np.eye(N))
diff --git a/tests/ops/qubit/test_non_parametric_ops.py b/tests/ops/qubit/test_non_parametric_ops.py
--- a/tests/ops/qubit/test_non_parametric_ops.py
+++ b/tests/ops/qubit/test_non_parametric_ops.py
@@ -623,6 +623,14 @@ def test_simplify_only_visual_False(self):
         op = qml.Barrier(wires=(0, 1, 2, 3), only_visual=False)
         assert op.simplify() is op
 
+    def test_qml_matrix_fails(self):
+        """Test that qml.matrix(op) and op.matrix() both fail."""
+        op = qml.Barrier(0)
+        with pytest.raises(qml.operation.MatrixUndefinedError):
+            qml.matrix(op)
+        with pytest.raises(qml.operation.MatrixUndefinedError):
+            op.matrix()
+
 
 class TestWireCut:
     """Tests for the WireCut operator"""
@@ -653,6 +661,14 @@ def test_wires_empty_list_raises_error(self):
         ):
             qml.WireCut(wires=[])
 
+    def test_qml_matrix_fails(self):
+        """Test that qml.matrix(op) and op.matrix() both fail."""
+        op = qml.WireCut(0)
+        with pytest.raises(qml.operation.MatrixUndefinedError):
+            qml.matrix(op)
+        with pytest.raises(qml.operation.MatrixUndefinedError):
+            op.matrix()
+
 
 class TestMultiControlledX:
     """Tests for the MultiControlledX"""