RandomUnitaryEvolution
full name: tenpy.algorithms.tebd.RandomUnitaryEvolution
parent module:
tenpy.algorithms.tebd
type: class
Inheritance Diagram
Methods
|
|
Draw new random two-site unitaries replacing the usual U of TEBD. |
|
Gives an approximate prediction for the required memory usage. |
|
|
Apply |
|
Updates either even or odd bonds in unit cell. |
Return necessary data to resume a |
|
Do nothing, as we call |
|
Resume a run that was interrupted. |
|
Time evolution with TEBD and random two-site unitaries (possibly conserving charges). |
|
TEBD algorithm in imaginary time to find the ground state. |
|
|
Perform a (real-)time evolution of |
Returns list of necessary steps for the suzuki trotter decomposition. |
|
Return time steps of U for the Suzuki Trotter decomposition of desired order. |
|
|
Initialize algorithm from another algorithm instance of a different class. |
|
Updates the B matrices on a given bond. |
Update a bond with a (possibly non-unitary) U_bond. |
|
|
Perform an update suitable for imaginary time evolution. |
Class Attributes and Properties
whether the algorithm supports time-dependent H |
|
truncation error introduced on each non-trivial bond. |
- class tenpy.algorithms.tebd.RandomUnitaryEvolution(psi, options, **kwargs)[source]
Bases:
TEBDEngine
Evolution of an MPS with random two-site unitaries in a TEBD-like fashion.
Instead of using a model Hamiltonian, this TEBD engine evolves with random two-site unitaries. These unitaries are drawn according to the Haar measure on unitaries obeying the conservation laws dictated by the conserved charges. If no charge is preserved, this distribution is called circular unitary ensemble (CUE), see
CUE()
. The distribution can be changed through theRandomUnitaryEvolution.distribution_function
.On one hand, such an evolution is of interest in recent research (see eg. arXiv:1710.09827). On the other hand, it also comes in handy to “randomize” an initial state, e.g. for DMRG. Note that the entanglement grows very quickly, choose the truncation parameters accordingly!
Options
- config RandomUnitaryEvolution
option summary delta_tau_list (from TEBDEngine) in PurificationTEBD.run_GS
A list of floats: the timesteps to be used. [...]
distribution_func in RandomUnitaryEvolution.calc_U
Function or name for one of the matrix ensembles in [...]
distribution_func_kwargs in RandomUnitaryEvolution.calc_U
Extra keyword arguments for `distribution_func`.
dt (from TimeEvolutionAlgorithm) in TimeEvolutionAlgorithm
Minimal time step by which to evolve.
E_offset (from TEBDEngine) in TEBDEngine
Energy offset to be applied in :meth:`calc_U`, see doc there. [...]
max_delta_t (from TEBDEngine) in TEBDEngine
Threshold for raising errors on too large time steps. Default ``1.0``. [...]
max_N_sites_per_ring (from Algorithm) in Algorithm
Threshold for raising errors on too many sites per ring. Default ``18``. [...]
max_trunc_err (from TimeEvolutionAlgorithm) in TimeDependentHAlgorithm.evolve
Threshold for raising errors on too large truncation errors. Default ``0.01 [...]
Number of two-site unitaries to be applied on each bond.
order (from TEBDEngine) in PurificationTEBD.run_GS
Order of the Suzuki-Trotter decomposition.
preserve_norm (from TimeEvolutionAlgorithm) in TimeEvolutionAlgorithm
Whether the state will be normalized to its initial norm after each time st [...]
start_time (from TimeEvolutionAlgorithm) in TimeEvolutionAlgorithm
Initial value for :attr:`evolved_time`.
start_trunc_err (from TimeEvolutionAlgorithm) in TimeEvolutionAlgorithm
Initial truncation error for :attr:`trunc_err`.
Truncation parameters as described in :cfg:config:`truncate`
- option N_steps: int
Number of two-site unitaries to be applied on each bond.
- option trunc_params: dict
Truncation parameters as described in
truncate
Examples
One can initialize a “random” state with total Sz = L//2 as follows:
>>> from tenpy.algorithms.tebd import RandomUnitaryEvolution >>> from tenpy.networks.mps import MPS >>> L = 8 >>> spin_half = tenpy.networks.site.SpinHalfSite(conserve='Sz') >>> psi = MPS.from_product_state([spin_half]*L, ["up", "down"]*(L//2), bc='finite') # Neel >>> print(psi.chi) [1, 1, 1, 1, 1, 1, 1] >>> options = dict(N_steps=2, trunc_params={'chi_max':10}) >>> eng = RandomUnitaryEvolution(psi, options) >>> eng.run() >>> print(psi.chi) [2, 4, 8, 10, 8, 4, 2] >>> psi.canonical_form() # a good idea if there was a truncation necessary.
The “random” unitaries preserve the specified charges, e.g. here we have Sz-conservation. If you start in a sector of all up spins, the random unitaries can only apply a phase:
>>> psi2 = MPS.from_product_state([spin_half]*L, ["up"]*L, bc='finite') # all spins up >>> print(psi2.chi) [1, 1, 1, 1, 1, 1, 1] >>> eng2 = RandomUnitaryEvolution(psi2, options) >>> eng2.run() # random unitaries respect Sz conservation -> we stay in all-up sector >>> print(psi2.chi) # still a product state, not really random!!! [1, 1, 1, 1, 1, 1, 1]
- run()[source]
Time evolution with TEBD and random two-site unitaries (possibly conserving charges).
- calc_U()[source]
Draw new random two-site unitaries replacing the usual U of TEBD.
- option RandomUnitaryEvolution.distribution_func: str | function
Function or name for one of the matrix ensembles in
random_matrix
which generates unitaries (or a subset of them). To be used as func for generating unitaries withfrom_func_square()
, i.e. the U still preserves the charge block structure!
- option RandomUnitaryEvolution.distribution_func_kwargs: dict
Extra keyword arguments for distribution_func.
- evolve(N_steps, dt)[source]
Apply
N_steps
random two-site unitaries to each bond (in even-odd pattern).- Parameters:
- Returns:
trunc_err – The error of the represented state which is introduced due to the truncation during this sequence of update steps.
- Return type:
TruncationError
- estimate_RAM(mem_saving_factor=None)[source]
Gives an approximate prediction for the required memory usage.
This calculation is based on the requested bond dimension, the local Hilbert space dimension, the number of sites, and the boundary conditions.
- Parameters:
mem_saving_factor (float) – Represents the amount of RAM saved due to conservation laws. By default, it is ‘None’ and is extracted from the model automatically. However, this is only possible in a few cases and needs to be estimated in most cases. This is due to the fact that it is dependent on the model parameters. If one has a better estimate, one can pass the value directly. This value can be extracted by building the initial state psi (usually by performing DMRG) and then calling
print(psi.get_B(0).sparse_stats())
TeNPy will automatically print the fraction of nonzero entries in the first line, for example,6 of 16 entries (=0.375) nonzero
. This fraction corresponds to the mem_saving_factor; in our example, it is 0.375.- Returns:
usage – Required RAM in MB.
- Return type:
See also
tenpy.simulations.simulation.estimate_simulation_RAM
global function calling this.
- evolve_step(U_idx_dt, odd)[source]
Updates either even or odd bonds in unit cell.
Depending on the choice of p, this function updates all even (
E
, odd=False,0) or odd (O
) (odd=True,1) bonds:| - B0 - B1 - B2 - B3 - B4 - B5 - B6 - | | | | | | | | | | |----| |----| |----| | | | E | | E | | E | | | |----| |----| |----| | |----| |----| |----| | | | O | | O | | O | | | |----| |----| |----| |
Note that finite boundary conditions are taken care of by having
Us[0] = None
.- Parameters:
U_idx_dt (int) – Time step index in
self._U
, evolve withUs[i] = self.U[U_idx_dt][i]
at bond(i-1,i)
.odd (bool/int) – Indication of whether to update even (
odd=False,0
) or even (odd=True,1
) sites
- Returns:
trunc_err – The error of the represented state which is introduced due to the truncation during this sequence of update steps.
- Return type:
TruncationError
- get_resume_data(sequential_simulations=False)[source]
Return necessary data to resume a
run()
interrupted at a checkpoint.At a
checkpoint
, you can savepsi
,model
andoptions
along with the data returned by this function. When the simulation aborts, you can resume it using this saved data with:eng = AlgorithmClass(psi, model, options, resume_data=resume_data) eng.resume_run()
An algorithm which doesn’t support this should override resume_run to raise an Error.
- Parameters:
sequential_simulations (bool) – If True, return only the data for re-initializing a sequential simulation run, where we “adiabatically” follow the evolution of a ground state (for variational algorithms), or do series of quenches (for time evolution algorithms); see
run_seq_simulations()
.- Returns:
resume_data – Dictionary with necessary data (apart from copies of psi, model, options) that allows to continue the algorithm run from where we are now. It might contain an explicit copy of psi.
- Return type:
- resume_run()[source]
Resume a run that was interrupted.
In case we saved an intermediate result at a
checkpoint
, this function allows to resume therun()
of the algorithm (after re-initialization with the resume_data). Since most algorithms just have a while loop with break conditions, the default behavior implemented here is to just callrun()
.
- run_GS()[source]
TEBD algorithm in imaginary time to find the ground state.
Note
It is almost always more efficient (and hence advisable) to use DMRG. This algorithms can nonetheless be used quite well as a benchmark and for comparison.
- option TEBDEngine.delta_tau_list: list
A list of floats: the timesteps to be used. Choosing a large timestep delta_tau introduces large (Trotter) errors, but a too small time step requires a lot of steps to reach
exp(-tau H) --> |psi0><psi0|
. Therefore, we start with fairly large time steps for a quick time evolution until convergence, and then gradually decrease the time step.
- option TEBDEngine.order: int
Order of the Suzuki-Trotter decomposition.
- option TEBDEngine.N_steps: int
Number of steps before measurement can be performed
- run_evolution(N_steps, dt)[source]
Perform a (real-)time evolution of
psi
by N_steps * dt.This is the inner part of
run()
without the logging. For parameters seeTimeEvolutionAlgorithm
.
- static suzuki_trotter_decomposition(order, N_steps)[source]
Returns list of necessary steps for the suzuki trotter decomposition.
We split the Hamiltonian as \(H = H_{even} + H_{odd} = H[0] + H[1]\). The Suzuki-Trotter decomposition is an approximation \(\exp(t H) \approx prod_{(j, k) \in ST} \exp(d[j] t H[k]) + O(t^{order+1 })\).
- Parameters:
order (
1, 2, 4, '4_opt'
) – The desired order of the Suzuki-Trotter decomposition. Order1
approximation is simply \(e^A a^B\). Order2
is the “leapfrog” e^{A/2} e^B e^{A/2}. Order4
is the fourth-order from [suzuki1991] (also referenced in [schollwoeck2011]), and'4_opt'
gives the optimized version of Equ. (30a) in [barthel2020].- Returns:
ST_decomposition – Indices
j, k
of the time-stepsd = suzuki_trotter_time_step(order)
and the decomposition of H. They are chosen such that a subsequent application ofexp(d[j] t H[k])
to a given state|psi>
yields(exp(N_steps t H[k]) + O(N_steps t^{order+1}))|psi>
.- Return type:
- static suzuki_trotter_time_steps(order)[source]
Return time steps of U for the Suzuki Trotter decomposition of desired order.
See
suzuki_trotter_decomposition()
for details.
- classmethod switch_engine(other_engine, *, options=None, **kwargs)[source]
Initialize algorithm from another algorithm instance of a different class.
You can initialize one engine from another, not too different subclasses. Internally, this function calls
get_resume_data()
to extract data from the other_engine and then initializes the new class.Note that it transfers the data without making copies in most case; even the options! Thus, when you call run() on one of the two algorithm instances, it will modify the state, environment, etc. in the other. We recommend to make the switch as
engine = OtherSubClass.switch_engine(engine)
directly replacing the reference.- Parameters:
cls (class) – Subclass of
Algorithm
to be initialized.other_engine (
Algorithm
) – The engine from which data should be transferred. Another, but not too different algorithm subclass-class; e.g. you can switch from theTwoSiteDMRGEngine
to theOneSiteDMRGEngine
.options (None | dict-like) – If not None, these options are used for the new initialization. If None, take the options from the other_engine.
**kwargs – Further keyword arguments for class initialization. If not defined, resume_data is collected with
get_resume_data()
.
- time_dependent_H = False
whether the algorithm supports time-dependent H
- property trunc_err_bonds
truncation error introduced on each non-trivial bond.
- update_bond(i, U_bond)[source]
Updates the B matrices on a given bond.
Function that updates the B matrices, the bond matrix s between and the bond dimension chi for bond i. The corresponding tensor networks look like this:
| --S--B1--B2-- --B1--B2-- | | | | | | theta: U_bond C: U_bond | | | | |
- Parameters:
- Returns:
trunc_err – The error of the represented state which is introduced by the truncation during this update step.
- Return type:
TruncationError
- update_bond_imag(i, U_bond)[source]
Update a bond with a (possibly non-unitary) U_bond.
Similar as
update_bond()
; but after the SVD just keep the A, S, B canonical form. In that way, one can sweep left or right without using old singular values, thus preserving the canonical form during imaginary time evolution.- Parameters:
- Returns:
trunc_err – The error of the represented state which is introduced by the truncation during this update step.
- Return type:
TruncationError
- update_imag(N_steps, call_canonical_form=True)[source]
Perform an update suitable for imaginary time evolution.
Instead of the even/odd brick structure used for ordinary TEBD, we ‘sweep’ from left to right and right to left, similar as DMRG. Thanks to that, we are able to preserve at least the orthonormality of the canoncial form.
- Parameters:
N_steps (int) – The number of steps for which the whole lattice should be updated.
call_canonical_from (bool) – The singular values saved in the MPS are not exactly correct after the update, since the non-unitary update on other bonds can change them. To fix this, we call psi.canonical_form at the end. Since this is about as a expensive as a single sweep, we allow to disable it, e.g. during the imaginary evolution looking for ground states where the intermediate results is not so critical.
- Returns:
trunc_err – The error of the represented state which is introduced due to the truncation during this sequence of update steps.
- Return type:
TruncationError