Пример #1
0
def test_mpo_trotter2():
    n = 4  # number of sites

    state = generate_state(n=n)
    J = 1
    B = 1
    times = [1, 2]
    hamiltonian = generate_hamiltonian(n=n, J=J, B=B)

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

    num_trotter_slices = 101

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

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

    rho_t_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_mpo[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=precision)
    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)
Пример #3
0
def tedopa1(h_loc, a, state, method, trotter_compr, compr, j, domain,
            ts_full, ts_system, g, trotter_order=2, num_trotter_slices=100,
            ncap=20000, v=False):
    """
    Mapping the Hamiltonian of a system composed of one site, linearly coupled
    to a reservoir of bosonic modes, to a 1D chain and performing time evolution

    Args:
        h_loc (numpy.ndarray): Local Hamiltonian of the one site system
        a (numpy.ndarray): Interaction operator defined as A_hat in the paper
        state (mpnum.MPArray): The state of the system which is to be
            evolved.
        method (str): The form of the state, determining the method used
            in the calculations. Either 'mps', 'mpo' or 'pmps'.
        trotter_compr (dict):
            Compression parameters used in the iterations of Trotter (in the
            form used by mpnum.compress())
        compr (dict): Parameters for the compression which is executed on every
            MPA during the calculations, except for the Trotter calculation,
            where trotter_compr is used.
            compr = dict(method='svd', rank=10) would for example ensure that
            the ranks of any MPA never exceed 10 during all of the calculations.
        j (types.LambdaType): spectral function J(omega) as defined in the paper
        domain (list[float]): Domain on which j is defined,
            for example [0, np.inf]
        ts_full (list[float]): The times for which the evolution should
            be computed and the whole state chain returned.
        ts_system (list[float]): The times for which the evolution should be
            computed and the reduced density matrix of only the system should be
            returned.
        g (float): Constant g, assuming that for J(omega) it is g(omega)=g*omega
        trotter_order (int):
            Order of trotter to be used. Currently only 2 and 4
            are implemented
        num_trotter_slices (int): Number of Trotter slices to be used for the
            largest t in ts_full or ts_system.
            If ts_system=[10, 25, 30] and num_trotter_slices=100,
            then the program would use 100/30*10=33, 100/30*25=83 and
            100/30*30=100 Trotter slices to calculate the time evolution for the
            three times.
        ncap (int):
            Number internally used by py-orthpol. Must be <= 60000,
            the higher the longer the calculation of the recurrence
            coefficients takes and the more accurate it becomes.
        v (bool): Verbose or not verbose (will print what is going on vs.
            won't print anything)

    Returns:
        list[list[float], list[mpnum.MPArray]]:
            An array of times and an array of the corresponding evolved states
    """
    state_shape = state.shape

    if len(domain) != 2:
        raise ValueError("Domain needs to be of the form [x1, x2]")
    if len(a) != state_shape[0][0]:
        raise ValueError(
            "Dimension of 'a' must be the same as that of the \
            first site of the chain.")
    if len(state_shape) < 2:
        raise ValueError("The provided state has no chain representing "
                         "the mapped environment")

    if v:
        print("Calculating the TEDOPA mapping...")

    singlesite_ops, twosite_ops = map(h_loc, a, state_shape,
                                      j, domain, g, ncap)
    
    if v:
        print("Proceeding to tmps...")

    ts, subsystems = get_times(ts_full, ts_system, len(state), 0, 1)

    times, subsystems, states, compr_errors, trot_errors = tmps.evolve(
        state=state, hamiltonians=[singlesite_ops, twosite_ops], ts=ts,
        subsystems=subsystems,
        num_trotter_slices=num_trotter_slices, method=method,
        trotter_compr=trotter_compr, trotter_order=trotter_order,
        compr=compr, v=v)
    return times, states
Пример #4
0
def tedopa2(h_loc, a_twosite, state, method, sys_position, trotter_compr, compr, js,
            domains, ts_full, ts_system, gs=(1, 1), trotter_order=2,
            num_trotter_slices=100,
            ncap=20000, v=False):
    """
    Mapping the Hamiltonian of a system composed of two sites, each linearly
    coupled to a reservoir of bosonic modes, to a 1D chain and performing
    time evolution.

    The first elements in the lists js, domains, etc. always refer to the
    first(left) site and the second elements in the lists refer to the
    second (right) site of the system

    Args:
        h_loc (numpy.ndarray): Local Hamiltonian of the two site system
        a_twosite (list[numpy.ndarray]): The two interaction operators defined as
            A_hat in the paper
        state (mpnum.MPArray): The state of the system which is to be
            evolved.
        method (str): The form of the state, determining the method used
            in the calculations. Either 'mps', 'mpo' or 'pmps'.
        sys_position (int): Which index, in the chain representing the state, is
            the position of the first site of the system (starting at 0).
            E.g. 2 if the chain sites are
            environment-environment-system-system-environment-environment
        trotter_compr (dict):
            Compression parameters used in the iterations of Trotter (in the
            form used by mpnum.compress())
        compr (dict): Parameters for the compression which is executed on every
            MPA during the calculations, except for the Trotter calculation,
            where trotter_compr is used.
            compr = dict(method='svd', rank=10) would for example ensure that
            the ranks of any MPA never exceed 10 during all of the calculations.
        js (list[types.LambdaType]): spectral functions J(omega) for both
            environments as defined in the paper
        domains (list[list[float]]): Domains on which the js are defined,
            for example [[0, np.inf], [0,1]]
        ts_full (list[float]): The times for which the evolution should
            be computed and the whole state chain returned.
        ts_system (list[float]): The times for which the evolution should be
            computed and the reduced density matrix of only the system should be
            returned.
        gs (list[float]): Constant g, assuming that for J(omega) it is
            g(omega) = g * omega
        trotter_order (int):
            Order of trotter to be used. Currently only 2 and 4
            are implemented
        num_trotter_slices (int): Number of Trotter slices to be used for the
            largest t in ts_full or ts_system.
            If ts_system=[10, 25, 30] and num_trotter_slices=100,
            then the program would use 100/30*10=33, 100/30*25=83 and
            100/30*30=100 Trotter slices to calculate the time evolution for the
            three times.
        ncap (int):
            Number internally used by py-orthpol. Must be <= 60000,
            the higher the longer the calculation of the recurrence
            coefficients takes and the more accurate it becomes.
        v (bool): Verbose or not verbose (will print what is going on vs.
            won't print anything)

    Returns:
        list[list[float], list[mpnum.MPArray]]:
            An array of times and an array of the corresponding evolved states
    """
    state_shape = state.shape
    # ToDo: Implement some checks, like above
    if v:
        print("Calculating the TEDOPA mapping...")
    left_ops = map(np.zeros([state_shape[sys_position][0]] * 2),
                   a_twosite[0], list(reversed(state_shape[:sys_position + 1:])),
                   js[0], domains[0], gs[0], ncap)
    singlesite_ops_left, twosite_ops_left = [list(reversed(i)) for i in
                                             left_ops]
    singlesite_ops_right, twosite_ops_right = \
        map(np.zeros([state_shape[sys_position + 1][0]] * 2), a_twosite[1],
            list(state_shape[sys_position + 1::]), js[1], domains[1],
            gs[1], ncap)
    singlesite_ops = singlesite_ops_left + singlesite_ops_right
    twosite_ops = twosite_ops_left + [h_loc] + twosite_ops_right

    if v:
        print("Proceeding to tmps...")

    ts, subsystems = get_times(ts_full, ts_system, len(state), sys_position, 2)

    times, subsystems, states, compr_errors, trot_errors = tmps.evolve(
        state=state, hamiltonians=[singlesite_ops, twosite_ops], ts=ts,
        subsystems=subsystems, num_trotter_slices=num_trotter_slices,
        method=method, trotter_compr=trotter_compr, trotter_order=trotter_order,
        compr=compr, v=v)
    return times, states
Пример #5
0
def tedopa1(h_loc, a, state, method, j, domain, ts_full, ts_system,
            trotter_compr=None, compr=None, g=1, trotter_order=2,
            num_trotter_slices=100, ncap=20000, v=0):
    """
    TEDOPA for a single site coupled to a bosonic bath.

    This function proceeds in two steps: (i) Map the Hamiltonian from a system
    composed of one site that is linearly coupled to a reservoir of bosonic
    modes with a given spectral function to the same site coupled to a 1D chain
    of bosonic modes and (ii) perform time evolution.

    The performed mapping is based on an algorithm introduced by Chin et al.
    in Journal of Mathematical Physics 51, 092109 (2010); doi: 10.1063/1.3490188.

    The inputs to this function include the initial state, the local
    Hamiltonian, the spectral density, time of evolution, query times and some
    performance parameters. The output provides the MPAs of the evolved state at
    the requested times.

    Args:
        h_loc (numpy.ndarray):
            Matrix representation of the local Hamiltonian of the one-site
            system.
        a (numpy.ndarray):
            Interaction operator. This is the site-part of the tensor product
            that comprises the interaction Hamiltonian and is defined as
            :math:`\\hat{A}` in Chin et al.
        state (mpnum.MPArray):
            The initial state of the system which is to be evolved.
        method (str):
            The parameterization of the intial state. Either 'mps', 'mpo' or
            'pmps'. Determines which method is used in the simulation.
        j (types.LambdaType):
            Spectral function :math:`J(\\omega)` as defined in Chin et al.
        domain (list[float]):
            Domain on which :math:`J(\\omega)` is defined, for example [0,
            np.inf]
        ts_full (list[float]):
            The times for which the evolution should be computed and the whole
            state chain returned.
        ts_system (list[float]):
            The times for which the evolution should be computed and the reduced
            density matrix of only the system should be returned.
        trotter_compr (dict):
            Compression parameters used in the iterations of Trotter (in the
            form required by :func:`mpnum.MPArray.compress`. If unsure, look at
            https://github.com/dseuss/mpnum/blob/master/examples/mpnum_intro.ipynb .)
            If omitted, some default compression will be used that will
            probably work but might lead to problems. See
            :func:`tmps._set_compr_params` for more information.
        compr (dict):
            Parameters for the compression which is executed on every MPA during
            the calculations, except for the Trotter calculation, where
            trotter_compr is used. compr = dict(method='svd', rank=10) would for
            example ensure that the ranks of any MPA never exceed 10 during all
            of the calculations. An accepted relative error for the
            compression can be provided in addition to or instead of ranks,
            which would lead to e.g.
            compr = dict(method='svd', rank=10, relerr=1e-12).
            If omitted, some default compression will be used that will
            probably work but might lead to problems. See
            :func:`tmps._set_compr_params` for more information.
        g (float):
            Cutoff :math:`g`, assuming that for :math:`J(\\omega)` it is
            :math:`g(\\omega)=g\\omega`.
        trotter_order (int):
            Order of Trotter - Suzuki decomposition to be used. Currently only 2
            and 4 are implemented
        num_trotter_slices (int):
            Number of Trotter slices to be used for the largest t in ts_full or
            ts_system. If ts_system=[10, 25, 30] and num_trotter_slices=100,
            then the program would use 100/30*10=33, 100/30*25=83 and
            100/30*30=100 Trotter slices to calculate the time evolution for the
            three times.
        ncap (int):
            Number internally used by py-orthpol to determine accuracy of the
            returned recurrence coefficients. Must be <= 60000, the higher the
            longer the calculation of the recurrence coefficients takes and the
            more accurate it becomes.
        v (int):
            Level of verbose output. 0 means no output, 1 means that some
            basic output showing the progress of calculations is produced. 2
            will in addition show the bond dimensions of the state after every
            couple of iterations, 3 will show bond dimensions after every
            Trotter iteration.

    Returns:
        list[list[float], list[mpnum.MPArray]]:
            The first list is an array of times for which the states are
            actually computed (might differ slightly from the times in ts_full
            and ts_system, since the ones in times have to be multiples of
            tau). The second list is an array of the corresponding evolved
            states.
    """
    state_shape = state.shape
    if len(domain) != 2:
        raise ValueError("Domain needs to be of the form [x1, x2]")
    if len(a) != state_shape[0][0]:
        raise ValueError(
            "Dimension of 'a' must be the same as that of the \
            first site of the chain.")
    if len(state_shape) < 2:
        raise ValueError("The provided state has no chain representing the \
                         mapped environment. Check state.shape.")

    if v != 0:
        print("Calculating the TEDOPA mapping...")
    singlesite_ops, twosite_ops = map(h_loc, a, state_shape,
                                      j, domain, g, ncap)
    if v != 0:
        print("Proceeding to tmps...")

    ts, subsystems = get_times(ts_full, ts_system, len(state), 0, 1)

    times, subsystems, states = tmps.evolve(
        state=state, hamiltonians=[singlesite_ops, twosite_ops], ts=ts,
        subsystems=subsystems,
        num_trotter_slices=num_trotter_slices, method=method,
        trotter_compr=trotter_compr, trotter_order=trotter_order,
        compr=compr, v=v)
    return times, states
Пример #6
0
def tedopa2(h_loc, a_twosite, state, method, sys_position, js,
            domains, ts_full, ts_system, trotter_compr=None, compr=None,
            gs=(1, 1), trotter_order=2, num_trotter_slices=100, ncap=20000,
            v=0):
    """
    TEDOPA for two sites coupled to each other and each individually to its own
    bosonic bath.

    This function proceeds in two steps: (i) Map the Hamiltonian from a system
    composed of two coupled sites that are each linearly coupled to their
    possibly distinct reservoir of bosonic modes with a given spectral
    function to a 1D chain representing the whole setup and (ii) perform time
    evolution.

    The performed mapping is based on an algorithm introduced by Chin et al.
    in Journal of Mathematical Physics 51, 092109 (2010); doi: 10.1063/1.3490188.

    The inputs to this function include the initial state, the local
    Hamiltonian, the spectral densities, time of evolution, query times and some
    performance parameters. The output provides the MPAs of the evolved state at
    the requested times.

    The first elements in the lists js, domains, etc. always refer to the
    first (left) site and the second elements in the lists refer to the
    second (right) site of the system

    Args:
        h_loc (numpy.ndarray):
            Matrix representation of the local Hamiltonian of the two-site
            system.
        a_twosite (list[numpy.ndarray]):
            List of two matrices, each of which represents the site-part of the
            tensor product interaction Hamiltonian for the two sites.
        state (mpnum.MPArray):
            The initial state of the system which is to be evolved.
        method (str):
            The parameterization of the intial state. Either 'mps', 'mpo' or
            'pmps'. Determines which method is used in the simulation.
        sys_position (int):
            Which index, in the chain representing the state, is the position of
            the first site of the system (starting at 0). E.g. sys_position = 2
            if the chain-length is is 6 and sites are of the form
            env-env-sys-sys-env-env.
        js (list[types.LambdaType]):
            Spectral functions :math:`J(\\omega)` for the two environments as
            defined by Chin et al.
        domains (list[list[float]]):
            Domains on which the :math:`J(\\omega)` are defined. Can be
            different for the two sites, for example, [[0, np.inf], [0,1]]
        ts_full (list[float]):
            The times for which the evolution should be computed and the whole
            state chain returned.
        ts_system (list[float]):
            The times for which the evolution should be computed and the reduced
            density matrix of only the system should be returned.
        trotter_compr (dict):
            Compression parameters used in the iterations of Trotter (in the
            form required by :func:`mpnum.MPArray.compress`. If unsure, look at
            https://github.com/dseuss/mpnum/blob/master/examples/mpnum_intro.ipynb .)
            If omitted, some default compression will be used that will
            probably work but might lead to problems. See
            :func:`tmps._set_compr_params` for more information.
        compr (dict):
            Parameters for the compression which is executed on every MPA during
            the calculations, except for the Trotter calculation, where
            trotter_compr is used. compr = dict(method='svd', rank=10) would for
            example ensure that the ranks of any MPA never exceed 10 during all
            of the calculations. An accepted relative error for the
            compression can be provided in addition to or instead of ranks,
            which would lead to e.g.
            compr = dict(method='svd', rank=10, relerr=1e-12).
            If omitted, some default compression will be used that will
            probably work but might lead to problems. See
            :func:`tmps._set_compr_params` for more information.
        gs (list[float]):
            List of cutoffs :math:`g`, assuming that for :math:`J(\\omega)`
            it is :math:`g(\\omega)=g\\omega`.
        trotter_order (int):
            Order of Trotter-Suzuki decomposition to be used. Currently only 2
            and 4 are implemented
        num_trotter_slices (int):
            Number of Trotter slices to be used for the largest t in ts_full or
            ts_system. If ts_system=[10, 25, 30] and num_trotter_slices=100,
            then the program would use 100/30*10=33, 100/30*25=83 and
            100/30*30=100 Trotter slices to calculate the time evolution for the
            three times.
        ncap (int):
            Number internally used by py-orthpol to determine accuracy of the
            returned recurrence coefficients. Must be <= 60000, the higher the
            longer the calculation of the recurrence coefficients takes and the
            more accurate it becomes.
        v (int):
            Level of verbose output. 0 means no output, 1 means that some
            basic output showing the progress of calculations is produced. 2
            will in addition show the bond dimensions of the state after every
            couple of iterations, 3 will show bond dimensions after every
            Trotter iteration.

    Returns:
        list[list[float], list[mpnum.MPArray]]:
            The first list is an array of times for which the states are
            actually computed (might differ slightly from the times in ts_full
            and ts_system, since the ones in times have to be multiples of
            tau). The second list is an array of the corresponding evolved
            states.
    """
    state_shape = state.shape
    if len(domains[0]) != 2 or len(domains[1]) != 2:
        raise ValueError("A domain needs to be of the form [x1, x2]")
    if len(a_twosite[0]) != state_shape[sys_position][0]:
        raise ValueError(
            "Dimension of 'a_twosite[0]' must be the same as that of the \
            first site of the system.")
    if len(a_twosite[1]) != state_shape[sys_position + 1][0]:
        raise ValueError(
            "Dimension of 'a_twosite[1]' must be the same as that of the \
            second site of the system.")
    if len(state_shape) < 3:
        raise ValueError("The provided state has no chain representing the \
                         mapped environment. Check state.shape.")

    if v != 0:
        print("Calculating the TEDOPA mapping...")
    left_ops = map(np.zeros([state_shape[sys_position][0]] * 2),
                   a_twosite[0], list(
            reversed(state_shape[:sys_position + 1:])),
                   js[0], domains[0], gs[0], ncap)
    singlesite_ops_left, twosite_ops_left = [list(reversed(i)) for i in
                                             left_ops]
    singlesite_ops_right, twosite_ops_right = \
        map(np.zeros([state_shape[sys_position + 1][0]] * 2), a_twosite[1],
            list(state_shape[sys_position + 1::]), js[1], domains[1],
            gs[1], ncap)
    singlesite_ops = singlesite_ops_left + singlesite_ops_right
    twosite_ops = twosite_ops_left + [h_loc] + twosite_ops_right

    if v != 0:
        print("Proceeding to tmps...")

    ts, subsystems = get_times(ts_full, ts_system, len(state), sys_position, 2)

    times, subsystems, states = tmps.evolve(
        state=state, hamiltonians=[singlesite_ops, twosite_ops], ts=ts,
        subsystems=subsystems, num_trotter_slices=num_trotter_slices,
        method=method, trotter_compr=trotter_compr, trotter_order=trotter_order,
        compr=compr, v=v)
    return times, states