quspin.tools.block_tools.block_ops
- class quspin.tools.block_tools.block_ops(blocks, static, dynamic, basis_con, basis_args, dtype, basis_kwargs={}, get_proj_kwargs={}, save_previous_data=True, compute_all_blocks=False, check_symm=True, check_herm=True, check_pcon=True)[source]
Bases:
object
Splits up the dynamics of a state over various symmetry sectors.
Particularly useful if the initial state does NOT obey a symmetry but the hamiltonian does. Moreover, we provide a multiprocessing option which allows the user to split up the dynamics over multiple processing cores.
Can be used to calculate nonequal time correlators in symmetry-reduced sectors.
Notes
The block_ops object is initialised only after calling the function methods of the class to save memory.
Examples
The following sequence of examples uses the Bose-Hubbard model
\[H=-J\sum_j b^\dagger_{j+1}b_j + \mathrm{h.c.} + \frac{U}{2}\sum_j n_j(n_j-1)\]to show how to use the block_ops class to evolve a Fock state, which explicitly breaks translational invariance, by decomposing it in all momentum blocks, time-evolving the projections, and putting the state back together in the Fock basis in the end. We use the time-evolved state to measure the local density operator \(n_j\).
The code snippets for the time evolution can be found in the examples for the function methods of the class. The code snippet below initiates the class, and is required to run the example codes for the function methods.
1from quspin.basis import boson_basis_1d # bosonic Hilbert space 2from quspin.tools.block_tools import block_ops # dynamics in symmetry blocks 3import numpy as np # general math functions 4 5# 6##### define model parameters 7# initial seed for random number generator 8np.random.seed(0) # seed is 0 to produce plots from QuSpin2 paper 9# setting up parameters of simulation 10L = 6 # length of chain 11J = 1.0 # top side of ladder hopping 12U = 20.0 # Hubbard interaction 13# 14##### set up Hamiltonian and observables 15# define site-coupling lists 16int_list_1 = [[-0.5 * U, i] for i in range(L)] # interaction $-U/2 \sum_i n_i$ 17int_list_2 = [[0.5 * U, i, i] for i in range(L)] # interaction: $U/2 \num_i n_i^2$ 18# setting up hopping lists 19hop_list = [[-J, i, (i + 1) % L] for i in range(L)] # PBC 20# set up static and dynamic lists 21static = [ 22 ["+-", hop_list], # hopping 23 ["-+", hop_list], # hopping h.c. 24 ["nn", int_list_2], # U n_i^2 25 ["n", int_list_1], # -U n_i 26] 27dynamic = [] # no dynamic operators 28# create block_ops object 29blocks = [dict(kblock=kblock) for kblock in range(L)] # blocks to project on to 30baisis_args = (L,) # boson_basis_1d manditory arguments 31basis_kwargs = dict(Nb=L // 2, sps=3) # boson_basis_1d optional args 32get_proj_kwargs = dict(pcon=True) # set projection to full particle basis 33H_block = block_ops( 34 blocks, 35 static, 36 dynamic, 37 boson_basis_1d, 38 baisis_args, 39 np.complex128, 40 basis_kwargs=basis_kwargs, 41 get_proj_kwargs=get_proj_kwargs, 42) 43# 44# setting up local Fock basis 45basis = boson_basis_1d(L, Nb=L // 2, sps=3) 46# setting up observables 47no_checks = dict(check_herm=False, check_symm=False, check_pcon=False) 48n_list = [ 49 hamiltonian([["n", [[1.0, i]]]], [], basis=basis, dtype=np.float64, **no_checks)
- __init__(blocks, static, dynamic, basis_con, basis_args, dtype, basis_kwargs={}, get_proj_kwargs={}, save_previous_data=True, compute_all_blocks=False, check_symm=True, check_herm=True, check_pcon=True)[source]
Instantiates the block_ops class.
- Parameters:
- blockslist/tuple/iterator
Contains the symmetry blocks to construct the Hamiltonian with, as dictionaries or hamiltonian objects.
- staticlist
Static operator list used to construct the block Hamiltonians. Follows hamiltonian format.
- dynamiclist
Dynamic operator list used to construct the block Hamiltonians. Follows hamiltonian format.
- basis_con
basis
Basis constructor used to build the basis objects to create the block diagonal Hamiltonians.
- basis_argstuple
This argument is passed as the first argument for basis_con. Contains all required arguments for the basis.
- dtype‘type’
The data type (e.g. numpy.float64) to construct the Hamiltonian with.
- basis_kwargsdict, optional
Dictionary of keyword arguments to add when calling basis constructor.
- get_proj_kwargsdict, optional
Dictionary of keyword arguments for basis.get_proj() and basis.project_from().
- save_previous_databool, optional
To do time evolution the block_ops class constructs Hamiltonians, which can take time. Set this flag to True, and the class will save previously calculated Hamiltonians, so next time one needs to do evolution in that block, the code does NOT have to calculate it again. Default is True.
- compute_all_blocksbool, optional
Flag which tells the block_ops class to compute all symmetry blocks at initialization. Default is False.
This option sets save_previous_data = True automatically.
- check_symmbool, optional
Enable/Disable symmetry check of the operators for the first Hamiltonian constructed.
- check_hermbool, optional
Enable/Disable hermiticity check of the operators for the first Hamiltonian constructed.
- check_pconbool, optional
Enable/Disable particle conservation check of the operators for the first Hamiltonian constructed.
Methods
__init__
(blocks, static, dynamic, basis_con, ...)Instantiates the block_ops class.
Sets compute_all_blocks = True.
evolve
(psi_0, t0, times[, iterate, n_jobs, ...])Creates symmetry blocks of the Hamiltonian and then uses them to run hamiltonian.evolve() in parallel.
expm
(psi_0[, H_time_eval, iterate, n_jobs, ...])Creates symmetry blocks of the Hamiltonian and then uses them to run _expm_multiply() in parallel.
update_blocks
(blocks, basis_con, basis_args)Allows to update the blocks variable of the class.
Attributes
dictionary which contains the block Hamiltonians under keys labelled by the symmetry blocks, e.g. str(block) where block is a block dictionary variable.
dictionary which contains the block projectors under keys labelled by the symmetry blocks, e.g. str(block) where block is a block dictionary variable.
dictionary which contains the basis objects under keys labelled by the symmetry blocks, e.g. str(block) where block is a block dictionary variable.
numpy data type to store the block hamiltonians in.
contains the dynamic operators used to construct the symmetry-block Hamiltonians.
reflects state of optimal argument save_previous_data.
contains the static operators used to construct the symmetry-block Hamiltonians.
- property H_dict
dictionary which contains the block Hamiltonians under keys labelled by the symmetry blocks, e.g. str(block) where block is a block dictionary variable.
- Type:
dict
- property P_dict
dictionary which contains the block projectors under keys labelled by the symmetry blocks, e.g. str(block) where block is a block dictionary variable.
- Type:
dict
- property basis_dict
dictionary which contains the basis objects under keys labelled by the symmetry blocks, e.g. str(block) where block is a block dictionary variable.
- Type:
dict
- compute_all_blocks()[source]
Sets compute_all_blocks = True.
Examples
The example below builds on the code snippet shown in the description of the block_ops class.
1] 2#
- property dtype
numpy data type to store the block hamiltonians in.
- Type:
type
- property dynamic
contains the dynamic operators used to construct the symmetry-block Hamiltonians.
- Type:
list
- evolve(psi_0, t0, times, iterate=False, n_jobs=1, block_diag=False, stack_state=False, imag_time=False, solver_name='dop853', **solver_args)[source]
Creates symmetry blocks of the Hamiltonian and then uses them to run hamiltonian.evolve() in parallel.
Arguments NOT described below can be found in the documentation for the `hamiltonian.evolve()` method.
- Parameters:
- psi_0numpy.ndarray, list, tuple
Quantum state which defined on the full Hilbert space of the problem. Does not need to obey and sort of symmetry.
- t0float
Inistial time to start the evolution at.
- timesnumpy.ndarray, list
Contains the times to compute the solution at. Must be some an iterable object.
- iteratebool, optional
Flag to return generator when set to True. Otherwise the output is an array of states. Default is ‘False’.
- n_jobsint, optional
Number of processes requested for the computation time evolution dynamics.
NOTE: one of those processes is used to gather results. For best performance, all blocks should be approximately the same size and n_jobs-1 must be a common devisor of the number of blocks, such that there is roughly an equal workload for each process. Otherwise the computation will be as slow as the slowest process.
- block_diagbool, optional
When set to True, this flag puts the Hamiltonian matrices for the separate symemtry blocks into a list and then loops over it to do time evolution. When set to False, it puts all blocks in a single giant sparse block diagonal matrix. Default is False.
This flag is useful if there are a lot of smaller-sized blocks.
- Returns:
- obj
if iterate = True, returns generator which generates the time dependent state in the full H-space basis.
if iterate = False, returns numpy.ndarray which has the time-dependent states in the full H-space basis in the rows.
- Raises:
- ValueError
Variable imag_time=True option on hamiltonian.evolve() method not supported.
- ValueError
iterate=True requires times to be an array or a list.
- RuntimeError
Terminates when initial state has no projection onto the specified symmetry blocks.
Examples
The example below builds on the code snippet shown in the description of the block_ops class.
1# 2##### compute all momentum blocks 3H_block.compute_all_blocks() 4# 5##### calculating the evolved states using matrix exponentiation 6# setting up parameters for evolution 7start, stop, num = 0, 30, 301 # 0.1 equally spaced points 8times = np.linspace(start, stop, num) 9n_jobs = 1 # paralelisation: increase to see if calculation runs faster! 10psi_t = H_block.expm( 11 psi, a=-1j, start=start, stop=stop, num=num, block_diag=False, n_jobs=n_jobs 12) 13# calculating the local densities as a function of time 14n_t = np.vstack([n.expt_value(psi_t).real for n in n_list]).T 15# 16##### calculating the evolved state using the evolve method 17# setting up parameters for evolution 18start, stop, num = 0, 30, 301 # 0.1 equally spaced points 19times = np.linspace(start, stop, num) 20psi_t = H_block.evolve(psi, times[0], times) 21n_t = np.vstack([n.expt_value(psi_t).real for n in n_list]).T
- expm(psi_0, H_time_eval=0.0, iterate=False, n_jobs=1, block_diag=False, a=-0 - 1j, start=None, stop=None, endpoint=None, num=None, shift=None)[source]
Creates symmetry blocks of the Hamiltonian and then uses them to run _expm_multiply() in parallel.
Arguments NOT described below can be found in the documentation for the `exp_op` class.
- Parameters:
- psi_0numpy.ndarray, list, tuple
Quantum state which defined on the full Hilbert space of the problem. Does not need to obey and sort of symmetry.
- t0float
Inistial time to start the evolution at.
- H_time_evalnumpy.ndarray, list
Times to evaluate the Hamiltonians at when doing the matrix exponentiation.
- iteratebool, optional
Flag to return generator when set to True. Otherwise the output is an array of states. Default is ‘False’.
- n_jobsint, optional
Number of processes requested for the computation time evolution dynamics.
NOTE: one of those processes is used to gather results. For best performance, all blocks should be approximately the same size and n_jobs-1 must be a common devisor of the number of blocks, such that there is roughly an equal workload for each process. Otherwise the computation will be as slow as the slowest process.
- block_diagbool, optional
When set to True, this flag puts the Hamiltonian matrices for the separate symemtri blocks into a list and then loops over it to do time evolution. When set to False, it puts all blocks in a single giant sparse block diagonal matrix. Default is False.
This flag is useful if there are a lot of smaller-sized blocks.
- Returns:
- obj
if iterate = True, returns generator which generates the time dependent state in the full H-space basis.
if iterate = False, returns numpy.ndarray which has the time-dependent states in the full H-space basis in the rows.
- Raises:
- ValueError
Various ValueError`s of `exp_op class.
- RuntimeError
Terminates when initial state has no projection onto the specified symmetry blocks.
Examples
The example below builds on the code snippet shown in the description of the block_ops class.
1# set up initial state 2i0 = basis.index("111000") # pick state from basis set 3psi = np.zeros(basis.Ns, dtype=np.float64) 4psi[i0] = 1.0 5# print info about setup 6state_str = "".join( 7 str(int((basis[i0] // basis.sps ** (L - i - 1)) % basis.sps)) for i in range(L) 8)
- property save_previous_data
reflects state of optimal argument save_previous_data.
- Type:
bool
- property static
contains the static operators used to construct the symmetry-block Hamiltonians.
- Type:
list
- update_blocks(blocks, basis_con, basis_args, compute_all_blocks=False)[source]
Allows to update the blocks variable of the class.
- Parameters:
- blockslist/tuple/iterator
Contains the new symmetry blocks to be added to the basis_dict attribute of the class, as dictionaries or hamiltonian objects.
- basis_con
basis
Basis constructor used to build the basis objects to create the new block diagonal Hamiltonians.
- basis_argstuple
This argument is passed as the first argument for basis_con. Contains all required arguments for the basis.
- compute_all_blocksbool, optional
Flag which tells the block_ops class to compute all symmetry blocks at initialization. Default is False.