示例#1
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
示例#2
0
def test_unequal_site_dim_thermal_state_generation(L, system_index, beta, nof_steps, mpa_type):
    """
        Pytest test for generating a thermal state via imaginary time evolution for a chain with unequal site dimensions
    :param beta: Inverse temperature of the final state
    :param nof_steps: number of steps in the propagation grid
    :return:
    """
    sys_site_op = fock.n(3)
    bath_site_op = pauli.Z
    sys_couple_op = fock.a(3) + fock.a_dag(3)
    bath_couple_op = pauli.X
    seed = 42
    rank = 1

    exdiag_state, dims, ed_site_ops, ed_bond_ops, tm_state, tm_site_ops, tm_bond_ops = \
        star_test_generator.generate_irregular_mps_test(L, system_index, sys_site_op, bath_site_op,
                                                        sys_couple_op, bath_couple_op, seed=seed, rank=rank)
    op_compression = {'method': 'svd', 'relerr': 1e-12}
    state_compression = {'method': 'svd', 'relerr': 1e-10}
    exdiag_thermal = exdiag.generate_thermal_state(beta, dims, system_index, ed_site_ops, ed_bond_ops)
    # Setup for tMPS evolution
    tmps_thermal, info = thermal.from_hamiltonian(beta, mpa_type, system_index, tm_site_ops, tm_bond_ops,
                                                  nof_steps=nof_steps,
                                                  state_compression_kwargs=state_compression,
                                                  op_compression_kwargs=op_compression)
    if mpa_type == 'pmps':
        tmps_thermal = mp.pmps_to_mpo(tmps_thermal)
    normdiff = np.linalg.norm(exdiag_thermal - tmps_thermal.to_array_global().reshape(np.prod(dims, dtype=int),
                                                                                      np.prod(dims, dtype=int)))
    assert normdiff < 1e-8
示例#3
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)
示例#4
0
def test_unequal_site_dim_thermal_state_generation(beta, nof_steps, mpa_type):
    """
        Pytest test for generating a thermal state via imaginary time evolution for a chain with unequal site dimensions
        for spin operators with local dimensions [2, 4, 4] in the chain
    :param beta: Inverse temperature of the final state
    :param nof_steps: number of steps in the propagation grid
    :return:
    """
    site_dims = [2, 4, 4]

    site_ops = [pauli.X, np.kron(pauli.X, pauli.X), np.kron(pauli.X, pauli.X)]
    dim4_op = np.kron(pauli.X, pauli.Z)
    bond_ops = [np.kron(pauli.X, dim4_op), np.kron(dim4_op, dim4_op)]
    exdiag_thermal = exdiag.generate_thermal_state(beta, site_dims, site_ops,
                                                   bond_ops)
    # Setup for tMPS evolution
    state_compress_kwargs = {'method': 'svd', 'relerr': 1e-10}
    tmps_thermal, info = thermal.from_hamiltonian(
        beta,
        mpa_type,
        site_ops,
        bond_ops,
        nof_steps=nof_steps,
        state_compression_kwargs=state_compress_kwargs,
        op_compression_kwargs=None)
    global_dim = np.prod(site_dims, dtype=int)
    if mpa_type == 'pmps':
        tmps_thermal = mp.pmps_to_mpo(tmps_thermal)
    normdiff = np.linalg.norm(
        np.abs(exdiag_thermal -
               tmps_thermal.to_array_global().reshape(global_dim, global_dim)))
    assert normdiff < 1e-8
示例#5
0
def test_thermal_state_generation(L, beta, nof_steps, mpa_type):
    """
        Pytest test for generating a thermal state via imaginary time evolution for a spin chain
    :param L: Size of the chain
    :param beta: Inverse temperature of the final state
    :param nof_steps: number of steps in the propagation grid
    :return:
    """
    site_dim = 2
    site_dims = [site_dim] * L

    site_op = pauli.X
    bond_op = np.kron(pauli.X, pauli.Z)
    exdiag_thermal = exdiag.generate_thermal_state(beta, site_dims,
                                                   repeat(site_op, L),
                                                   repeat(bond_op, L - 1))
    # Setup for tMPS evolution
    state_compress_kwargs = {'method': 'svd', 'relerr': 1e-10, 'sites_step': 3}
    tmps_thermal, info = thermal.from_hamiltonian(
        beta,
        mpa_type, [site_op] * L, [bond_op] * (L - 1),
        nof_steps=nof_steps,
        state_compression_kwargs=state_compress_kwargs,
        op_compression_kwargs=None)
    if mpa_type == 'pmps':
        tmps_thermal = mp.pmps_to_mpo(tmps_thermal)
    normdiff = np.linalg.norm(
        exdiag_thermal -
        tmps_thermal.to_array_global().reshape(site_dim**L, site_dim**L))
    assert normdiff < 1e-8
示例#6
0
def test_irregular_chain(sot, nof_steps, tau):
    """
        Pytest test for time evolution of a mixed quantum state in mpo 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.  Those are constructed from
        random hermitian matrices
        The physical dimension of each site (site_dim) is allowed to vary from site to site!
        The test is perfomed for one random Hamiltonian for an even L chain of the form [2, 4, 3, 5]
        for different time discretizations.
    :param nof_steps: Number of time evolution steps
    :param tau: Timestep in each step of the time evolution
    :return:
    """
    # Parameters for the chain:
    # Chain shape:
    site_dims = [2, 4, 3, 2]
    # Site local initial states
    psi_1, psi_2, psi_3, psi_4 = np.array([0, 1], dtype=float), np.array([0, 1, 0, 0], dtype=float), \
                                 np.array([0, 0, 1], dtype=float), np.array([0, 1], dtype=float)
    # Generate site and bond operators of random hamiltonian
    random_sites = [np.random.rand(2, 2), np.random.rand(4, 4), np.random.rand(3, 3), np.random.rand(2, 2)]
    random_bonds = [np.random.rand(8, 8), np.random.rand(12, 12), np.random.rand(6, 6)]
    # Make them hermitian
    site_ops = [(site + site.T.conj()) / 2 for site in random_sites]
    bond_ops = [(bond + bond.T.conj()) / 2 for bond in random_bonds]
    # Put initial states together
    psi_0 = np.kron(np.kron(np.kron(psi_1, psi_2), psi_3), psi_4)
    rho_0 = np.outer(psi_0, psi_0.conj())
    # Setup for exact diagonalization
    exdiag_mixed_propagator = exdiag.ExDiagPropagator(rho_0, site_dims, site_ops, bond_ops, 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}
    mps_psi_0 = np.copy(psi_0).reshape(*site_dims)
    mps = mp.MPArray.from_array(mps_psi_0, ndims=1)
    pmps = mp.mps_to_pmps(mps)
    tmps_propagator = from_hamiltonian(pmps, 'pmps', site_ops, bond_ops, tau=tau,
                                       state_compression_kwargs=state_compress_kwargs,
                                       op_compression_kwargs=op_compression_kwargs,
                                       second_order_trotter=sot)

    # Propagataion loop
    normdist = []
    for step in range(nof_steps):
        exdiag_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(int(np.prod(site_dims)), int(np.prod(site_dims)))
        normdist.append(np.linalg.norm(tmps_rho_t_array - exdiag_mixed_propagator.psi_t))

    max_normdist = np.max(np.array(normdist))
    if sot:
        assert np.max(max_normdist) < 1e-6
    else:
        assert np.max(max_normdist) < 1e-8
示例#7
0
def test_regular_chain(L, sot, nof_steps, tau):
    """
        Pytest test for time evolution of a mixed quantum state in pmps 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. Those are constructed from
        pauli spin operators.
        The physical dimension of each site (site_dim) is constant d(=2 here)
        Tests are performed for different chain lengths and different time discretizations
        The initial state is a superposition product state
    :param L: Chain L
    :param nof_steps: Number of time evolution steps
    :param tau: Timestep in each step of the time evolution
    :return:
    """
    #Parameters
    psi_i = np.array([1.0, 1.0])
    psi_i /= np.linalg.norm(psi_i)
    psi_0 = kron.generate_product_state(psi_i, L)
    rho_0 = np.outer(psi_0, psi_0.conj())

    site_dim = 2
    site_dims = [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}
    mps_psi_0 = np.copy(psi_0).reshape(*site_dims)
    mps = mp.MPArray.from_array(mps_psi_0, ndims=1)
    pmps = mp.mps_to_pmps(mps)
    tmps_propagator = from_hamiltonian(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
示例#8
0
def sandwich_mpa(op, psi, mpa_type):
    """
        Calculates <op>_{psi} = tr(op*psi) for a state of specified mpa_type
    """
    if mpa_type == 'mps':
        psi = mp.mps_to_mpo(psi)
    elif mpa_type == 'pmps':
        psi = mp.pmps_to_mpo(psi)
    elif mpa_type == 'mpo':
        pass
    else:
        raise AssertionError('Unknown mpa_type')
    return mp.trace(mp.dot(op, psi))
示例#9
0
def test_pmps_thermal_state(L, dim, beta):
    """
        Pytest test for calculating the norm  of nearest neighbor Hamiltonians
        with equal site dimension
    :param L: Size of the chain
    :return:
    """
    n = fock.n(dim)
    thermal_exact = [np.diag(np.exp(-beta*np.diag(n)))/ np.sum(np.exp(-beta*np.diag(n)))]*L
    thermal_test = get_thermal_state(beta, [n]*L, 'pmps' , as_type='mparray_list', to_cform=None)
    normdist = []
    for exact, test in zip(thermal_exact, thermal_test):
        normdist.append(np.linalg.norm(exact - mp.MPArray.to_array_global(mp.pmps_to_mpo(test))))
    assert np.max(normdist) < 1e-8
示例#10
0
def to_ndarray(psi, mpa_type):
    """
        Convert mpnum MPArray to numpy ndarray. Allowed mpa_types are 'mps', 'mpo', and 'pmps'
    """
    if isinstance(psi, mp.MPArray):
        if mpa_type == 'mps':
            return psi.to_array()
        elif mpa_type == 'mpo':
            return psi.to_array_global()
        elif mpa_type == 'pmps':
            return mp.pmps_to_mpo(psi).to_array_global()
        else:
            raise AssertionError('Unrecognized mpa_type')
    elif isinstance(psi, np.ndarray):
        pass
    else:
        raise AssertionError('Unrecognized data type for psi')
示例#11
0
def _propagation(propagator, nof_steps, to_mpo, verbose):
    """
        Performs imaginary time evolution of the passed propagator. If to_mpo is set True, the state
        will be converted to an mpo before returning
    """
    if verbose:
        print('Starting propagtion')
    for step in range(nof_steps):
        propagator.evolve()
        if verbose:
            print('Step {:d}:'.format(step + 1))
            print(propagator.psi_t.ranks)
    if to_mpo:
        psi_t = mp.pmps_to_mpo(propagator.psi_t)
    else:
        psi_t = propagator.psi_t
    if verbose:
        print('Propagation finished')
    return psi_t, propagator.info()
    def test_pmps_trotter2(self):
        n = 5  # number of sites

        state = self.state(n=n)
        J = 1
        B = 1
        times = [1, 2]
        hamiltonian = self.hamiltonian(n=n, J=J, B=B)

        mpo_state = tmps.matrix_to_mpo(state, [[2, 2]] * n)
        pmps_state = mp.mpo_to_pmps(mpo_state)

        num_trotter_slices = 102

        times, sites, evolved_states, errors1, errors2 = \
            tmps.evolve(state=pmps_state, hamiltonians=[B * self.sx(),
                                                        J * np.kron(self.sz(),
                                                                    self.sz())],
                        ts=times, num_trotter_slices=num_trotter_slices,
                        method='pmps',
                        trotter_compr=dict(method='svd', relerr=1e-20),
                        trotter_order=2, compr=dict(method='svd', relerr=1e-20))

        rho_t_arr = [
            self.exp(state=state, hamiltonian=hamiltonian, t=times[i])
            for i in range(len(times))
        ]

        rho_t_pmps = [
            mp.pmps_to_mpo(evolved_states[i]).to_array_global().reshape(
                [2**n, 2**n]) for i in range(len(times))
        ]

        fidelities = [
            np.trace(
                sqrtm(
                    sqrtm(rho_t_arr[i]).dot(rho_t_pmps[i]).dot(
                        sqrtm(rho_t_arr[i])))) for i in range(len(times))
        ]

        for i in range(len(times)):
            assert np.isclose(1, fidelities[i], rtol=self.precision)
示例#13
0
def state_reduction(psi, mpa_type, startsite=0, nof_sites=1):
    """
        Calculates reduced state as mpo for psi as mps, mpo or pmps
        for site 1 to site nof_sites from the start of the chain:
        So we get a reduced state for the indices s_i,..,s_{nof_sites}
    :param psi: State to generate reduced state from as mps, pmps or mpo
    :param mpa_type: mpa type of psi (mps, pmo or pmps)
    :param startsite: first site of the reduced state (may be negative, indexing works like for python lists)
    :param nof_sites: number of sites up to which (starting from startsite) the reduced state should be generated
    :return: reduced state as mpo
    """
    assert len(psi) > 0
    if startsite < 0:
        # Out of bounds index check
        assert startsite >= -len(psi)
        # Convert negative startsite to a positive one
        startsite = len(psi) + startsite
    # Out of bounds index check
    assert startsite + nof_sites <= len(psi)
    if mpa_type == 'mps':
        return next(
            mp.reductions_mps_as_mpo(psi,
                                     width=nof_sites,
                                     startsites=range(startsite,
                                                      startsite + 1)))
    elif mpa_type == 'mpo':
        return next(
            mp.reductions_mpo(psi,
                              width=nof_sites,
                              startsites=range(startsite, startsite + 1)))
    elif mpa_type == 'pmps':
        return mp.pmps_to_mpo(
            next(
                mp.reductions_pmps(psi,
                                   width=nof_sites,
                                   startsites=range(startsite,
                                                    startsite + 1))))
    else:
        raise AssertionError('Invalid propagator')
示例#14
0
def generate_regular_pmps_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 PMPS.
            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:
        psi_0 = kron.generate_product_state(single_state, L)
        exdiag_state = np.outer(psi_0, psi_0.conj())
        psi_0_mps = mp.MPArray.from_array(exdiag_state.reshape(tuple([2] * L)),
                                          ndims=1)
        tm_state = mp.mps_to_pmps(psi_0_mps)
    else:
        rng = np.random.RandomState(seed=seed)
        tm_state = mp.random_mpa(sites=L,
                                 ldim=(2, 2),
                                 rank=rank,
                                 randstate=rng,
                                 normalized=True)
        mpo_rho_0 = mp.pmps_to_mpo(tm_state)
        exdiag_state = mp.MPArray.to_array_global(mpo_rho_0).reshape(
            2**L, 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
示例#15
0
def reduction(propagator, startsite=0, nof_sites=1):
    """
        Calculates reduced state as mpo for the psi_t of a TMPSPropagator object
        for site 1 to site nof_sites from the start of the chain:
        So weg get a reduced state for the indices s_i,..,s_{nof_sites}
    :param propagator: TMPSPropagator object from whcih we take the state psi_t for generation of the reduced state
    :param startsite: first site of the reduced state (may be negative, indexing works like for python lists)
    :param nof_sites: number of sites up to which (starting from startsite) the reduced state should be generated
    :return: reduced state as mpo
    """
    assert len(propagator.psi_t) > 0
    if startsite < 0:
        # Out of bounds index check
        assert startsite >= -len(propagator.psi_t)
        # Convert negative startsite to a positive one
        startsite = len(propagator.psi_t) + startsite
    # Out of bounds index check
    assert startsite + nof_sites <= len(propagator.psi_t)
    if propagator.mpa_type == 'mps':
        return next(
            mp.reductions_mps_as_mpo(propagator.psi_t,
                                     width=nof_sites,
                                     startsites=range(startsite,
                                                      startsite + 1)))
    elif propagator.mpa_type == 'mpo':
        return next(
            mp.reductions_mpo(propagator.psi_t,
                              width=nof_sites,
                              startsites=range(startsite, startsite + 1)))
    elif propagator.mpa_type == 'pmps':
        return mp.pmps_to_mpo(
            next(
                mp.reductions_pmps(propagator.psi_t,
                                   width=nof_sites,
                                   startsites=range(startsite,
                                                    startsite + 1))))
    else:
        raise AssertionError('Invalid propagator')
示例#16
0
def generate_irregular_pmps_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 PMPS.
            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, bath_dim)] * system_index + [
        (sys_dim, sys_dim)
    ] + [(bath_dim, bath_dim)] * (L - system_index - 1)
    tm_state = mp.random_mpa(sites=L,
                             ldim=tuple(ldim),
                             rank=rank,
                             randstate=rng,
                             normalized=True)
    mpo_rho_0 = mp.pmps_to_mpo(tm_state)
    exdiag_state = mp.MPArray.to_array_global(mpo_rho_0).reshape(
        bath_dim**(L - 1) * sys_dim,
        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
示例#17
0
def test_irregular_chain(L, system_index, sot, nof_steps, tau):
    """
        Pytest test for time evolution of a mixed quantum state in mpo form under a Hamiltonian of the form:
        sum_i^L H_{i} + sum_j^(L-1) H_{system_index, j}
        where the H_(i) are called site ops and the H_{i, i+1} are called bond ops, constructed from ladder operators
        and pauli operators.
        The physical dimension of the system site is different from the bath sites
        Tests are performed for different chain lengths and different time discretizations
        The initial state is a random state
    :param L: Chain L
    :param system_index: Index of the system site in the chain
    :param sot: second order trotter evolution switch
    :param nof_steps: Number of time evolution steps
    :param tau: Timestep in each step of the time evolution
    :return:
    """
    sys_site_op = fock.n(3)
    bath_site_op = pauli.Z
    sys_couple_op = fock.a(3) + fock.a_dag(3)
    bath_couple_op = pauli.X
    seed = 42
    rank = 1

    exdiag_state, dims, ed_site_ops, ed_bond_ops, tm_state, tm_site_ops, tm_bond_ops = \
        star_test_generator.generate_irregular_pmps_test(L, system_index, sys_site_op, bath_site_op,
                                                         sys_couple_op, bath_couple_op, seed=seed, rank=rank)
    op_compression = {'method': 'svd', 'relerr': 1e-12}
    state_compression = {
        'method': 'svd',
        'relerr': 1e-10,
        'sites_relerr': 1e-12
    }

    tm_prop = from_hamiltonian(tm_state,
                               'pmps',
                               system_index,
                               tm_site_ops,
                               tm_bond_ops,
                               tau=tau,
                               op_compression_kwargs=op_compression,
                               state_compression_kwargs=state_compression,
                               second_order_trotter=sot)

    ed_prop = StarExDiagPropagator(exdiag_state,
                                   dims,
                                   system_index,
                                   ed_site_ops,
                                   ed_bond_ops,
                                   tau,
                                   state_type='op')
    normdist = []
    for i in range(nof_steps):
        tm_prop.evolve()
        ed_prop.evolve()
        tmps_psi_t_array = mp.MPArray.to_array_global(
            mp.pmps_to_mpo(tm_prop.psi_t)).reshape(np.prod(dims, dtype=int),
                                                   np.prod(dims, dtype=int))
        diff = tmps_psi_t_array - ed_prop.psi_t
        normdist.append(np.linalg.norm(diff))
    max_normdist = np.max(np.array(normdist))
    if sot:
        assert np.max(max_normdist) < 1e-6
    else:
        assert np.max(max_normdist) < 1e-8