Skip to content

torch_vn_algebra.chains

Source: torch_vn_algebra/chains.py. Signatures and docstrings as in the source.

Module documentation

Spin-1/2 chains with a conserved number of up spins (U(1) symmetry, total S^z).

The Hilbert space (C^2)^{(x) L} splits into sectors N = 0, ..., L (number of up spins) of
dimension binom(L, N); every operator that conserves S^z_total is an element of

    M = (+)_{N=0}^{L} M_{binom(L, N)}(C),

the algebra obtained by fusing L single-site algebras M_1 (+) M_1 with charges 0, 1
(composite.fused_tensor_product); the basis order of SpinChain coincides with that construction.
Basis states are bit strings: bit i of a label is the spin on site i (1 = up).

    chain = SpinChain(L=10, boundary='periodic')
    H = chain.xxz(J=1.0, Delta=1.0, h=fields)          # fields: (L,) or (batch, L) -> batch of H
    H5 = chain.xxz(..., sector=5)                      # one sector only: no padding
    rho_A = chain.reduced_state(rho, n_left=4)          # state of sites 0..3 (a SpinChain(4) state)

Hamiltonian:  H = sum_<ij> [ J/2 (S+_i S-_j + S-_i S+_j) + J Delta S^z_i S^z_j ] + sum_i h_i S^z_i.

SpinChain

class SpinChain(L: int, boundary: str='open', complex_valued: bool=True, precision: str='double', device=None)

SpinChain.algebra

@property
def algebra(self) -> TypeIAlgebra
The full algebra (+)_N M_{binom(L, N)} (created on first use; padded to the largest sector).

SpinChain.bonds

@property
def bonds(self) -> List[tuple]
Nearest-neighbour bonds (i, i+1); a periodic chain adds (L-1, 0) for L > 2. For L = 2 the two sites
share a single bond, so the periodic and the open chain coincide (the bond is not counted twice).

SpinChain.sector_dim

def sector_dim(self, N: int) -> int

SpinChain.sector_algebra

def sector_algebra(self, N: int) -> TypeIAlgebra
The single-sector algebra M_{binom(L, N)} (no padding), cached.

SpinChain.bits

def bits(self, N: int) -> torch.Tensor
(binom(L, N), L) tensor of 0/1 spins of the basis states of sector N.

SpinChain.xxz

def xxz(self, J: float=1.0, Delta: float=1.0, h=None, sector: Optional[int]=None) -> Operator
XXZ Hamiltonian H = sum_bonds J [ (S+_i S-_j + h.c.)/2 + Delta Sz_i Sz_j ] + sum_i h_i Sz_i with fields h
(scalar, (L,) or (batch, L): one Hamiltonian per row); bonds as in `bonds` (periodic L = 2: one bond).
sector=None: operator in the full algebra (all sectors, padded); sector=N: operator in
sector_algebra(N) only.

SpinChain.xxz_sparse

def xxz_sparse(self, J: float=1.0, Delta: float=1.0, h=None, sector: int=0)
The XXZ Hamiltonian of one sector in sparse form (krylov.SparseSectorHamiltonian): a batch of
diagonals (one per row of h) and one shared sparse hopping matrix; memory O(batch * k + k * L)
instead of O(batch * k^2). For krylov.ground_state / krylov.evolve.

SpinChain.momentum_dims

def momentum_dims(self, N: int) -> List[int]
Dimensions of the momentum sectors k = 2 pi m / L, m = 0..L-1, inside sector N.

SpinChain.momentum_algebra

def momentum_algebra(self, N: int) -> TypeIAlgebra
(+)_m M_{d_m}: the operators commuting with N and with translations, sectors labelled by m.

SpinChain.xxz_momentum

def xxz_momentum(self, J: float=1.0, Delta: float=1.0, h: float=0.0, sector: int=0) -> Operator
Translation-invariant XXZ Hamiltonian of sector N, block diagonal in the momentum k = 2 pi m / L
(requires a periodic, complex chain; h must be uniform). Basis of block m:
|a, k> = (1/sqrt(N_a)) sum_j e^{-i k j} T^j |a>, N_a = L^2 / R_a, for representatives a of period
R_a with m R_a = 0 mod L. The union of the spectra of all blocks is the spectrum of sector N.

SpinChain.heisenberg

def heisenberg(self, J: float=1.0, h=None, sector: Optional[int]=None) -> Operator

SpinChain.random_field_heisenberg

def random_field_heisenberg(self, W: float, batch_size: int, J: float=1.0, sector: Optional[int]=None, generator: Optional[torch.Generator]=None) -> Operator
Heisenberg chain with i.i.d. fields h_i ~ U[-W, W]; one disorder realisation per batch element.

SpinChain.sz

def sz(self, i: int, sector: Optional[int]=None) -> Operator
S^z on site i.

SpinChain.number

def number(self, sector: Optional[int]=None) -> Operator
N = number of up spins (central: N * 1 in sector N).

SpinChain.basis_state

def basis_state(self, bitstring: Union[str, Sequence[int]]) -> DensityMatrix
|s><s| for a configuration given as '0110...' (site 0 first) or a 0/1 sequence.

SpinChain.vector_in_sector

def vector_in_sector(self, bitstring) -> torch.Tensor
Basis vector of a configuration as a column of its sector (shape (binom(L, N),)).

SpinChain.reduced_state

def reduced_state(self, rho: Operator, n_left: int, sector: Optional[int]=None) -> DensityMatrix
Partial trace over sites n_left, ..., L-1. rho lives in the full algebra (sector=None) or in
sector_algebra(sector). Returns a state of SpinChain(n_left, ...).algebra; for U(1)
symmetric states the result is block diagonal in the particle number of the left part.

SpinChain.entanglement_entropy

def entanglement_entropy(self, rho: Operator, n_left: int, sector: Optional[int]=None) -> torch.Tensor
von Neumann entropy of the reduced state of sites 0..n_left-1.

SpinChain.site_amplitude_damping

def site_amplitude_damping(self, i: int, gamma: float) -> InterSectorChannel
Spin flip down on site i with probability gamma (a map between sectors N -> N-1):
K_0 = |down><down|_i + sqrt(1 - gamma) |up><up|_i,  K_1 = sqrt(gamma) S-_i.

SpinChain.lowering

def lowering(self, i: int) -> InterSectorChannel
S-_i as a single jump operator between sectors N -> N-1 (for Lindblad loss terms).

SpinChain.level_spacing_ratio

@staticmethod
def level_spacing_ratio(energies: torch.Tensor) -> torch.Tensor
Mean ratio of consecutive level spacings r = <min(s_n, s_{n+1}) / max(s_n, s_{n+1})> per row of
sorted energies (Oganesyan-Huse). Exact values proved in the lecture notes (Proposition 5.14): 2 ln 2 - 1 = 0.386
for independent exponential spacings, 4 - 2 sqrt 3 = 0.536 (GOE) and 2 sqrt 3 / pi - 1/2 = 0.603 (GUE) for
3 x 3 matrices. For large GOE matrices the value is about 0.53 (Atas et al. 2013; a numerical result, not
an exact one), so for large spectra compare with a sampled reference of the same size.