def test_symmetric_extension_hierarchy_four_bell_with_resource_state(): """Symmetric extension hierarchy for four Bell states and resource state.""" e_0, e_1 = basis(2, 0), basis(2, 1) e_00, e_11 = np.kron(e_0, e_0), np.kron(e_1, e_1) eps = 1 / 2 eps_state = np.sqrt((1 + eps) / 2) * e_00 + np.sqrt((1 - eps) / 2) * e_11 eps_dm = eps_state * eps_state.conj().T states = [ np.kron(bell(0) * bell(0).conj().T, eps_dm), np.kron(bell(1) * bell(1).conj().T, eps_dm), np.kron(bell(2) * bell(2).conj().T, eps_dm), np.kron(bell(3) * bell(3).conj().T, eps_dm), ] # Ensure we are checking the correct partition of the states. states = [ swap(states[0], [2, 3], [2, 2, 2, 2]), swap(states[1], [2, 3], [2, 2, 2, 2]), swap(states[2], [2, 3], [2, 2, 2, 2]), swap(states[3], [2, 3], [2, 2, 2, 2]), ] res = symmetric_extension_hierarchy(states=states, probs=None, level=2) exp_res = 1 / 2 * (1 + np.sqrt(1 - eps**2)) np.testing.assert_equal(np.isclose(res, exp_res), True)
def test_fidelity_non_identical_states_1(): """Test the fidelity between two non-identical states.""" e_0, e_1 = basis(2, 0), basis(2, 1) rho = 3 / 4 * e_0 * e_0.conj().T + 1 / 4 * e_1 * e_1.conj().T sigma = 2 / 3 * e_0 * e_0.conj().T + 1 / 3 * e_1 * e_1.conj().T np.testing.assert_equal( np.isclose(fidelity(rho, sigma), 0.996, rtol=1e-03), True)
def test_schmidt_decomp_two_qubit_3(): """ Schmidt decomposition of two-qubit state. The Schmidt decomposition of 1/2* (|00> + |11>) has Schmidt coefficients equal to 1/2[1, 1] """ e_0, e_1 = basis(2, 0), basis(2, 1) phi = 1 / 2 * (np.kron(e_0, e_0) + np.kron(e_1, e_1)) singular_vals, vt_mat, u_mat = schmidt_decomposition(phi) expected_singular_vals = 1 / 2 * np.array([[1], [1]]) bool_mat = np.isclose(expected_singular_vals, singular_vals) np.testing.assert_equal(np.all(bool_mat), True) expected_vt_mat = np.array([[1, 0], [0, 1]]) bool_mat = np.isclose(expected_vt_mat, vt_mat) np.testing.assert_equal(np.all(bool_mat), True) expected_u_mat = np.array([[1, 0], [0, 1]]) bool_mat = np.isclose(expected_u_mat, u_mat) np.testing.assert_equal(np.all(bool_mat), True) s_decomp = ( singular_vals[0] * np.atleast_2d(np.kron(vt_mat[:, 0], u_mat[:, 0])).T + singular_vals[1] * np.atleast_2d(np.kron(vt_mat[:, 1], u_mat[:, 1])).T) np.testing.assert_equal(np.isclose(np.linalg.norm(phi - s_decomp), 0), True)
def test_matsumoto_fidelity_non_identical_states_2(): """Test the Matsumoto fidelity between two non-identical states.""" e_0, e_1 = basis(2, 0), basis(2, 1) rho = 3 / 4 * e_0 * e_0.conj().T + 1 / 4 * e_1 * e_1.conj().T sigma = 1 / 8 * e_0 * e_0.conj().T + 7 / 8 * e_1 * e_1.conj().T np.testing.assert_equal( np.isclose(matsumoto_fidelity(rho, sigma), 0.774, rtol=1e-03), True)
def test_bures_distance_non_identical_states_2(): """Test the bures_distance between two non-identical states.""" e_0, e_1 = basis(2, 0), basis(2, 1) rho = 3 / 4 * e_0 * e_0.conj().T + 1 / 4 * e_1 * e_1.conj().T sigma = 1 / 8 * e_0 * e_0.conj().T + 7 / 8 * e_1 * e_1.conj().T np.testing.assert_equal( np.isclose(bures_distance(rho, sigma), 0.6724, rtol=1e-03), True)
def test_schmidt_decomp_two_qubit_2(): """ Schmidt decomposition of two-qubit state. The Schmidt decomposition of | phi > = 1/2(|00> + |01> + |10> - |11>) is the state 1/sqrt(2) * (|0>|+> + |1>|->). """ e_0, e_1 = basis(2, 0), basis(2, 1) phi = 1 / 2 * (np.kron(e_0, e_0) + np.kron(e_0, e_1) + np.kron(e_1, e_0) - np.kron(e_1, e_1)) singular_vals, vt_mat, u_mat = schmidt_decomposition(phi) expected_singular_vals = 1 / np.sqrt(2) * np.array([[1], [1]]) bool_mat = np.isclose(expected_singular_vals, singular_vals) np.testing.assert_equal(np.all(bool_mat), True) expected_vt_mat = np.array([[-1, 0], [0, -1]]) bool_mat = np.isclose(expected_vt_mat, vt_mat) np.testing.assert_equal(np.all(bool_mat), True) expected_u_mat = 1 / np.sqrt(2) * np.array([[-1, -1], [-1, 1]]) bool_mat = np.isclose(expected_u_mat, u_mat) np.testing.assert_equal(np.all(bool_mat), True) s_decomp = ( singular_vals[0] * np.atleast_2d(np.kron(vt_mat[:, 0], u_mat[:, 0])).T + singular_vals[1] * np.atleast_2d(np.kron(vt_mat[:, 1], u_mat[:, 1])).T) np.testing.assert_equal(np.isclose(np.linalg.norm(phi - s_decomp), 0), True)
def test_is_not_mub_dim_2(): """Return False for non-MUB of dimension 2.""" e_0, e_1 = basis(2, 0), basis(2, 1) mub_1 = [e_0, e_1] mub_2 = [1 / np.sqrt(2) * (e_0 + e_1), e_1] mub_3 = [1 / np.sqrt(2) * (e_0 + 1j * e_1), e_0] mubs = [mub_1, mub_2, mub_3] np.testing.assert_equal(is_mutually_unbiased_basis(mubs), False)
def test_is_product_separable_state(): """Check that is_product_vector returns True for a separable state.""" e_0, e_1 = basis(2, 0), basis(2, 1) sep_vec = ( 1 / 2 * (np.kron(e_0, e_0) - np.kron(e_0, e_1) - np.kron(e_1, e_0) + np.kron(e_1, e_1)) ) res = is_product(sep_vec) np.testing.assert_equal(res[0], True)
def test_concurrence_separable(): """The concurrence of a product state is zero.""" e_0, e_1 = basis(2, 0), basis(2, 1) v_vec = np.kron(e_0, e_1) sigma = v_vec * v_vec.conj().T res = concurrence(sigma) np.testing.assert_equal(np.isclose(res, 0), True)
def test_is_mutually_unbiased_basis_dim_2(): """Return True for MUB of dimension 2.""" e_0, e_1 = basis(2, 0), basis(2, 1) mub_1 = [e_0, e_1] mub_2 = [1 / np.sqrt(2) * (e_0 + e_1), 1 / np.sqrt(2) * (e_0 - e_1)] mub_3 = [1 / np.sqrt(2) * (e_0 + 1j * e_1), 1 / np.sqrt(2) * (e_0 - 1j * e_1)] mubs = [mub_1, mub_2, mub_3] np.testing.assert_equal(is_mutually_unbiased_basis(mubs), True)
def test_max_ent_2_0_0(): """Generate maximally entangled state: `|00> + |11>`.""" e_0, e_1 = basis(2, 0), basis(2, 1) expected_res = 1 * (np.kron(e_0, e_0) + np.kron(e_1, e_1)) res = max_entangled(2, False, False) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_domino_4(): """Domino with index = 4.""" e_1, e_2 = basis(3, 1), basis(3, 2) expected_res = np.kron(e_2, 1 / np.sqrt(2) * (e_1 - e_2)) res = domino(4) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_state_distinguishability_three_state_vec(): """State distinguishability for two state vectors.""" e_0, e_1 = basis(2, 0), basis(2, 1) states = [e_0, e_1] probs = [1 / 2, 1 / 2] res = state_distinguishability(states, probs) np.testing.assert_equal(np.isclose(res, 1), True)
def test_domino_2(): """Domino with index = 2.""" e_0, e_1 = basis(3, 0), basis(3, 1) expected_res = np.kron(e_0, 1 / np.sqrt(2) * (e_0 - e_1)) res = domino(2) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_max_ent_2(): """Generate maximally entangled state: `1/sqrt(2) * (|00> + |11>)`.""" e_0, e_1 = basis(2, 0), basis(2, 1) expected_res = 1 / np.sqrt(2) * (np.kron(e_0, e_0) + np.kron(e_1, e_1)) res = max_entangled(2) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_bures_distance_pure_states(): """Test the bures_distance between two pure states.""" e_0, e_1 = basis(2, 0), basis(2, 1) e_plus = (e_0 + e_1) / np.sqrt(2) rho = e_plus * e_plus.conj().T sigma = e_0 * e_0.conj().T np.testing.assert_equal( np.isclose(bures_distance(rho, sigma), 0.765, rtol=1e-03), True)
def test_sub_fidelity_lower_bound_2(): """Test sub_fidelity is lower bound on fidelity for rho and pi.""" e_0, e_1 = basis(2, 0), basis(2, 1) rho = 3 / 4 * e_0 * e_0.conj().T + 1 / 4 * e_1 * e_1.conj().T sigma = 1 / 8 * e_0 * e_0.conj().T + 7 / 8 * e_1 * e_1.conj().T res = sub_fidelity(rho, sigma) np.testing.assert_array_less(res, fidelity(rho, sigma))
def test_domino_8(): """Domino with index = 8.""" e_0, e_1, e_2 = basis(3, 0), basis(3, 1), basis(3, 2) expected_res = np.kron(1 / np.sqrt(2) * (e_0 - e_1), e_2) res = domino(8) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_schmidt_rank_singlet_state(): """ Computing the Schmidt rank of the entangled singlet state should yield a value greater than 1. """ e_0, e_1 = basis(2, 0), basis(2, 1) rho = 1 / np.sqrt(2) * (np.kron(e_0, e_1) - np.kron(e_1, e_0)) np.testing.assert_equal(schmidt_rank(rho) > 1, True)
def test_bell_0(): """Generate the Bell state: `1/sqrt(2) * (|00> + |11>)`.""" e_0, e_1 = basis(2, 0), basis(2, 1) expected_res = 1 / np.sqrt(2) * (np.kron(e_0, e_0) + np.kron(e_1, e_1)) res = bell(0) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_tensor_list_3(): """Test tensor list with three items.""" e_0, e_1 = basis(2, 0), basis(2, 1) expected_res = np.kron(np.kron(e_0, e_1), e_0) res = tensor([e_0, e_1, e_0]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_is_pure_list(): """Check that list of pure states returns True.""" e_0, e_1, e_2 = basis(3, 0), basis(3, 1), basis(3, 2) e0_dm = e_0 * e_0.conj().T e1_dm = e_1 * e_1.conj().T e2_dm = e_2 * e_2.conj().T np.testing.assert_equal(is_pure([e0_dm, e1_dm, e2_dm]), True)
def test_ghz_2_3(): """Produces the 3-qubit GHZ state: `1/sqrt(2) * (|000> + |111>)`.""" e_0, e_1 = basis(2, 0), basis(2, 1) expected_res = 1 / np.sqrt(2) * (tensor(e_0, e_0, e_0) + tensor(e_1, e_1, e_1)) res = ghz(2, 3).toarray() bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True)
def test_concurrence_entangled(): """The concurrence on maximally entangled Bell state.""" e_0, e_1 = basis(2, 0), basis(2, 1) e_00, e_11 = np.kron(e_0, e_0), np.kron(e_1, e_1) u_vec = 1 / np.sqrt(2) * (e_00 + e_11) rho = u_vec * u_vec.conj().T res = concurrence(rho) np.testing.assert_equal(np.isclose(res, 1), True)
def test_unambiguous_state_distinguishability_two_states(): """Unambiguous state distinguishability for two state density matrices.""" e_0, e_1 = basis(2, 0), basis(2, 1) e_00 = e_0 * e_0.conj().T e_11 = e_1 * e_1.conj().T states = [e_00, e_11] probs = [1 / 2, 1 / 2] res = state_distinguishability(states, probs, dist_method="unambiguous") np.testing.assert_equal(np.isclose(res, 1), True)
def test_measure_state(): """Test measure on quantum state.""" e_0, e_1 = basis(2, 0), basis(2, 1) psi = 1 / np.sqrt(3) * e_0 + np.sqrt(2 / 3) * e_1 rho = psi * psi.conj().T proj_0 = e_0 * e_0.conj().T proj_1 = e_1 * e_1.conj().T np.testing.assert_equal(np.isclose(measure(proj_0, rho), 1 / 3), True) np.testing.assert_equal(np.isclose(measure(proj_1, rho), 2 / 3), True)
def test_schmidt_rank_entangled_state(): """Computing Schmidt rank of entangled state should be > 1.""" e_0, e_1 = basis(2, 0), basis(2, 1) phi = ( (1 + np.sqrt(6)) / (2 * np.sqrt(6)) * np.kron(e_0, e_0) + (1 - np.sqrt(6)) / (2 * np.sqrt(6)) * np.kron(e_0, e_1) + (np.sqrt(2) - np.sqrt(3)) / (2 * np.sqrt(6)) * np.kron(e_1, e_0) + (np.sqrt(2) + np.sqrt(3)) / (2 * np.sqrt(6)) * np.kron(e_1, e_1) ) np.testing.assert_equal(schmidt_rank(phi) == 2, True)
def bell(idx: int) -> np.ndarray: r""" Produce a Bell state [WikBell]_. Returns one of the following four Bell states depending on the value of :code:`idx`: .. math:: \begin{equation} \begin{aligned} u_0 = \frac{1}{\sqrt{2}} \left( |00 \rangle + |11 \rangle \right), & \qquad & u_1 = \frac{1}{\sqrt{2}} \left( |00 \rangle - |11 \rangle \right), \\ u_2 = \frac{1}{\sqrt{2}} \left( |01 \rangle + |10 \rangle \right), & \qquad & u_3 = \frac{1}{\sqrt{2}} \left( |01 \rangle - |10 \rangle \right). \end{aligned} \end{equation} Examples ========== When :code:`idx = 0`, this produces the following Bell state .. math:: u_0 = \frac{1}{\sqrt{2}} \left( |00 \rangle + |11 \rangle \right). Using :code:`toqito`, we can see that this yields the proper state. >>> from toqito.states import bell >>> import numpy as np >>> bell(0) [[0.70710678], [0. ], [0. ], [0.70710678]] References ========== .. [WikBell] Wikipedia: Bell state https://en.wikipedia.org/wiki/Bell_state :param idx: A parameter in [0, 1, 2, 3] :return: Bell state with index :code:`idx`. """ e_0, e_1 = basis(2, 0), basis(2, 1) if idx == 0: return 1 / np.sqrt(2) * (np.kron(e_0, e_0) + np.kron(e_1, e_1)) if idx == 1: return 1 / np.sqrt(2) * (np.kron(e_0, e_0) - np.kron(e_1, e_1)) if idx == 2: return 1 / np.sqrt(2) * (np.kron(e_0, e_1) + np.kron(e_1, e_0)) if idx == 3: return 1 / np.sqrt(2) * (np.kron(e_0, e_1) - np.kron(e_1, e_0)) raise ValueError("Invalid integer value for Bell state.")
def test_w_state_3(): """The 3-qubit W-state.""" e_0, e_1 = basis(2, 0), basis(2, 1) expected_res = (1 / np.sqrt(3) * (tensor(e_1, e_0, e_0) + tensor(e_0, e_1, e_0) + tensor(e_0, e_0, e_1))) res = w_state(3) bool_mat = np.isclose(res, expected_res, atol=0.2) np.testing.assert_equal(np.all(bool_mat), True)
def test_schmidt_rank_separable_state(): """ Computing the Schmidt rank of a separable state should yield a value equal to 1. """ e_0, e_1 = basis(2, 0), basis(2, 1) e_00 = np.kron(e_0, e_0) e_01 = np.kron(e_0, e_1) e_10 = np.kron(e_1, e_0) e_11 = np.kron(e_1, e_1) rho = 1 / 2 * (e_00 - e_01 - e_10 + e_11) np.testing.assert_equal(schmidt_rank(rho) == 1, True)