def test_dnorm_qubit_triangle(): """ Metrics: checks that dnorm(A + B) ≤ dnorm(A) + dnorm(B). """ def case(A, B, tol=1e-4): assert (dnorm(A + B) <= dnorm(A) + dnorm(B) + tol) for dim in (2, 3): for _ in range(10): yield (case, rand_super_bcsz(dim), rand_super_bcsz(dim))
def test_dnorm_bounded(n_cases=10): """ Metrics: dnorm(A - B) in [0, 2] for random superops A, B. """ def case(A, B, tol=1e-4): # We allow for a generous tolerance so that we don't kill off SCS. assert_(-tol <= dnorm(A, B) <= 2.0 + tol) for _ in range(n_cases): yield case, rand_super_bcsz(3), rand_super_bcsz(3)
def test_chi_choi_roundtrip(self): def case(qobj): qobj = to_chi(qobj) rt_qobj = to_chi(to_choi(qobj)) assert_almost_equal(rt_qobj.data.toarray(), qobj.data.toarray()) assert_equal(rt_qobj.type, qobj.type) assert_equal(rt_qobj.dims, qobj.dims) for N in (2, 4, 8): yield case, rand_super_bcsz(N)
def test_dnorm_qubit_scalar(): """ Metrics: checks that dnorm(a * A) == a * dnorm(A) for scalar a, qobj A. """ def case(a, A, B, significant=5): assert_approx_equal(dnorm(a * A, a * B), a * dnorm(A, B), significant=significant) for dim in (2, 3): for _ in range(10): yield (case, np.random.random(), rand_super_bcsz(dim), rand_super_bcsz(dim))
def test_dnorm_force_solve(self, dim, matrix_generator): """ Metrics: checks that special cases for dnorm agree with SDP solutions. """ if matrix_generator == 'bcsz': A = rand_super_bcsz(dim) B = rand_super_bcsz(dim) elif matrix_generator == 'haar': A = rand_unitary_haar(dim) B = rand_unitary_haar(dim) assert (dnorm(A, B, force_solve=False) == pytest.approx(dnorm( A, B, force_solve=True), abs=1e-5))
def test_dnorm_cptp(): """ Metrics: checks that the diamond norm is one for CPTP maps. """ # NB: It might be worth dropping test_dnorm_force_solve, and separating # into cases for each optimization path. def case(A, significant=4): for force_solve in (False, True): assert_approx_equal(dnorm(A, force_solve=force_solve), 1) for dim in (2, 3): for _ in range(10): yield case, rand_super_bcsz(dim)
def test_dnorm_qubit_triangle(): """ Metrics: checks that dnorm(A + B) ≤ dnorm(A) + dnorm(B). """ def case(A, B, tol=1e-4): assert ( dnorm(A + B) <= dnorm(A) + dnorm(B) + tol ) for dim in (2, 3): for _ in range(10): yield ( case, rand_super_bcsz(dim), rand_super_bcsz(dim) )
def test_call(): """ Test Qobj: Call """ # Make test objects. psi = rand_ket(3) rho = rand_dm_ginibre(3) U = rand_unitary(3) S = rand_super_bcsz(3) # Case 0: oper(ket). assert U(psi) == U * psi # Case 1: oper(oper). Should raise TypeError. with expect_exception(TypeError): U(rho) # Case 2: super(ket). assert S(psi) == vector_to_operator(S * operator_to_vector(ket2dm(psi))) # Case 3: super(oper). assert S(rho) == vector_to_operator(S * operator_to_vector(rho)) # Case 4: super(super). Should raise TypeError. with expect_exception(TypeError): S(S)
def test_dual_channel(sub_dimensions, n_trials=50): """ Qobj: dual_chan() preserves inner products with arbitrary density ops. """ S = rand_super_bcsz(np.prod(sub_dimensions)) S.dims = [[sub_dimensions, sub_dimensions], [sub_dimensions, sub_dimensions]] S = to_super(S) left_dims, right_dims = S.dims # Assume for the purposes of the test that S maps square operators to # square operators. in_dim = np.prod(right_dims[0]) out_dim = np.prod(left_dims[0]) S_dual = to_super(S.dual_chan()) primals = [] duals = [] for _ in [None] * n_trials: X = rand_dm_ginibre(out_dim) X.dims = left_dims X = operator_to_vector(X) Y = rand_dm_ginibre(in_dim) Y.dims = right_dims Y = operator_to_vector(Y) primals.append((X.dag() * S * Y)[0, 0]) duals.append((X.dag() * S_dual.dag() * Y)[0, 0]) np.testing.assert_array_almost_equal(primals, duals)
def test_dual_channel(): """ Qobj: dual_chan() preserves inner products with arbitrary density ops. """ def case(S, n_trials=50): S = to_super(S) left_dims, right_dims = S.dims # Assume for the purposes of the test that S maps square operators to square operators. in_dim = np.prod(right_dims[0]) out_dim = np.prod(left_dims[0]) S_dual = to_super(S.dual_chan()) primals = [] duals = [] for idx_trial in range(n_trials): X = rand_dm_ginibre(out_dim) X.dims = left_dims X = operator_to_vector(X) Y = rand_dm_ginibre(in_dim) Y.dims = right_dims Y = operator_to_vector(Y) primals.append((X.dag() * S * Y)[0, 0]) duals.append((X.dag() * S_dual.dag() * Y)[0, 0]) np.testing.assert_array_almost_equal(primals, duals) for subdims in [[2], [2, 2], [2, 3], [3, 5, 2]]: dim = np.prod(subdims) S = rand_super_bcsz(dim) S.dims = [[subdims, subdims], [subdims, subdims]] yield case, S
def test_dnorm_qubit_scalar(): """ Metrics: checks that dnorm(a * A) == a * dnorm(A) for scalar a, qobj A. """ def case(a, A, B, significant=5): assert_approx_equal( dnorm(a * A, a * B), a * dnorm(A, B), significant=significant ) for dim in (2, 3): for _ in range(10): yield ( case, np.random.random(), rand_super_bcsz(dim), rand_super_bcsz(dim) )
def test_stinespring_cp(self, dimension): """ Stinespring: A and B match for CP maps. """ superop = rand_super_bcsz(dimension) A, B = to_stinespring(superop) assert norm(A - B) < tol
def test_stinespring_agrees(self, thresh=1e-10): """ Stinespring: Partial Tr over pair agrees w/ supermatrix. """ def case(map, state): S = to_super(map) A, B = to_stinespring(map) q1 = vector_to_operator(S * operator_to_vector(state)) # FIXME: problem if Kraus index is implicitly # ptraced! q2 = (A * state * B.dag()).ptrace((0, )) assert_((q1 - q2).norm('tr') <= thresh) for idx in range(4): yield case, rand_super_bcsz(2), rand_dm_ginibre(2)
def test_tensor_swap_other(): dims = (2, 3, 4, 5, 7) for dim in dims: S = to_super(rand_super_bcsz(dim)) # Swapping the inner indices on a superoperator should give a Choi matrix. J = to_choi(S) case_tensor_swap(S, [(1, 2)], [[[dim], [dim]], [[dim], [dim]]], J)
def test_dnorm_on_dense_matrix(self, dim): """ Metrics: Tests sparse versus dense dnorm calculation on dense matrices. """ force_solve = True A = rand_super_bcsz(dim) dense_run_result = dnorm(A, force_solve=force_solve, sparse=False) sparse_run_result = dnorm(A, force_solve=force_solve, sparse=True) assert dense_run_result == pytest.approx(sparse_run_result, abs=1e-7)
def test_unitarity_bounded(nq=3, n_cases=10): """ Metrics: Unitarity in [0, 1]. """ def case(q_oper): assert_(0.0 <= unitarity(q_oper) <= 1.0) for _ in range(n_cases): yield case, rand_super_bcsz(2**nq)
def test_stinespring_cp(self, thresh=1e-10): """ Stinespring: A and B match for CP maps. """ def case(map): A, B = to_stinespring(map) assert_(norm((A - B).data.todense()) < thresh) for idx in range(4): case(rand_super_bcsz(7))
def test_stinespring_cp(self, thresh=1e-10): """ Stinespring: A and B match for CP maps. """ def case(map): A, B = to_stinespring(map) assert_(norm((A - B).data.todense()) < thresh) for idx in range(4): yield case, rand_super_bcsz(7)
def test_chi_choi_roundtrip(self, dimension): superop = rand_super_bcsz(dimension) superop = to_chi(superop) rt_superop = to_chi(to_choi(superop)) dif = norm(rt_superop - superop) assert dif == pytest.approx(0, abs=1e-7) assert rt_superop.type == superop.type assert rt_superop.dims == superop.dims
def test_dnorm_force_solve(): """ Metrics: checks that special cases for dnorm agree with SDP solutions. """ def case(A, B, significant=4): assert_approx_equal(dnorm(A, B, force_solve=False), dnorm(A, B, force_solve=True)) for dim in (2, 3): for _ in range(10): yield (case, rand_super_bcsz(dim), None) for _ in range(10): yield (case, rand_unitary_haar(dim), rand_unitary_haar(dim))
def test_dag_preserves_superrep(): """ Checks that dag() preserves superrep. """ def case(qobj): orig_superrep = qobj.superrep assert_equal(qobj.dag().superrep, orig_superrep) for dim in (2, 4, 8): qobj = rand_super_bcsz(dim) yield case, to_super(qobj) # These two shouldn't even do anything, since qobj # is Hermicity-preserving. yield case, to_choi(qobj) yield case, to_chi(qobj)
def test_dnorm_cptp(): """ Metrics: checks that the diamond norm is one for CPTP maps. """ # NB: It might be worth dropping test_dnorm_force_solve, and separating # into cases for each optimization path. def case(A, significant=4): for force_solve in (False, True): assert_approx_equal( dnorm(A, force_solve=force_solve), 1 ) for dim in (2, 3): for _ in range(10): yield case, rand_super_bcsz(dim)
def test_stinespring_agrees(self, dimension): """ Stinespring: Partial Tr over pair agrees w/ supermatrix. """ map = rand_super_bcsz(dimension) state = rand_dm_ginibre(dimension) S = to_super(map) A, B = to_stinespring(map) q1 = vector_to_operator(S * operator_to_vector(state)) # FIXME: problem if Kraus index is implicitly # ptraced! q2 = (A * state * B.dag()).ptrace((0, )) assert (q1 - q2).norm('tr') <= tol
def test_stinespring_agrees(self, thresh=1e-10): """ Stinespring: Partial Tr over pair agrees w/ supermatrix. """ def case(map, state): S = to_super(map) A, B = to_stinespring(map) q1 = vector_to_operator( S * operator_to_vector(state) ) # FIXME: problem if Kraus index is implicitly # ptraced! q2 = (A * state * B.dag()).ptrace((0,)) assert_((q1 - q2).norm('tr') <= thresh) for idx in range(4): yield case, rand_super_bcsz(2), rand_dm_ginibre(2)
def test_dnorm_force_solve(): """ Metrics: checks that special cases for dnorm agree with SDP solutions. """ def case(A, B, significant=4): assert_approx_equal( dnorm(A, B, force_solve=False), dnorm(A, B, force_solve=True) ) for dim in (2, 3): for _ in range(10): yield ( case, rand_super_bcsz(dim), None ) for _ in range(10): yield ( case, rand_unitary_haar(dim), rand_unitary_haar(dim) )
def test_dual_channel(): """ Qobj: dual_chan() preserves inner products with arbitrary density ops. """ def case(S, n_trials=50): S = to_super(S) left_dims, right_dims = S.dims # Assume for the purposes of the test that S maps square operators to square operators. in_dim = np.prod(right_dims[0]) out_dim = np.prod(left_dims[0]) S_dual = to_super(S.dual_chan()) primals = [] duals = [] for idx_trial in range(n_trials): X = rand_dm_ginibre(out_dim) X.dims = left_dims X = operator_to_vector(X) Y = rand_dm_ginibre(in_dim) Y.dims = right_dims Y = operator_to_vector(Y) primals.append((X.dag() * S * Y)[0, 0]) duals.append((X.dag() * S_dual.dag() * Y)[0, 0]) np.testing.assert_array_almost_equal(primals, duals) for subdims in [ [2], [2, 2], [2, 3], [3, 5, 2] ]: dim = np.prod(subdims) S = rand_super_bcsz(dim) S.dims = [[subdims, subdims], [subdims, subdims]] yield case, S
def test_rand_super_bcsz_cptp(): """ Random Qobjs: Tests that BCSZ-random superoperators are CPTP. """ S = rand_super_bcsz(5) assert_(S.iscptp)
def test_dag_preserves_superrep(dimension, conversion): """ Checks that dag() preserves superrep. """ qobj = conversion(rand_super_bcsz(dimension)) assert qobj.superrep == qobj.dag().superrep
def test_dnorm_cptp(self, dim): """ Metrics: checks that the diamond norm is one for CPTP maps. """ A = rand_super_bcsz(dim) assert 1 == pytest.approx(dnorm(A, force_solve=True), abs=1e-7)