def test_pauliz_tensor_hadamard(self, theta, phi, varphi, tol_stochastic): """Test that a tensor product involving PauliZ and hadamard works correctly""" dev = qml.device("default.qubit", wires=3, shots=int(1e6)) @qml.qnode(dev, diff_method="parameter-shift") def circuit(a, b, c): ansatz(a, b, c) return sample(qml.PauliZ(0) @ qml.Hadamard(1) @ qml.PauliY(2)) s1 = circuit(theta, phi, varphi) zero_state = np.zeros(2**3) zero_state[0] = 1 psi = zero_state psi = tensor_product([Rotx(theta), I, I]) @ zero_state psi = tensor_product([I, Rotx(phi), I]) @ psi psi = tensor_product([I, I, Rotx(varphi)]) @ psi psi = tensor_product([CNOT, I]) @ psi psi = tensor_product([I, CNOT]) @ psi # Diagonalize according to the observable psi = tensor_product([I, Roty(-np.pi / 4), I]) @ psi psi = tensor_product([I, I, Z]) @ psi psi = tensor_product([I, I, S]) @ psi psi = tensor_product([I, I, H]) @ psi expected_probabilities = np.abs(psi)**2 assert np.allclose(dev.probability(), expected_probabilities, atol=tol_stochastic, rtol=0) # s1 should only contain 1 and -1 assert np.allclose(s1**2, 1, atol=tol_stochastic, rtol=0)
def test_paulix_tensor_pauliy(self, theta, phi, varphi, tol): """Test that a tensor product involving PauliX and PauliY works correctly""" dev = qml.device("default.qubit", wires=3) @qml.qnode(dev) def circuit(a, b, c): ansatz(a, b, c) return sample(qml.PauliX(0) @ qml.PauliY(2)) s1 = circuit(theta, phi, varphi) # s1 should only contain 1 and -1 assert np.allclose(s1**2, 1, atol=tol, rtol=0) zero_state = np.zeros(2**3) zero_state[0] = 1 psi = zero_state psi = tensor_product([Rotx(theta), I, I]) @ zero_state psi = tensor_product([I, Rotx(phi), I]) @ psi psi = tensor_product([I, I, Rotx(varphi)]) @ psi psi = tensor_product([CNOT, I]) @ psi psi = tensor_product([I, CNOT]) @ psi # Diagonalize according to the observable psi = tensor_product([H, I, I]) @ psi psi = tensor_product([I, I, Z]) @ psi psi = tensor_product([I, I, S]) @ psi psi = tensor_product([I, I, H]) @ psi expected_probabilities = np.abs(psi)**2 assert np.allclose(dev.probability(), expected_probabilities, atol=tol, rtol=0)
def test_tensor_hermitian(self, theta, phi, varphi, tol): """Test that a tensor product involving qml.Hermitian works correctly""" dev = qml.device("default.qubit", wires=3) A = np.array([ [-6, 2 + 1j, -3, -5 + 2j], [2 - 1j, 0, 2 - 1j, -5 + 4j], [-3, 2 + 1j, 0, -4 + 3j], [-5 - 2j, -5 - 4j, -4 - 3j, -6], ]) @qml.qnode(dev) def circuit(a, b, c): ansatz(a, b, c) return sample(qml.PauliZ(0) @ qml.Hermitian(A, [1, 2])) s1 = circuit(theta, phi, varphi) # s1 should only contain the eigenvalues of # the hermitian matrix tensor product Z Z = np.diag([1, -1]) eigvals = np.linalg.eigvalsh(np.kron(Z, A)) assert set(np.round(s1, 8)).issubset(set(np.round(eigvals, 8))) zero_state = np.zeros(2**3) zero_state[0] = 1 psi = zero_state psi = tensor_product([Rotx(theta), I, I]) @ zero_state psi = tensor_product([I, Rotx(phi), I]) @ psi psi = tensor_product([I, I, Rotx(varphi)]) @ psi psi = tensor_product([CNOT, I]) @ psi psi = tensor_product([I, CNOT]) @ psi # Diagonalize according to the observable eigvals, eigvecs = np.linalg.eigh(A) psi = tensor_product([I, eigvecs.conj().T]) @ psi expected_probabilities = np.abs(psi)**2 assert np.allclose(dev.probability(), expected_probabilities, atol=tol, rtol=0)
def test_multiple_expectation_different_wires(self, qubit_device_2_wires, tol): """Tests that qnodes return multiple expectation values.""" a, b, c = torch.tensor(0.5), torch.tensor(0.54), torch.tensor(0.3) @qml.qnode(qubit_device_2_wires, interface='torch') def circuit(x, y, z): qml.RX(x, wires=[0]) qml.RZ(y, wires=[0]) qml.CNOT(wires=[0, 1]) qml.RY(y, wires=[0]) qml.RX(z, wires=[0]) return qml.expval(qml.PauliY(0)), qml.expval(qml.PauliZ(1)) res = circuit(a, b, c) out_state = np.kron(Rotx(c.numpy()), I) @ np.kron(Roty(b.numpy()), I) @ CNOT \ @ np.kron(Rotz(b.numpy()), I) @ np.kron(Rotx(a.numpy()), I) @ np.array([1, 0, 0, 0]) ex0 = np.vdot(out_state, np.kron(Y, I) @ out_state) ex1 = np.vdot(out_state, np.kron(I, Z) @ out_state) ex = np.array([ex0, ex1]) assert np.allclose(ex, res.numpy(), atol=tol, rtol=0)
def test_qnode_fanout(self, qubit_device_1_wire, tol): """Tests that qnodes can compute the correct function when the same parameter is used in multiple gates.""" @qml.qnode(qubit_device_1_wire, interface='torch') def circuit(reused_param, other_param): qml.RX(reused_param, wires=[0]) qml.RZ(other_param, wires=[0]) qml.RX(reused_param, wires=[0]) return qml.expval(qml.PauliZ(0)) thetas = torch.linspace(-2 * np.pi, 2 * np.pi, 7) for reused_param in thetas: for theta in thetas: other_param = theta**2 / 11 y_eval = circuit(reused_param, other_param) Rx = Rotx(reused_param.numpy()) Rz = Rotz(other_param.numpy()) zero_state = np.array([1., 0.]) final_state = (Rx @ Rz @ Rx @ zero_state) y_true = expZ(final_state) assert np.allclose(y_eval, y_true, atol=tol, rtol=0)