def test_kron_basic(self, parallel): a = qu.rand_ket(2) b = qu.rand_ket(4) c = qu.rand_ket(4) d = qu.rand_ket(5) t = qu.kron(a, b, c, d, parallel=parallel) assert_allclose(t, a & b & c & d)
def test_bell_state(self): p = qu.bell_state('psi-') assert_allclose(qu.schmidt_gap(p, [2, 2], 0), 0.0) p = qu.up() & qu.down() assert_allclose(qu.schmidt_gap(p, [2, 2], 0), 1.0) p = qu.rand_ket(2**3) assert 0 < qu.schmidt_gap(p, [2] * 3, sysa=[0, 1]) < 1.0
def test_bell_state(self): p = bell_state('psi-') assert_allclose(schmidt_gap(p, [2, 2], 0), 0.0) p = up() & down() assert_allclose(schmidt_gap(p, [2, 2], 0), 1.0) p = rand_ket(2**3) assert 0 < schmidt_gap(p, [2] * 3, sysa=[0, 1]) < 1.0
def test_quantum_discord_pure(self): for _ in range(10): p = qu.rand_ket(4) p = p @ p.H iab = qu.mutual_information(p) qd = qu.quantum_discord(p) assert_allclose(iab / 2, qd)
def test_from_dense(self): psi = qu.rand_ket(2**8) mps = MatrixProductState.from_dense(psi, dims=[2] * 8) assert mps.tags == {'I{}'.format(i) for i in range(8)} assert mps.site_inds == tuple('k{}'.format(i) for i in range(8)) assert mps.nsites == 8 mpod = mps.to_dense() assert qu.expec(mpod, psi) == pytest.approx(1)
def test_bigger(self): psi = qu.rand_ket(2**5) assert np.sum(abs(psi) < 1e-12) == 0 A = qu.kronpow(qu.pauli('Z'), 5) res, psi_after = qu.measure(psi, A, eigenvalue=-1.0) # should have projected to half subspace assert np.sum(abs(psi_after) < 1e-12) == 2**4 assert res == -1.0
def test_vec_dense(self): a = qu.rand_ket(4) b = qu.core._trace_keep(a, [2, 2], 0) c = qu.partial_trace(a.A, [2, 2], 0) assert_allclose(b, c) b = qu.core._trace_keep(a, [2, 2], 1) c = qu.partial_trace(a.A, [2, 2], 1) assert_allclose(b, c)
def test_vec_dense(self): a = rand_ket(4) b = _trace_lose(a, [2, 2], 1) c = partial_trace(a.A, [2, 2], 0) assert_allclose(b, c) b = _trace_lose(a, [2, 2], 0) c = partial_trace(a.A, [2, 2], 1) assert_allclose(b, c)
def test_mutinf_subsys_pure(self): p = rand_ket(2**7) dims = (2**3, 2**4) # exact mi0 = mutual_information(p, dims, sysa=0) mi1 = mutinf_subsys(p, dims, sysa=0, sysb=1, approx_thresh=1e30) assert_allclose(mi1, mi0) # approx mi2 = mutinf_subsys(p, dims, sysa=0, sysb=1, approx_thresh=1) assert_allclose(mi1, mi2, rtol=5e-2)
def test_entropy_subsystem(self): p = rand_ket(2**9) # exact e1 = entropy_subsys(p, (2**5, 2**4), 0, approx_thresh=1e30) # approx e2 = entropy_subsys(p, (2**5, 2**4), 0, approx_thresh=1) assert e1 != e2 assert_allclose(e1, e2, rtol=5e-2) assert entropy_subsys(p, (2**5, 2**4), [0, 1], approx_thresh=1) == 0.0
def test_expm_slepc(self, expm_backend): ham = qu.ham_mbl(7, dh=0.5, sparse=True) psi = qu.rand_ket(2**7) evo_exact = qu.Evolution(psi, ham, method='solve') evo_slepc = qu.Evolution(psi, ham, method='expm', expm_backend=expm_backend) ts = np.linspace(0, 100, 6) for p1, p2 in zip(evo_exact.at_times(ts), evo_slepc.at_times(ts)): assert abs(qu.expec(p1, p2) - 1) < 1e-9
def test_mutinf_subsys(self): p = qu.rand_ket(2**9) dims = (2**3, 2**2, 2**4) # exact rho_ab = qu.ptr(p, dims, [0, 2]) mi0 = qu.mutual_information(rho_ab, [8, 16]) mi1 = qu.mutinf_subsys(p, dims, sysa=0, sysb=2, approx_thresh=1e30) assert_allclose(mi1, mi0) # approx mi2 = qu.mutinf_subsys(p, dims, sysa=0, sysb=2, approx_thresh=1) assert_allclose(mi1, mi2, rtol=0.1)
def test_exp_sparse(self): a = rand_herm(100, sparse=True, density=0.1) k = rand_ket(100) out = mfn_multiply_slepc(a, k) al, av = eigh(a.A) expected = av @ np.diag(np.exp(al)) @ av.conj().T @ k assert_allclose(out, expected)
def test_construct(self, gate, dtype, sparse): if gate in ('Rx', 'Ry', 'Rz', 'phase_gate'): args = (0.43827, ) elif gate in ('U_gate'): args = (0.1, 0.2, 0.3) else: args = () G = getattr(qu, gate)(*args, dtype=dtype, sparse=sparse) assert G.dtype == dtype assert qu.issparse(G) is sparse psi = qu.rand_ket(G.shape[0]) Gpsi = G @ psi assert qu.expec(Gpsi, Gpsi) == pytest.approx(1.0)
def test_logneg_subsys_pure_should_swap_subsys(self): p = qu.rand_ket(2**(5 + 2)) dims = (2**5, 2**2) sysa = 0 sysb = 1 # exact 1 ln0 = qu.logneg(p, dims, 0) # exact 2 ln1 = qu.logneg_subsys(p, dims, sysa, sysb, approx_thresh=1e30) assert_allclose(ln0, ln1) # approx ln2 = qu.logneg_subsys(p, dims, sysa, sysb, approx_thresh=1, tol=0.005) assert ln1 != ln2 assert_allclose(ln1, ln2, rtol=0.2)
def test_logneg_subsys_pure(self): p = qu.rand_ket(2**(3 + 4)) dims = (2**3, 2**4) sysa = 0 sysb = 1 # exact 1 ln0 = qu.logneg(p, dims, 0) # exact 2 ln1 = qu.logneg_subsys(p, dims, sysa, sysb, approx_thresh=1e30) assert_allclose(ln0, ln1) # approx ln2 = qu.logneg_subsys(p, dims, sysa, sysb, approx_thresh=1, tol=5e-3) assert ln1 != ln2 assert_allclose(ln1, ln2, rtol=1e-1)
def test_logneg_subsys(self): p = qu.rand_ket(2**(2 + 3 + 1 + 2)) dims = (2**2, 2**3, 2**1, 2**2) sysa = [0, 3] sysb = 1 # exact 1 ln0 = qu.logneg(qu.ptr(p, dims, [0, 1, 3]), [4, 8, 4], [0, 2]) # exact 2 ln1 = qu.logneg_subsys(p, dims, sysa, sysb, approx_thresh=1e30) assert_allclose(ln0, ln1) # approx ln2 = qu.logneg_subsys(p, dims, sysa, sysb, approx_thresh=1) assert ln1 != ln2 assert_allclose(ln1, ln2, rtol=5e-2)
def test_sqrt_sparse(self): import scipy.sparse as sp a = rand_pos(32, sparse=True, density=0.1) a = a + 0.001 * sp.eye(32) k = rand_ket(32) out = mfn_multiply_slepc(a, k, fntype='sqrt', isherm=True) al, av = eigh(a.A) al[al < 0] = 0.0 # very small neg values spoil sqrt expected = av @ np.diag(np.sqrt(al)) @ av.conj().T @ k assert_allclose(out, expected, rtol=1e-6)
def test_expm_krylov_expokit(self): ham = rand_herm(100, sparse=True, density=0.8) psi = rand_ket(100) evo_exact = QuEvo(psi, ham, method='solve') evo_krylov = QuEvo(psi, ham, method='expm', expm_backend='slepc-krylov') evo_expokit = QuEvo(psi, ham, method='expm', expm_backend='slepc-expokit') ts = np.linspace(0, 100, 21) for p1, p2, p3 in zip(evo_exact.at_times(ts), evo_krylov.at_times(ts), evo_expokit.at_times(ts)): assert abs(expec(p1, p2) - 1) < 1e-9 assert abs(expec(p1, p3) - 1) < 1e-9
def ham_rcr_psi(): # Define a random hamiltonian with a known recurrence time d = 3 np.random.seed(1) ems = np.random.randint(1, 6, d) ens = np.random.randint(1, 6, d) # eigenvalues as rational numbers # numerator lowest common divisor LCD = reduce(gcd, ems) # denominator lowest common multiple LCM = reduce(lambda a, b: a * b // gcd(a, b), ens) trc = 2 * pi * LCM / LCD evals = np.array(ems) / np.array(ens) v = rand_uni(d) ham = v @ np.diag(evals) @ v.H p0 = rand_ket(d) tm = 0.573 * trc pm = v @ np.diag(np.exp(-1.0j * tm * evals)) @ v.H @ p0 return ham, trc, p0, tm, pm
def test_swap_higher_dim(self, sparse): a = qu.rand_ket(9) s = qu.swap(3, sparse=sparse) assert_allclose(s @ a, a.reshape([3, 3]).T.reshape([9, 1]))
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 ket_d2(): return rand_ket(_TEST_SZ)
def test_permute_sparse_ket(self): dims = [3, 2, 5, 4] a = qu.rand_ket(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_partial_trace_simple_ket(self): a = qu.rand_ket(12, sparse=True, density=0.5) dims = [2, 3, 2] b = qu.partial_trace(a, dims, [0, 1]) c = qu.partial_trace(a.A, dims, [0, 1]) assert_allclose(b, c)