def test_both_mixed(self, p1, p2): f = qu.fidelity(qu.eye(3) / 3, qu.eye(3) / 3) assert_allclose(f, 1.0) f = qu.fidelity(p1, p1) assert_allclose(f, 1.0) f = qu.fidelity(p1, p2) assert f > 0 and f < 1
def test_eye(self, herm, sparse): if sparse: with pytest.raises(NotImplementedError): p = qu.sqrtm(qu.eye(2, sparse=sparse), herm=herm) else: p = qu.sqrtm(qu.eye(2), herm=herm) assert_allclose(p, qu.eye(2))
def gen_term(self, sites=None): """Generate the interaction term acting on ``sites``. """ # make sure have sites as (i, i + 1) if supplied if sites is not None: i, j = sites = tuple(sorted(sites)) if j - i != 1: raise ValueError("Only nearest neighbour interactions are " "supported for an ``NNI``.") else: i = j = None term = self.H2s.get(sites, self.H2s[None]) if term is None: raise ValueError("No term has been set for sites {}, either specif" "ically or via a default term.".format(sites)) # add single site term to left site if present H1 = self.H1s.get(i, self.H1s[None]) # but only if this site has a term set if H1 is not None: I_2 = qu.eye(H1.shape[0], dtype=H1.dtype) term = term + qu.kron(H1, I_2) # if not PBC, for the last interaction, add to right site as well if sites and (j == self.n - 1) and (not self.cyclic): H1 = self.H1s.get(j, self.H1s[None]) # but again, only if that site has a term set if H1 is not None: I_2 = qu.eye(H1.shape[0], dtype=H1.dtype) term = term + qu.kron(I_2, H1) return term
def test_rand_uni(self, dtype): u = qu.rand_uni(3, dtype=dtype) assert u.shape == (3, 3) assert type(u) == qu.qarray assert u.dtype == dtype # low tolerances for float32 etc assert_allclose(qu.eye(3), u @ u.H, atol=1e-7, rtol=1e-5) assert_allclose(qu.eye(3), u.H @ u, atol=1e-7, rtol=1e-5)
def test_unitary_vectors(self, bigsparsemat, SVDType): a = bigsparsemat uk, sk, vk = svds_slepc(a, k=10, return_vecs=True, SVDType=SVDType) assert_allclose(uk.H @ uk, eye(10), atol=1e-6) assert_allclose(vk @ vk.H, eye(10), atol=1e-6) pk, lk, qk = svds_scipy(a, k=10, return_vecs=True) assert_allclose(sk, lk) assert pk.shape == uk.shape assert vk.shape == qk.shape assert_allclose(abs(uk.H @ pk), eye(10), atol=1e-6) assert_allclose(abs(qk @ vk.H), eye(10), atol=1e-6)
def test_dop_reverse_sparse(self): a = rand_rho(4, sparse=True, density=0.5) b = perm_eyepad(a, np.array([2, 2, 2]), [2, 0]) c = (a & eye(2)).A.reshape([2, 2, 2, 2, 2, 2]) \ .transpose([1, 2, 0, 4, 5, 3]) \ .reshape([8, 8]) assert_allclose(b.A, c)
def test_dop_reverse(self): a = rand_rho(4) b = perm_eyepad(a, np.array([2, 2, 2]), [2, 0]) c = (a & eye(2)).A.reshape([2, 2, 2, 2, 2, 2]) \ .transpose([1, 2, 0, 4, 5, 3]) \ .reshape([8, 8]) assert_allclose(b, c)
def test_dop_spread(self): a = rand_rho(4) b = perm_eyepad(a, [2, 2, 2], [0, 2]) c = (a & eye(2)).A.reshape([2, 2, 2, 2, 2, 2]) \ .transpose([0, 2, 1, 3, 5, 4]) \ .reshape([8, 8]) assert_allclose(b, c)
def test_2d_simple(self): a = (rand_matrix(2), rand_matrix(2)) dims = ((2, 3), (3, 2)) inds = ((0, 0), (1, 1)) b = eyepad(a, dims, inds) assert b.shape == (36, 36) assert_allclose(b, a[0] & eye(9) & a[1])
def test_ndarrays(self): a = rand_matrix(2) i = eye(2) b = eyepad([a], np.array([2, 2, 2]), [0, 2]) assert_allclose(b, a & i & a) b = eyepad([a], [2, 2, 2], np.array([0, 2])) assert_allclose(b, a & i & a)
def test_mid_multi(self): a = [rand_matrix(2) for i in range(3)] i = eye(2) dims = [2, 2, 2, 2, 2, 2] inds = [1, 2, 4] b = eyepad(a, dims, inds) assert_allclose(b, i & a[0] & a[1] & i & a[2] & i)
def test_dop_reverse_sparse(self): a = qu.rand_rho(4, sparse=True, density=0.5) b = qu.pkron(a, np.array([2, 2, 2]), [2, 0]) c = ((a & qu.eye(2)).A.reshape([2, 2, 2, 2, 2, 2]).transpose([1, 2, 0, 4, 5, 3]).reshape([8, 8])) assert_allclose(b.A, c)
def test_dop_reverse(self): a = qu.rand_rho(4) b = qu.pkron(a, np.array([2, 2, 2]), [2, 0]) c = ((a & qu.eye(2)).A.reshape([2, 2, 2, 2, 2, 2]).transpose([1, 2, 0, 4, 5, 3]).reshape([8, 8])) assert_allclose(b, c)
def test_2d_simple(self): a = (qu.rand_matrix(2), qu.rand_matrix(2)) dims = ((2, 3), (3, 2)) inds = ((0, 0), (1, 1)) b = qu.ikron(a, dims, inds) assert b.shape == (36, 36) assert_allclose(b, a[0] & qu.eye(9) & a[1])
def test_dop_spread(self): a = qu.rand_rho(4) b = qu.pkron(a, [2, 2, 2], [0, 2]) c = ((a & qu.eye(2)).A.reshape([2, 2, 2, 2, 2, 2]).transpose([0, 2, 1, 3, 5, 4]).reshape([8, 8])) assert_allclose(b, c)
def test_ndarrays(self): a = qu.rand_matrix(2) i = qu.eye(2) b = qu.ikron([a], np.array([2, 2, 2]), [0, 2]) assert_allclose(b, a & i & a) b = qu.ikron([a], [2, 2, 2], np.array([0, 2])) assert_allclose(b, a & i & a)
def test_mid_multi_reverse(self): a = [qu.rand_matrix(2) for i in range(3)] i = qu.eye(2) dims = [2, 2, 2, 2, 2, 2] inds = [5, 4, 1] b = qu.ikron(a, dims, inds) assert_allclose(b, i & a[2] & i & i & a[1] & a[0])
def test_cross_equality(self, mat_herm_sparse, k, which): _, a = mat_herm_sparse sigma = 1 if which in {None, "TR"} else None lks, vks = zip(*(qu.eigh(a, k=k, which=which, sigma=sigma, backend=b) for b in eigs_backends)) lks, vks = tuple(lks), tuple(vks) for i in range(len(lks) - 1): assert_allclose(lks[i], lks[i + 1]) assert_allclose(abs(vks[i].H @ vks[i + 1]), qu.eye(k), atol=1e-14)
def spin_numberop(self, spin): ''' TODO: why can't use ikron()? Fermionic number operator acting on `spin` sector. ''' #which fermion-spin sector to act on? #i.e. act on qbit 0 or qbit 1? opmap = { 0: lambda: qu.qu([[0, 0], [0, 1]]) & qu.eye(2), 1: lambda: qu.eye(2) & qu.qu([[0, 0], [0, 1]]) } op = opmap[spin]() qu.core.make_immutable(op) return op
def test_sparse(self): i = qu.eye(2, sparse=True) a = qu.qu(qu.rand_matrix(2), sparse=True) b = qu.ikron(a, [2, 2, 2], 1) # infer sparse assert (qu.issparse(b)) assert_allclose(b.A, (i & a & i).A) a = qu.rand_matrix(2) b = qu.ikron(a, [2, 2, 2], 1, sparse=True) # explicit sparse assert (qu.issparse(b)) assert_allclose(b.A, (i & a & i).A)
def test_sparse(self): i = eye(2, sparse=True) a = qu(rand_matrix(2), sparse=True) b = eyepad(a, [2, 2, 2], 1) # infer sparse assert(issparse(b)) assert_allclose(b.A, (i & a & i).A) a = rand_matrix(2) b = eyepad(a, [2, 2, 2], 1, sparse=True) # explicit sparse assert(issparse(b)) assert_allclose(b.A, (i & a & i).A)
def test_gate2split(self): psi = MPS_rand_state(10, 3) psi2 = psi.copy() G = qu.eye(2) & qu.eye(2) psi.gate2split(G, (2, 3), cutoff=0) assert psi.bond_size(2, 3) == 6 assert psi.H @ psi2 == pytest.approx(1.0) # check a unitary application G = qu.rand_uni(2**2) psi.gate2split(G, (7, 8)) psi.compress() assert psi.bond_size(2, 3) == 3 assert psi.bond_size(7, 8) > 3 assert psi.H @ psi == pytest.approx(1.0) assert abs(psi2.H @ psi) < 1.0 # check matches dense application of gate psid = psi2.to_dense() Gd = qu.ikron(G, [2] * 10, (7, 8)) assert psi.to_dense().H @ (Gd @ psid) == pytest.approx(1.0)
def test_subsystem(self): rho = qu.rand_rho(6) dims = [3, 2] I, X, Y, Z = (qu.pauli(s) for s in 'IXYZ') mi_i = qu.mutual_information(rho, dims) p = 0.1 Ek = [(1 - p)**0.5 * I, (p / 3)**0.5 * X, (p / 3)**0.5 * Y, (p / 3)**0.5 * Z] with pytest.raises(ValueError): qu.kraus_op(rho, qu.randn((3, 2, 2)), check=True, dims=dims, where=1) sigma = qu.kraus_op(rho, Ek, check=True, dims=dims, where=1) mi_f = qu.mutual_information(sigma, dims) assert mi_f < mi_i assert qu.tr(sigma) == pytest.approx(1.0) sig_exp = sum( (qu.eye(3) & E) @ rho @ qu.dag(qu.eye(3) & E) for E in Ek) assert_allclose(sig_exp, sigma)
def test_basic(self): a = qu.rand_matrix(2) i = qu.eye(2) dims = [2, 2, 2] b = qu.ikron([a], dims, [0]) assert_allclose(b, a & i & i) b = qu.ikron([a], dims, [1]) assert_allclose(b, i & a & i) b = qu.ikron([a], dims, [2]) assert_allclose(b, i & i & a) b = qu.ikron([a], dims, [0, 2]) assert_allclose(b, a & i & a) b = qu.ikron([a], dims, [0, 1, 2]) assert_allclose(b, a & a & a)
def _two_site_nnint_mpo(self, third_site_identity=False): '''Two-site nearest-neighbor interaction, optionally padded with an identity to act on a third site. ''' Nop = number_op() site_tag = self._site_tag_id if third_site_identity: oplist = [ Nop.reshape(2, 2, 1), Nop.reshape(1, 2, 2, 1), qu.eye(2).reshape(1, 2, 2) ] else: oplist = [Nop.reshape(2, 2, 1), Nop.reshape(1, 2, 2)] return qtn.MatrixProductOperator(arrays=oplist, shape='ludr', site_tag_id=site_tag)
def jw_annihil_op(self, k, spin): ''' Annihilation Jordan-Wigner qubit operator, acting on site `k` and `spin` sector. (Z_0)x(Z_1)x ...x(Z_k-1)x |0><1|_k ''' spin = {0: 0, 1: 1, 'up': 0, 'down': 1, 'u': 0, 'd': 1}[spin] Z, I = qu.pauli('z'), qu.eye(2) s_minus = qu.qu([[0, 1], [0, 0]]) #|0><1| N = self._Nverts Z_sig = {0: Z & I, 1: I & Z}[spin] s_minus_sig = {0: s_minus & I, 1: I & s_minus}[spin] op_list = [Z_sig for i in range(k)] + [s_minus_sig] ind_list = [i for i in range(k + 1)] return qu.ikron(ops=op_list, dims=self._dims, inds=ind_list)
def jw_creation_op(self, k, spin): ''' Jordan-Wigner transformed creation operator, for site k and `spin` sector (Z_0)x(Z_1)x ...x(Z_k-1)x |1><0|_k ''' spin = {0: 0, 1: 1, 'up': 0, 'down': 1, 'u': 0, 'd': 1}[spin] Z, I = qu.pauli('z'), qu.eye(2) s_plus = qu.qu([[0, 0], [1, 0]]) N = self._Nverts Z_sig = {0: Z & I, 1: I & Z}[spin] s_plus_sig = {0: s_plus & I, 1: I & s_plus}[spin] op_list = [Z_sig for i in range(k)] + [s_plus_sig] ind_list = [i for i in range(k + 1)] return qu.ikron(ops=op_list, dims=self._dims, inds=ind_list)
def test_eye(self, sparse, herm): p = qu.expm(qu.eye(2, sparse=sparse), herm=herm) assert_allclose((p.A if sparse else p) / np.e, qu.eye(2)) if sparse: assert isinstance(p, sp.csr_matrix)
def test_zeros_dense(self, herm): p = qu.expm(np.zeros((2, 2), dtype=complex), herm=herm) assert_allclose(p, qu.eye(2))
def test_bell_state(self): a = qu.bell_state('psi-', sparse=True) b = qu.core._trace_keep(a @ a.H, [2, 2], 0) assert_allclose(b, qu.eye(2) / 2) b = qu.core._trace_keep(a @ a.H, [2, 2], 1) assert_allclose(b, qu.eye(2) / 2)