def one_qubit_dm(self, qstate, i): ''' Returns subsystem density matrix for qubit i by tracing out all other qubits in `qstate`. `qstate` needs to be in *full* qubit space! ''' assert qstate.size == qu.prod(self._sim_dims) return qu.ptr(qstate, dims=self._sim_dims, keep=i)
def psi_mb_ab_mat(): return np.concatenate( [rand_ket(prod(DIMS_MB[:7])) for _ in range(6)], axis=1)
def psi_mb_ab(): return rand_ket(prod(DIMS_MB[:7]))
def psi_mb_abc(): return rand_ket(prod(DIMS_MB))
def psi_ab_mat(): return np.concatenate( [rand_ket(prod(DIMS[:-1])) for _ in range(6)], axis=1)
def psi_ab(): return rand_ket(prod(DIMS[:-1]))
def psi_abc(): return rand_ket(prod(DIMS))
def test_lazy_ptr_dot_mat_simple(self, psi_abc, psi_ab_mat): rho_ab = psi_abc.ptr(DIMS, [0, 1]) psi_out_expected = rho_ab @ psi_ab_mat psi_out_got = lazy_ptr_dot(psi_abc, psi_ab_mat) assert psi_out_got.shape == (prod(DIMS[:-1]), 6) assert_allclose(psi_out_expected, psi_out_got)
def test_partial_trace_multi_ket(self): dims = [2, 3, 4] a = np.random.randn(qu.prod(dims), 1) for i1, i2 in itertools.combinations([0, 1, 2], 2): b = qu.partial_trace(a, dims, [i1, i2]) assert (b.shape[1] == dims[i1] * dims[i2])
def test_partial_trace_single_ket(self): dims = [2, 3, 4] a = np.random.randn(qu.prod(dims), 1) for i, dim in enumerate(dims): b = qu.partial_trace(a, dims, i) assert (b.shape[0] == dim)
def test_permute_sparse_op(self): dims = [3, 2, 5, 4] a = qu.rand_rho(qu.prod(dims), sparse=True, density=0.5) b = qu.permute(a, dims, [3, 1, 2, 0]) c = qu.permute(a.A, dims, [3, 1, 2, 0]) assert_allclose(b.A, c)
def test_permute_sparse_ket(self): dims = [3, 2, 5, 4] a = rand_ket(prod(dims), sparse=True, density=0.5) b = permute(a, dims, [3, 1, 2, 0]) c = permute(a.A, dims, [3, 1, 2, 0]) assert_allclose(b.A, c)