示例#1
0
 def test_basic(self, rand_rank):
     rho = qu.rand_rho(9)
     ln = qu.logneg(rho, [3, 3])
     for p in (0.2, 0.5, 0.8, 1.0):
         rho_d = qu.dephase(rho, p, rand_rank=rand_rank)
         assert qu.logneg(rho_d, [3, 3]) <= ln
         assert rho_d.tr() == pytest.approx(1.0)
示例#2
0
 def test_subsystem(self):
     p = qu.singlet_pairs(4)
     rhoab = p.ptr([2, 2, 2, 2], [0, 1])
     assert qu.logneg(rhoab, [2] * 2) > 1 - 1e-14
     rhoab = p.ptr([2, 2, 2, 2], [1, 2])
     assert qu.logneg(rhoab, [2] * 2) < 1e-14
     rhoab = p.ptr([2, 2, 2, 2], [2, 3])
     assert qu.logneg(rhoab, [2] * 2) > 1 - 1e-14
示例#3
0
    def test_entanglement(self):
        rho = qu.rand_seperable([2, 3, 2], 10)
        assert_allclose(qu.tr(rho), 1.0)
        assert qu.isherm(rho)

        assert qu.logneg(rho, [2, 6]) < 1e-12
        assert qu.logneg(rho, [6, 2]) < 1e-12

        rho_a = qu.ptr(rho, [2, 3, 2], 1)

        el = qu.eigvalsh(rho_a)
        assert np.all(el < 1 - 1e-12)
        assert np.all(el > 1e-12)
示例#4
0
    def test_entanglement(self):
        rho = rand_seperable([2, 3, 2], 10)
        assert_almost_equal(tr(rho), 1.0)
        assert isherm(rho)

        assert logneg(rho, [2, 6]) < 1e-12
        assert logneg(rho, [6, 2]) < 1e-12

        rho_a = ptr(rho, [2, 3, 2], 1)

        el = eigvals(rho_a)
        assert np.all(el < 1 - 1e-12)
        assert np.all(el > 1e-12)
示例#5
0
    def test_quevo_multi_compute(self, method, qtype):

        ham = ham_heis(2, cyclic=False)
        p0 = qu(up() & down(), qtype=qtype)

        def some_quantity(t, _):
            return t

        def some_other_quantity(_, pt):
            return logneg(pt)

        evo = QuEvo(p0,
                    ham,
                    method=method,
                    compute={
                        't': some_quantity,
                        'logneg': some_other_quantity
                    })
        manual_lns = []
        for pt in evo.at_times(np.linspace(0, 1, 6)):
            manual_lns.append(logneg(pt))
        ts = evo.results['t']
        lns = evo.results['logneg']
        assert len(lns) >= len(manual_lns)
        # check a specific value of logneg at t=0.8 was computed automatically
        checked = False
        for t, ln in zip(ts, lns):
            if abs(t - 0.8) < 1e-12:
                assert abs(ln - manual_lns[4]) < 1e-12
                checked = True
        assert checked
示例#6
0
 def test_logneg_approx_many_body(self, psi_mb_abc, bsz):
     sysa = [0, 1, 7, 8]
     sysb = [2, 3, 9]
     rho_ab = psi_mb_abc.ptr(DIMS_MB, sysa + sysb)
     actual_ln = logneg(rho_ab, [2] * 7, sysa=(0, 1, 4, 5))
     approx_ln = logneg_subsys_approx(psi_mb_abc, DIMS_MB,
                                      sysa=sysa, sysb=sysb, bsz=bsz)
     assert_allclose(actual_ln, approx_ln, rtol=1e-1)
示例#7
0
    def test_bipartite_schmidt_state(self):
        psi = MPS_rand_state(16, 5)
        psid = psi.to_dense()
        eln = qu.logneg(psid, [2**7, 2**9])

        s_d_ket = psi.bipartite_schmidt_state(7, get='ket-dense')
        ln_d_ket = qu.logneg(s_d_ket, [5, 5])
        assert_allclose(eln, ln_d_ket, rtol=1e-5)

        s_d_rho = psi.bipartite_schmidt_state(7, get='rho-dense')
        ln_d_rho = qu.logneg(s_d_rho, [5, 5])
        assert_allclose(eln, ln_d_rho, rtol=1e-5)

        T_s_ket = psi.bipartite_schmidt_state(7, get='ket')
        assert set(T_s_ket.inds) == {'kA', 'kB'}
        assert_allclose(T_s_ket.H @ T_s_ket, 1.0)

        T_s_rho = psi.bipartite_schmidt_state(7, get='rho')
        assert set(T_s_rho.outer_inds()) == {'kA', 'kB', 'bA', 'bB'}
        assert_allclose(T_s_rho.H @ T_s_rho, 1.0)
示例#8
0
 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)
示例#9
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)
示例#10
0
 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)
示例#11
0
    def test_quevo_compute_callback(self, qtype, method):
        ham = ham_heis(2, cyclic=False)
        p0 = qu(up() & down(), qtype=qtype)

        def some_quantity(t, pt):
            return t, logneg(pt)

        evo = QuEvo(p0, ham, method=method, compute=some_quantity)
        manual_lns = []
        for pt in evo.at_times(np.linspace(0, 1, 6)):
            manual_lns.append(logneg(pt))
        ts, lns = zip(*evo.results)
        assert len(lns) >= len(manual_lns)
        # check a specific value of logneg at t=0.8 was computed automatically
        checked = False
        for t, ln in zip(ts, lns):
            if abs(t - 0.8) < 1e-12:
                assert abs(ln - manual_lns[4]) < 1e-12
                checked = True
        assert checked
示例#12
0
    def test_evo_multi_compute(self, method, qtype):

        ham = qu.ham_heis(2, cyclic=False)
        p0 = qu.qu(qu.up() & qu.down(), qtype=qtype)

        def some_quantity(t, _):
            return t

        def some_other_quantity(_, pt):
            return qu.logneg(pt)

        # check that hamiltonian gets accepted without error for all methods
        def some_other_quantity_accepting_ham(t, pt, H):
            return qu.logneg(pt)

        compute = {
            't': some_quantity,
            'logneg': some_other_quantity,
            'logneg_ham': some_other_quantity_accepting_ham
        }

        evo = qu.Evolution(p0, ham, method=method, compute=compute)
        manual_lns = []
        for pt in evo.at_times(np.linspace(0, 1, 6)):
            manual_lns.append(qu.logneg(pt))
        ts = evo.results['t']
        lns = evo.results['logneg']
        lns_ham = evo.results['logneg_ham']
        assert len(lns) >= len(manual_lns)
        # check a specific value of logneg at t=0.8 was computed automatically
        checked = False
        for t, ln, ln_ham in zip(ts, lns, lns_ham):
            if abs(t - 0.8) < 1e-12:
                assert abs(ln - manual_lns[4]) < 1e-12
                # check that accepting hamiltonian didn't mess it up
                assert ln == ln_ham
                checked = True
        assert checked
示例#13
0
 def test_logneg_approx_simple(self, psi_abc, bsz):
     rho_ab = psi_abc.ptr(DIMS, [0, 1])
     actual_ln = logneg(rho_ab, DIMS[:-1], 0)
     approx_ln = logneg_subsys_approx(psi_abc, DIMS, 0, 1, bsz=bsz)
     assert_allclose(actual_ln, approx_ln, rtol=2e-1)
示例#14
0
 def test_bell_states(self, qtype, bs):
     p = qu.bell_state(bs, qtype=qtype)
     assert qu.logneg(p) > 1.0 - 1e-14
示例#15
0
 def some_quantity(t, pt):
     return t, logneg(pt)
示例#16
0
 def some_other_quantity(_, pt):
     return logneg(pt)
示例#17
0
 def test_interleaving(self):
     p = permute(singlet() & singlet(), [2, 2, 2, 2], [0, 2, 1, 3])
     assert logneg(p, [2] * 4, sysa=[0, 3]) > 2 - 1e-13
示例#18
0
 def some_other_quantity_accepting_ham(t, pt, H):
     return qu.logneg(pt)
示例#19
0
 def test_interleaving(self):
     p = qu.permute(qu.singlet() & qu.singlet(), [2, 2, 2, 2], [0, 2, 1, 3])
     assert qu.logneg(p, [2] * 4, sysa=[0, 3]) > 2 - 1e-13