def test_hamiltonian_mix_return(self, use_csingle): """Test expected serialization for a Hamiltonian return""" ham1 = qml.Hamiltonian( [0.3, 0.5, 0.4], [ qml.Hermitian(np.eye(4), wires=[0, 1]) @ qml.PauliY(2), qml.PauliX(0) @ qml.PauliY(2), qml.Hermitian(np.ones((8, 8)), wires=range(3)), ], ) ham2 = qml.Hamiltonian( [0.7, 0.3], [qml.PauliX(0) @ qml.Hermitian(np.eye(4), wires=[1, 2]), qml.PauliY(0) @ qml.PauliX(2)], ) with qml.tape.QuantumTape() as tape: qml.expval(ham1) qml.expval(ham2) obs_str = "HamiltonianC64" if use_csingle else "HamiltonianC128" hamiltonian_obs = HamiltonianC64 if use_csingle else HamiltonianC128 named_obs = NamedObsC64 if use_csingle else NamedObsC128 hermitian_obs = HermitianObsC64 if use_csingle else HermitianObsC128 tensor_prod_obs = TensorProdObsC64 if use_csingle else TensorProdObsC128 r_dtype = np.float32 if use_csingle else np.float64 c_dtype = np.complex64 if use_csingle else np.complex128 s = _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) s_expected1 = hamiltonian_obs( np.array([0.3, 0.5, 0.4], dtype=r_dtype), [ tensor_prod_obs( [ hermitian_obs(np.eye(4, dtype=c_dtype).ravel(), [0, 1]), named_obs("PauliY", [2]), ] ), tensor_prod_obs([named_obs("PauliX", [0]), named_obs("PauliY", [2])]), hermitian_obs(np.ones(64, dtype=c_dtype), [0, 1, 2]), ], ) s_expected2 = hamiltonian_obs( np.array([0.7, 0.3], dtype=r_dtype), [ tensor_prod_obs( [ named_obs("PauliX", [0]), hermitian_obs(np.eye(4, dtype=c_dtype).ravel(), [1, 2]), ] ), tensor_prod_obs([named_obs("PauliY", [0]), named_obs("PauliX", [2])]), ], ) assert s[0] == s_expected1 assert s[1] == s_expected2
def test_basic_return(self, monkeypatch, ObsFunc): """Test expected serialization for a simple return""" with qml.tape.QuantumTape() as tape: qml.expval(qml.PauliZ(0)) mock_obs = mock.MagicMock() use_csingle = True if ObsFunc == NamedObsC64 else False obs_str = "NamedObsC64" if ObsFunc == NamedObsC64 else "NamedObsC128" with monkeypatch.context() as m: m.setattr(pennylane_lightning._serialize, obs_str, mock_obs) _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) s = mock_obs.call_args[0] s_expected = ("PauliZ", [0]) ObsFunc(*s_expected) assert s == s_expected
def test_tensor_return(self, monkeypatch, use_csingle): """Test expected serialization for a tensor product return""" with qml.tape.QuantumTape() as tape: qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)) mock_obs = mock.MagicMock() ObsFunc = TensorProdObsC64 if use_csingle else TensorProdObsC128 named_obs = NamedObsC64 if use_csingle else NamedObsC128 obs_str = "TensorProdObsC64" if use_csingle else "TensorProdObsC128" with monkeypatch.context() as m: m.setattr(pennylane_lightning._serialize, obs_str, mock_obs) _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) s = mock_obs.call_args[0] s_expected = ([named_obs("PauliZ", [0]), named_obs("PauliZ", [1])],) ObsFunc(*s_expected) assert s == s_expected
def test_chunk_obs(self, monkeypatch, use_csingle, ObsChunk): """Test chunking of observable array""" with qml.tape.QuantumTape() as tape: qml.expval(qml.PauliZ(0) @ qml.PauliX(1)) qml.expval(qml.PauliY(wires=1)) qml.expval(qml.PauliX(0) @ qml.Hermitian([[0, 1], [1, 0]], wires=3) @ qml.Hadamard(2)) qml.expval(qml.Hermitian(qml.PauliZ.compute_matrix(), wires=0) @ qml.Identity(1)) s = _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) obtained_chunks = pennylane_lightning.lightning_qubit._chunk_iterable(s, ObsChunk) assert len(list(obtained_chunks)) == int(np.ceil(len(s) / ObsChunk))
def test_hamiltonian_tensor_return(self, use_csingle): """Test expected serialization for a Hamiltonian return""" with qml.tape.QuantumTape() as tape: ham = qml.Hamiltonian( [0.3, 0.5, 0.4], [ qml.Hermitian(np.eye(4), wires=[0, 1]) @ qml.PauliY(2), qml.PauliX(0) @ qml.PauliY(2), qml.Hermitian(np.ones((8, 8)), wires=range(3)), ], ) qml.expval(ham @ qml.PauliZ(3)) obs_str = "HamiltonianC64" if use_csingle else "HamiltonianC128" hamiltonian_obs = HamiltonianC64 if use_csingle else HamiltonianC128 named_obs = NamedObsC64 if use_csingle else NamedObsC128 hermitian_obs = HermitianObsC64 if use_csingle else HermitianObsC128 tensor_prod_obs = TensorProdObsC64 if use_csingle else TensorProdObsC128 r_dtype = np.float32 if use_csingle else np.float64 c_dtype = np.complex64 if use_csingle else np.complex128 s = _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) # Expression (ham @ obs) is converted internally by Pennylane # where obs is appended to each term of the ham s_expected = hamiltonian_obs( np.array([0.3, 0.5, 0.4], dtype=r_dtype), [ tensor_prod_obs( [ hermitian_obs(np.eye(4, dtype=c_dtype).ravel(), [0, 1]), named_obs("PauliY", [2]), named_obs("PauliZ", [3]), ] ), tensor_prod_obs( [named_obs("PauliX", [0]), named_obs("PauliY", [2]), named_obs("PauliZ", [3])] ), tensor_prod_obs( [hermitian_obs(np.ones(64, dtype=c_dtype), [0, 1, 2]), named_obs("PauliZ", [3])] ), ], ) assert s[0] == s_expected
def test_mixed_tensor_return(self, use_csingle): """Test expected serialization for a mixture of Hermitian and Pauli return""" with qml.tape.QuantumTape() as tape: qml.expval(qml.Hermitian(np.eye(4), wires=[0, 1]) @ qml.PauliY(2)) c_dtype = np.complex64 if use_csingle else np.complex128 tensor_prod_obs = TensorProdObsC64 if use_csingle else TensorProdObsC128 hermitian_obs = HermitianObsC64 if use_csingle else HermitianObsC128 named_obs = NamedObsC64 if use_csingle else NamedObsC128 s = _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) s_expected = tensor_prod_obs( [hermitian_obs(np.eye(4, dtype=c_dtype).ravel(), [0, 1]), named_obs("PauliY", [2])] ) assert s[0] == s_expected
def test_hermitian_return(self, use_csingle): """Test expected serialization for a Hermitian return""" with qml.tape.QuantumTape() as tape: qml.expval(qml.Hermitian(np.eye(4), wires=[0, 1])) hermitian_obs = HermitianObsC64 if use_csingle else HermitianObsC128 c_dtype = np.complex64 if use_csingle else np.complex128 s = _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) s_expected = hermitian_obs( np.array( [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0], dtype=c_dtype, ), [0, 1], ) s[0] == s_expected
def test_tensor_non_tensor_return(self, use_csingle): """Test expected serialization for a mixture of tensor product and non-tensor product return""" with qml.tape.QuantumTape() as tape: qml.expval(qml.PauliZ(0) @ qml.PauliX(1)) qml.expval(qml.Hadamard(1)) tensor_prod_obs = TensorProdObsC64 if use_csingle else TensorProdObsC128 named_obs = NamedObsC64 if use_csingle else NamedObsC128 s = _serialize_observables(tape, self.wires_dict, use_csingle=use_csingle) s_expected = [ tensor_prod_obs([named_obs("PauliZ", [0]), named_obs("PauliX", [1])]), named_obs("Hadamard", [1]), ] assert s == s_expected