diff --git a/CHANGELOG.md b/CHANGELOG.md index 1deadb9..4554d62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ * The ``qml.QubitStateVector`` template has been removed. Instead, use :class:`~pennylane.StatePrep`. [(#203)](https://github.com/PennyLaneAI/pennylane-cirq/pull/203) +* Support for the `pennylane.operation.Tensor` observable is removed. This observable was deprecated + in PennyLane 0.39, and is removed in PennyLane 0.40. + [(#204)](https://github.com/PennyLaneAI/pennylane-cirq/pull/204) + ### Deprecations 👋 ### Documentation 📝 diff --git a/pennylane_cirq/cirq_device.py b/pennylane_cirq/cirq_device.py index bdd7f75..843337c 100644 --- a/pennylane_cirq/cirq_device.py +++ b/pennylane_cirq/cirq_device.py @@ -41,7 +41,6 @@ import cirq import pennylane as qml from pennylane.devices import QubitDevice -from pennylane.operation import Tensor from pennylane.ops import Prod from pennylane.wires import Wires @@ -192,9 +191,8 @@ def supports_operation(self, operation): def to_paulistring(self, observable): """Convert an observable to a cirq.PauliString""" - if isinstance(observable, (Tensor, Prod)): - obs = observable.obs if isinstance(observable, Tensor) else observable.operands - obs = [self.to_paulistring(o) for o in obs] + if isinstance(observable, Prod): + obs = [self.to_paulistring(o) for o in observable.operands] return functools.reduce(operator.mul, obs) cirq_op = self._observable_map[observable.name] if cirq_op is None: diff --git a/pennylane_cirq/qsim_device.py b/pennylane_cirq/qsim_device.py index d35f7d2..ac3473b 100644 --- a/pennylane_cirq/qsim_device.py +++ b/pennylane_cirq/qsim_device.py @@ -81,16 +81,8 @@ def observables(self): return set(self._base_observable_map) def expval(self, observable, shot_range=None, bin_size=None): - is_tensor = isinstance(observable, (qml.operation.Tensor, qml.ops.Prod)) - ob_names = ( - [obs.name for obs in observable.operands] - if isinstance(observable, qml.ops.Prod) - else observable.name - ) - if ( - is_tensor and all(obs == "Identity" for obs in ob_names) - ) or observable.name == "Identity": + if isinstance(observable.simplify(), qml.Identity): return 1 return super().expval(observable, shot_range, bin_size) diff --git a/pennylane_cirq/simulator_device.py b/pennylane_cirq/simulator_device.py index 4f888b6..7f8589c 100644 --- a/pennylane_cirq/simulator_device.py +++ b/pennylane_cirq/simulator_device.py @@ -155,49 +155,28 @@ def expval(self, observable, shot_range=None, bin_size=None): # pylint: disable=missing-function-docstring # Analytic mode if self.shots is None: - if not isinstance(observable, (qml.operation.Tensor, qml.ops.Prod)): - # Observable on a single wire - # Projector, Hermitian - if self._observable_map[observable.name] is None or observable.name == "Projector": + all_observables = ( + list(observable.operands) if isinstance(observable, qml.ops.Prod) else [observable] + ) + + for obs in all_observables: + if self._observable_map[obs.name] is None or obs.name == "Projector": return super().expval(observable, shot_range, bin_size) - if observable.name == "Hadamard": - circuit = self.circuit - obs = cirq.PauliSum() + self.to_paulistring(qml.PauliZ(wires=observable.wires)) - else: - circuit = self.pre_rotated_circuit - obs = cirq.PauliSum() + self.to_paulistring(observable) + if "Hadamard" in [op.name for op in all_observables]: + list_obs = [] - # Observables are in tensor form - else: + for obs in all_observables: + list_obs.append(qml.PauliZ(wires=obs.wires)) - ob_names = ( - [op.name for op in observable.operands] - if isinstance(observable, qml.ops.Prod) - else observable.name - ) - - # Projector, Hamiltonian, Hermitian - for name in ob_names: - if self._observable_map[name] is None or name == "Projector": - return super().expval(observable, shot_range, bin_size) - - if "Hadamard" in ob_names: - list_obs = [] - observables = ( - observable.operands - if isinstance(observable, qml.ops.Prod) - else observable.obs - ) - for obs in observables: - list_obs.append(qml.PauliZ(wires=obs.wires)) - - T = qml.prod(*list_obs) - circuit = self.circuit - obs = cirq.PauliSum() + self.to_paulistring(T) - else: - circuit = self.pre_rotated_circuit - obs = cirq.PauliSum() + self.to_paulistring(observable) + T = qml.prod(*list_obs) + + circuit = self.circuit + obs = cirq.PauliSum() + self.to_paulistring(T) + + else: + circuit = self.pre_rotated_circuit + obs = cirq.PauliSum() + self.to_paulistring(observable) return self._simulator.simulate_expectation_values( program=circuit,