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)
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
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
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
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