torch_vn_algebra.composite¶
Source: torch_vn_algebra/composite.py. Signatures and docstrings as in the source.
Module documentation¶
Tensor products of Type I algebras.
Plain product:
((+)_c M_{k_c}) (x) ((+)_d M_{m_d}) = (+)_{(c, d)} M_{k_c m_d},
again of Type I with one sector for every pair (c, d), stored in the order s = c * D + d.
Fused (symmetric) product: when the sectors carry conserved charges (e.g. particle numbers),
the operators of the composite system that conserve the *total* charge form the larger algebra
(+)_q M_{n_q}, n_q = sum_{fuse(c, d) = q} k_c m_d,
in which all pairs with the same total charge q are merged into one sector (fused_tensor_product).
It contains the plain product: A (x) B sits block-diagonally inside every merged sector, but
operators such as hopping terms S+_i S-_j that move charge between the two factors only exist in
the fused algebra.
In both cases sector s is a list of pair blocks (c, d, offset): basis vector offset + a * m_d + b of
sector s is e_a (x) e_b with e_a in sector c of the first and e_b in sector d of the second factor.
Operators factorise blockwise, and the partial traces are maps between sectors,
implemented as InterSectorChannels.
tensor_product¶
def tensor_product(alg1: TypeIAlgebra, alg2: TypeIAlgebra) -> TypeIAlgebra
The algebra alg1 (x) alg2 with sectors (c, d) -> c * alg2.C + d and charges (q_c, q_d).
fused_tensor_product¶
def fused_tensor_product(alg1: TypeIAlgebra, alg2: TypeIAlgebra, fuse: Callable=operator.add) -> TypeIAlgebra
Charge-conserving product: pairs (c, d) with equal fuse(q_c, q_d) are merged into one sector.
Sectors are ordered by the fused charge (sorted when the charges are comparable), the pairs
inside a sector by (c, d). Default fusion rule: addition (U(1) charges).
sector_index¶
def sector_index(alg12: TypeIAlgebra, c: int, d: int) -> int
Index of the sector of alg12 that contains the pair (c, d).
pair_offset¶
def pair_offset(alg12: TypeIAlgebra, c: int, d: int) -> Tuple[int, int]
(sector, offset) of the pair block (c, d) in alg12.
kron¶
def kron(A: Operator, B: Operator, alg12: TypeIAlgebra) -> Operator
A (x) B in alg12 = tensor_product / fused_tensor_product of (A.algebra, B.algebra) (batched,
lazy). In a fused product A (x) B is block diagonal inside the merged sectors. States give a state.
partial_trace_channel¶
def partial_trace_channel(alg12: TypeIAlgebra, keep: int=1) -> InterSectorChannel
Partial trace alg12 -> alg1 (keep=1, trace out the second factor) or -> alg2 (keep=2), as a
trace-preserving map between sectors with Kraus operators 1 (x) <j| (resp. <j| (x) 1) on every pair
block. Works for plain and fused products and any fusion rule: the result is the restriction of the
state to alg1 (resp. alg2) as a subalgebra of B(H1 (x) H2) -- the Hilbert-space partial trace followed by the
conditional expectation onto alg1, which drops blocks between pairs of different charges of the kept factor
(for a plain product, or additive charges without repetitions, those blocks are zero anyway). Its
blunt-trace adjoint is the embedding A -> A (x) 1.
partial_trace¶
def partial_trace(X: Operator, keep: int=1) -> Operator
Tr_2 X (keep=1) or Tr_1 X (keep=2) for X in a tensor-product algebra, computed directly: every pair block
(c, d) is reshaped to (k_c, m_d, k_c, m_d) and traced over one factor, one gather per group of equal block
sizes (O(B sum k^2 m) operations; partial_trace_channel gives the same map as a channel, e.g. for its
adjoint). States give states.