def test_invalid_qubit_state_vector(self): """Test that an exception is raised if the state vector is the wrong size""" dev = TensorNetworkTF(wires=2) state = np.array([0, 123.432]) with pytest.raises(ValueError, match=r"State vector must be of length 2\*\*wires"): dev.execute([qml.QubitStateVector(state, wires=[0])], [], {})
def test_qubit_state_vector(self, init_state, tol): """Test qubit state vector application""" dev = TensorNetworkTF(wires=1) state = init_state(1) dev.execute([qml.QubitStateVector(state, wires=[0])], [], {}) res = dev._state.numpy().flatten() expected = state assert np.allclose(res, expected, atol=tol, rtol=0)
def test_two_qubit_parameters(self, init_state, op, func, theta, tol): """Test two qubit parametrized operations""" dev = TensorNetworkTF(wires=2) state = init_state(2) queue = [qml.QubitStateVector(state, wires=[0, 1])] queue += [op(theta, wires=[0, 1])] dev.execute(queue, [], {}) res = dev._state.numpy().flatten() expected = func(theta) @ state assert np.allclose(res, expected, atol=tol, rtol=0)
def test_three_qubit_no_parameters(self, init_state, op, mat, tol): """Test non-parametrized three qubit operations""" dev = TensorNetworkTF(wires=3) state = init_state(3) queue = [qml.QubitStateVector(state, wires=[0, 1, 2])] queue += [op(wires=[0, 1, 2])] dev.execute(queue, [], {}) res = dev._state.numpy().flatten() expected = mat @ state assert np.allclose(res, expected, atol=tol, rtol=0)
def test_basis_state(self, tol): """Test basis state initialization""" dev = TensorNetworkTF(wires=4) state = np.array([0, 0, 1, 0]) dev.execute([qml.BasisState(state, wires=[0, 1, 2, 3])], [], {}) res = dev._state.numpy().flatten() expected = np.zeros([2 ** 4]) expected[np.ravel_multi_index(state, [2] * 4)] = 1 assert np.allclose(res, expected, atol=tol, rtol=0)
def test_qubit_unitary(self, init_state, mat, tol): """Test application of arbitrary qubit unitaries""" N = int(np.log2(len(mat))) dev = TensorNetworkTF(wires=N) state = init_state(N) queue = [qml.QubitStateVector(state, wires=range(N))] queue += [qml.QubitUnitary(mat, wires=range(N))] dev.execute(queue, [], {}) res = dev._state.numpy().flatten() expected = mat @ state assert np.allclose(res, expected, atol=tol, rtol=0)
def test_multi_mode_hermitian_expectation(self, theta, phi, tol): """Test that arbitrary multi-mode Hermitian expectation values are correct""" 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], ] ) dev = TensorNetworkTF(wires=2) queue = [qml.RY(theta, wires=0), qml.RY(phi, wires=1), qml.CNOT(wires=[0, 1])] observables = [qml.Hermitian(A, wires=[0, 1])] for i in range(len(observables)): observables[i].return_type = qml.operation.Expectation res = dev.execute(queue, observables, {}) # below is the analytic expectation value for this circuit with arbitrary # Hermitian observable A expected = 0.5 * ( 6 * np.cos(theta) * np.sin(phi) - np.sin(theta) * (8 * np.sin(phi) + 7 * np.cos(phi) + 3) - 2 * np.sin(phi) - 6 * np.cos(phi) - 6 ) assert np.allclose(res, expected, atol=tol, rtol=0)
def test_rotation(self, init_state, tol): """Test three axis rotation gate""" dev = TensorNetworkTF(wires=1) state = init_state(1) a = 0.542 b = 1.3432 c = -0.654 queue = [qml.QubitStateVector(state, wires=[0])] queue += [qml.Rot(a, b, c, wires=0)] dev.execute(queue, [], {}) res = dev._state.numpy().flatten() expected = rot(a, b, c) @ state assert np.allclose(res, expected, atol=tol, rtol=0)
def test_hermitian_expectation(self, theta, phi, tol): """Test that arbitrary Hermitian expectation values are correct""" dev = TensorNetworkTF(wires=2) queue = [ qml.RY(theta, wires=0), qml.RY(phi, wires=1), qml.CNOT(wires=[0, 1]) ] observables = [qml.Hermitian(A, wires=[i]) for i in range(2)] for i in range(len(observables)): observables[i].return_type = qml.operation.Expectation res = dev.execute(queue, observables, {}) a = A[0, 0] re_b = A[0, 1].real d = A[1, 1] ev1 = ((a - d) * np.cos(theta) + 2 * re_b * np.sin(theta) * np.sin(phi) + a + d) / 2 ev2 = ((a - d) * np.cos(theta) * np.cos(phi) + 2 * re_b * np.sin(phi) + a + d) / 2 expected = np.array([ev1, ev2]) assert np.allclose(res, expected, atol=tol, rtol=0)
def test_single_wire_expectation(self, gate, obs, expected, theta, phi, tol): """Test that identity expectation value (i.e. the trace) is 1""" dev = TensorNetworkTF(wires=2) queue = [gate(theta, wires=0), gate(phi, wires=1), qml.CNOT(wires=[0, 1])] observables = [obs(wires=[i]) for i in range(2)] for i in range(len(observables)): observables[i].return_type = qml.operation.Expectation res = dev.execute(queue, observables, {}) assert np.allclose(res, expected(theta, phi), atol=tol, rtol=0)
def test_var(self, theta, phi, tol): """Tests for variance calculation""" dev = TensorNetworkTF(wires=1) # test correct variance for <Z> of a rotated state queue = [qml.RX(phi, wires=0), qml.RY(theta, wires=0)] observables = [qml.PauliZ(wires=[0])] for i in range(len(observables)): observables[i].return_type = qml.operation.Variance res = dev.execute(queue, observables, {}) expected = 0.25 * (3 - np.cos(2 * theta) - 2 * np.cos(theta) ** 2 * np.cos(2 * phi)) assert np.allclose(res, expected, atol=tol, rtol=0)
def test_var_hermitian(self, theta, phi, tol): """Tests for variance calculation using an arbitrary Hermitian observable""" dev = TensorNetworkTF(wires=2) # test correct variance for <H> of a rotated state H = np.array([[4, -1 + 6j], [-1 - 6j, 2]]) queue = [qml.RX(phi, wires=0), qml.RY(theta, wires=0)] observables = [qml.Hermitian(H, wires=[0])] for i in range(len(observables)): observables[i].return_type = qml.operation.Variance res = dev.execute(queue, observables, {}) expected = 0.5 * (2 * np.sin(2 * theta) * np.cos(phi)**2 + 24 * np.sin(phi) * np.cos(phi) * (np.sin(theta) - np.cos(theta)) + 35 * np.cos(2 * phi) + 39) assert np.allclose(res, expected, atol=tol, rtol=0)