Beispiel #1
0
    def run(seed):
        rgen = numpy.random.RandomState(seed)
        X = mpnum.random_mpa(sites, dim, rank, randstate=rgen, normalized=True)
        nr_measurements = int(C * dim * sites * rank**2 * numpy.log2(rank + 1))
        A = [
            mpnum.random_mpa(len(X),
                             X.pdims,
                             1,
                             randstate=rgen,
                             normalized=True,
                             dtype=X.dtype) for _ in range(nr_measurements)
        ]
        y = [inner_prod_mps(a, X) for a in A]

        X_sharp = AltminEstimator(A, y, rank).estimate(maxiter,
                                                       thresh=dist_crit)

        return {
            'X': X,
            'X_sharp': X_sharp,
            'dist': mpnum.normdist(X, X_sharp),
            'C': C,
            'seed': seed,
            'dim': dim,
            'rank': rank,
            'sites': sites
        }
Beispiel #2
0
def get_random_mpa(mpa_type, dims, seed=102, rank=1):
    """
        Returns a random normalized mpa of specified type ('mps', 'mpo', 'pmps'), specified physical dimensions (dims),
        rank and numpy seed.
    """
    rng = np.random.RandomState(seed=seed)
    if mpa_type == 'mps':
        shape = get_shape_from_dims(dims)
        return mp.random_mpa(sites=len(shape),
                             ldim=shape,
                             rank=rank,
                             randstate=rng,
                             normalized=True,
                             force_rank=True)
    elif mpa_type == 'pmps':
        shape = get_shape_from_dims(dims, dims)
        return mp.random_mpa(sites=len(shape),
                             ldim=shape,
                             rank=rank,
                             randstate=rng,
                             normalized=True,
                             force_rank=True)
    elif mpa_type == 'mpo':
        shape = get_shape_from_dims(dims, dims)
        pmps = mp.random_mpa(sites=len(shape),
                             ldim=shape,
                             rank=rank,
                             randstate=rng,
                             normalized=True,
                             force_rank=True)
        return mp.pmps_to_mpo(pmps)
Beispiel #3
0
def test_recover(sites, dim, rank):
    X = mp.random_mpa(sites, dim, rank, normalized=True)
    measurements = 5 * sites * rank**2 * dim
    A = [mp.random_mpa(sites, dim, 1) for _ in range(measurements)]
    Y = [mp.special.inner_prod_mps(a, X) for a in A]

    estimator = AltminEstimator(A, Y, 2 * rank)
    X_hat = next(it.islice(estimator, 10, 11))
    assert mp.normdist(X, X_hat) < 1e-3
Beispiel #4
0
def test_partial_inner_prod():
    sites = 4
    dim = 4
    a = mp.random_mpa(sites, dim, 1)
    b = mp.random_mpa(sites, dim, 1)
    a_dot_b = mp.inner(a, b)

    partial_a_dot_b = list(partial_inner_prod(a, b, 'right'))
    nptest.assert_allclose(a_dot_b, partial_a_dot_b[-1])

    partial_a_dot_b = list(partial_inner_prod(a, b, 'left'))
    nptest.assert_allclose(a_dot_b, partial_a_dot_b[-1])
Beispiel #5
0
def test_optimmat(sites, dim, rank):
    X = mp.random_mpa(sites, dim, rank, normalized=True)
    measurements = 5 * sites * rank**2 * dim
    A = [mp.random_mpa(sites, dim, 1) for _ in range(measurements)]
    Y = [mp.special.inner_prod_mps(a, X) for a in A]

    estimator = AltminEstimator(A, Y, 2 * rank)

    for pos, B in estimator._get_optimmat(X, direction='right'):
        B_ = np.array([_get_optimmat_row(a, X, pos) for a in A])
        nptest.assert_allclose(B, B_)

    for pos, B in estimator._get_optimmat(X, direction='left'):
        B_ = np.array([_get_optimmat_row(a, X, pos) for a in A])
        nptest.assert_allclose(B, B_)
Beispiel #6
0
def generate_irregular_mps_test(L,
                                system_index,
                                sys_site_op,
                                bath_site_op,
                                sys_couple_op,
                                bath_couple_op,
                                seed=42,
                                rank=2):
    """
            See get_operators for an explanation for most of the parameters. Additionally generates a random MPS.
            System and Bath operators may be of any dimension
        :returns: Initial state for exact diagonalization, dimensions of the chain, exact diagonalization site operators,
                  exact diagonalization bond operators, TMP initial state, TMP site operators, TMP bond operators
    """
    assert L > 2
    assert sys_site_op.shape == sys_couple_op.shape and bath_couple_op.shape == bath_site_op.shape
    bath_dim = bath_site_op.shape[0]
    sys_dim = sys_site_op.shape[0]
    dims = [bath_dim] * system_index + [sys_dim
                                        ] + [bath_dim] * (L - system_index - 1)
    rng = np.random.RandomState(seed=seed)
    ldim = [(bath_dim, )] * system_index + [
        (sys_dim, )
    ] + [(bath_dim, )] * (L - system_index - 1)
    tm_state = mp.random_mpa(sites=L,
                             ldim=tuple(ldim),
                             rank=rank,
                             randstate=rng,
                             normalized=True)
    exdiag_state = tm_state.to_array().reshape(bath_dim**(L - 1) * sys_dim)
    ed_site_ops, ed_bond_ops, tm_site_ops, tm_bond_ops = \
        get_operators(L, system_index, sys_site_op, bath_site_op, sys_couple_op, bath_couple_op)
    return exdiag_state, dims, ed_site_ops, ed_bond_ops, tm_state, tm_site_ops, tm_bond_ops
Beispiel #7
0
def generate_regular_mps_test(L,
                              system_index,
                              sys_site_op,
                              bath_site_op,
                              sys_couple_op,
                              bath_couple_op,
                              single_state=None,
                              seed=42,
                              rank=2):
    """
            See get_operators for an explanation for most of the parameters. Additionally generates a random MPS.
            Operators must be 2x2 Matrices
        :returns: Initial state for exact diagonalization, dimensions of the chain, exact diagonalization site operators,
                  exact diagonalization bond operators, TMP initial state, TMP site operators, TMP bond operators
    """
    assert L > 2
    assert sys_site_op.shape == bath_site_op.shape == sys_couple_op.shape == bath_couple_op.shape == (
        2, 2)
    dims = [2] * L
    if single_state is not None:
        exdiag_state = kron.generate_product_state(single_state, L)
        tm_state = mp.MPArray.from_array(exdiag_state.reshape(tuple([2] * L)),
                                         ndims=1)
    else:
        rng = np.random.RandomState(seed=seed)
        tm_state = mp.random_mpa(sites=L,
                                 ldim=2,
                                 rank=rank,
                                 randstate=rng,
                                 normalized=True)
        exdiag_state = tm_state.to_array().reshape(2**L)
    ed_site_ops, ed_bond_ops, tm_site_ops, tm_bond_ops = \
        get_operators(L, system_index, sys_site_op, bath_site_op, sys_couple_op, bath_couple_op)
    return exdiag_state, dims, ed_site_ops, ed_bond_ops, tm_state, tm_site_ops, tm_bond_ops
Beispiel #8
0
def test_calculate_expectation_values(sites, dim):
    mpo = mp.random_mpa(sites=sites, ldim=(dim, dim), rank=1)
    obsvbl = np.random.random([dim**sites] * 2)
    expct_value1 = np.trace(
        np.dot(mpo.to_array_global().reshape([dim**sites] * 2), obsvbl))
    expct_value2 = tm.calculate_expectation_values([mpo], obsvbl)[0]
    assert_almost_equal(expct_value1, expct_value2)
Beispiel #9
0
def test_regular_chain_random(L, sot, nof_steps, tau):
    """
        Pytest test for time evolution of a pure quantum state in mps form under a Hamiltonian of the form:
        sum_i^L H_{i} + sum_i^(L-1) H_{i, i+1}
        where the H_(i) are called site ops and the H_{i, i+1} are called bond ops, both are randomized.
        The physical dimension of each site (site_dim) is constant d!
        Tests are performed for different chain lengths and different time discretizations.
        The initial state is randomized.
    :param L: Chain L
    :param nof_steps: Number of time evolution steps
    :param tau: Timestep in each step of the time evolution
    :return:
    """
    site_dim = 2
    site_dims = [site_dim] * L

    # Generate random density operator by using a random mps and contracting over auxiliary legs
    rng = np.random.RandomState(seed=103)
    random_pmps = mp.random_mpa(sites=L, ldim=(site_dim, site_dim), rank=2, randstate=rng, normalized=True)
    mpo_rho_0 = mp.pmps_to_mpo(random_pmps)
    rho_0 = mp.MPArray.to_array_global(mpo_rho_0).reshape(site_dim ** L, site_dim ** L)

    site_op = pauli.Z
    bond_op = np.kron(pauli.Z, pauli.X)

    # Setup for exact diagonalization

    exact_mixed_propagator = exdiag.ExDiagPropagator(rho_0, site_dims, repeat(site_op, L),
                                                     repeat(bond_op, L - 1), tau,
                                                     state_type='op')

    # Setup for tMPS evolution
    state_compress_kwargs = {'method': 'svd', 'relerr': 1e-10, 'sites_relerr': 1e-12}
    op_compression_kwargs = {'method': 'svd', 'relerr': 1e-13}
    tmps_propagator = from_hamiltonian(random_pmps, 'pmps', site_op, bond_op, tau=tau,
                                       state_compression_kwargs=state_compress_kwargs,
                                       op_compression_kwargs=op_compression_kwargs,
                                       second_order_trotter=sot)

    normdist = []
    itno = 0
    for step in range(nof_steps):
        exact_mixed_propagator.evolve()
        tmps_propagator.evolve()

        mpo_t = mp.pmps_to_mpo(tmps_propagator.psi_t)
        tmps_rho_t_array = mp.MPArray.to_array_global(mpo_t).reshape(site_dim ** L, site_dim ** L)
        normdist.append(np.linalg.norm(tmps_rho_t_array - exact_mixed_propagator.psi_t))
        itno += 1
    max_normdist = np.max(np.array(normdist))
    if sot:
        assert np.max(max_normdist) < 1e-6
    else:
        assert np.max(max_normdist) < 1e-8