Ejemplo n.º 1
0
def rand_matrix_product_state(n, bond_dim, phys_dim=2, dtype=complex,
                              cyclic=False, trans_invar=False):
    """Generate a random matrix product state (in dense form, see
    :func:`~quimb.tensor.MPS_rand_state` for tensor network form).

    Parameters
    ----------
    n : int
        Number of sites.
    bond_dim : int
        Dimension of the bond (virtual) indices.
    phys_dim : int, optional
        Physical dimension of each local site, defaults to 2 (qubits).
    cyclic : bool (optional)
        Whether to impose cyclic boundary conditions on the entanglement
        structure.
    trans_invar : bool (optional)
        Whether to generate a translationally invariant state,
        requires cyclic=True.

    Returns
    -------
    ket : qarray
        The random state, with shape (phys_dim**n, 1)

    """
    from quimb.tensor import MPS_rand_state

    mps = MPS_rand_state(n, bond_dim, phys_dim=phys_dim, dtype=dtype,
                         cyclic=cyclic, trans_invar=trans_invar)
    return mps.to_dense()
Ejemplo n.º 2
0
 def test_apply_mps(self, cyclic, site_ind_id):
     A = MPO_rand(8, 5, cyclic=cyclic)
     x = MPS_rand_state(8, 4, site_ind_id=site_ind_id, cyclic=cyclic)
     y = A.apply(x)
     assert y.max_bond() == 20
     assert isinstance(y, MatrixProductState)
     assert len(y.tensors) == 8
     assert y.site_ind_id == site_ind_id
     Ad, xd, yd = A.to_dense(), x.to_dense(), y.to_dense()
     assert_allclose(Ad @ xd, yd)
Ejemplo n.º 3
0
 def test_insert_operator(self):
     p = MPS_rand_state(3, 7, tags='KET')
     q = p.H.retag({'KET': 'BRA'})
     qp = q & p
     sz = qu.spin_operator('z').real
     qp.insert_operator(sz, ('KET', 'I1'), ('BRA', 'I1'),
                        tags='SZ', inplace=True)
     assert 'SZ' in qp.tags
     assert len(qp.tensors) == 7
     x1 = qp ^ all
     x2 = qu.expec(p.to_dense(), qu.ikron(sz, [2, 2, 2], inds=1))
     assert x1 == pytest.approx(x2)
Ejemplo n.º 4
0
    def test_schmidt_values_entropy_gap_simple(self):
        n = 12
        p = MPS_rand_state(n, 16)
        p.right_canonize()
        svns = []
        sgs = []
        for i in range(1, n):
            sgs.append(p.schmidt_gap(i, current_orthog_centre=i - 1))
            svns.append(p.entropy(i, current_orthog_centre=i))

        pd = p.to_dense()
        ex_svns = [entropy_subsys(pd, [2] * n, range(i)) for i in range(1, n)]
        ex_sgs = [schmidt_gap(pd, [2] * n, range(i)) for i in range(1, n)]
        assert_allclose(ex_svns, svns)
        assert_allclose(ex_sgs, sgs)
Ejemplo n.º 5
0
 def test_partial_trace(self, rescale):
     n = 10
     p = MPS_rand_state(n, 7)
     r = p.ptr(keep=[2, 3, 4, 6, 8],
               upper_ind_id='u{}',
               rescale_sites=rescale)
     rd = r.to_dense()
     if rescale:
         assert r.lower_inds == ('u0', 'u1', 'u2', 'u3', 'u4')
         assert r.upper_inds == ('k0', 'k1', 'k2', 'k3', 'k4')
     else:
         assert r.lower_inds == ('u2', 'u3', 'u4', 'u6', 'u8')
         assert r.upper_inds == ('k2', 'k3', 'k4', 'k6', 'k8')
     assert_allclose(r.trace(), 1.0)
     assert isherm(rd)
     pd = p.to_dense()
     rdd = pd.ptr([2] * n, keep=[2, 3, 4, 6, 8])
     assert_allclose(rd, rdd)
Ejemplo n.º 6
0
 def test_partial_trace(self, rescale, keep):
     n = 10
     p = MPS_rand_state(n, 7)
     r = p.ptr(keep=keep, upper_ind_id='u{}', rescale_sites=rescale)
     rd = r.to_dense()
     if isinstance(keep, slice):
         keep = p.slice2sites(keep)
     else:
         if rescale:
             assert r.lower_inds == ('u0', 'u1', 'u2', 'u3', 'u4')
             assert r.upper_inds == ('k0', 'k1', 'k2', 'k3', 'k4')
         else:
             assert r.lower_inds == ('u2', 'u3', 'u4', 'u6', 'u8')
             assert r.upper_inds == ('k2', 'k3', 'k4', 'k6', 'k8')
     assert_allclose(r.trace(), 1.0)
     assert qu.isherm(rd)
     pd = p.to_dense()
     rdd = pd.ptr([2] * n, keep=keep)
     assert_allclose(rd, rdd)
Ejemplo n.º 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)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    def test_entropy_matches_dense(self, method):
        p = MPS_rand_state(5, 32)
        p_dense = p.to_dense()
        real_svn = qu.entropy(p_dense.ptr([2] * 5, [0, 1, 2]))

        svn = (p ^ ...).entropy(('k0', 'k1', 'k2'))
        assert_allclose(real_svn, svn)

        # use tensor to left of bipartition
        p.canonize(2)
        t1 = p['I2']
        left_inds = set(t1.inds) - set(p['I3'].inds)
        svn = (t1).entropy(left_inds, method=method)
        assert_allclose(real_svn, svn)

        # use tensor to right of bipartition
        p.canonize(3)
        t2 = p['I3']
        left_inds = set(t2.inds) & set(p['I2'].inds)
        svn = (t2).entropy(left_inds, method=method)
        assert_allclose(real_svn, svn)