slater

Tools for converting Slater determinants into matrix product states (MPS).

Classes

SchmidtModes

Mean-field orbitals that generate the Schmidt vectors of a Slater determinant.

SchmidtVectors

Schmidt vectors of a Slater determinant.

MPSTensorData

Data for computing one MPS tensor of a Slater determinant.

Functions

correlation_matrix

Ground-state correlation matrix of a mean-field Hamiltonian.

C_to_MPS

MPS representation of a Slater determinant from its correlation matrix.

C_to_iMPS

iMPS representation of a Slater determinant from correlation matrices.

Static variables

fermion_site

Lattice site prototype for the number-conserving fermion MPS.

fermion_leg

LegCharge for the single-site Hilbert space of the number-conserving fermion MPS.

chinfo

ChargeInfo for fermion number conservation.

Classes

class temfpy.slater.SchmidtModes(e, vL, vR, ixL, ixR, nL, nR, n_fermion)[source]

Mean-field orbitals that generate the Schmidt vectors of a Slater determinant.

e: ndarray

array (n_entangled,) – Entangled eigenvalues of the left-left block of the correlation matrix, in decreasing order.

vL: ndarray | None

array (nL, nL) – Eigenvectors of the left-left block of the correlation matrix, if computed.

The eigenvectors are the columns of the matrix in the order

  • filled orbitals (eigenvalue 1);

  • entangled orbitals (eigenvalue between 0 and 1, decreasing order);

  • empty orbitals (eigenvalue 0).

In particular, the eigenvalues corresponding to v_LE = vL[:, ixL["entangled"]] are given in order by e.

Note that the entangled orbital vectors v_LE are also left singular vectors of the offdiagonal block \(C^{LR}\) of the correlation matrix.

vR: ndarray | None

array (nR, nR) – Eigenvectors of the right-right block of the correlation matrix, if computed.

The eigenvectors are the columns of the matrix in the order

  • empty orbitals (eigenvalue 0);

  • entangled orbitals (eigenvalue between 0 and 1, decreasing order);

  • filled orbitals (eigenvalue 1).

In particular, the eigenvalues corresponding to v_RE = vR[:, ixR["entangled"]] are given in order by 1-e[::-1].

Note that the entangled orbital vectors v_RE are also right singular vectors of the offdiagonal block \(C^{LR}\) of the correlation matrix.

If both vL and vR are computed, the singular vectors v_LE[:, i] and v_RE[:, n_entangled-1-i] correspond to each other, with eigenvalues \(\lambda_i\) and \(1-\lambda_i\), so that the SVD of \(C^{LR}\) is

\[C^{LR} = \sum_{i=0}^{n_E-1} \sqrt{\lambda_i (1-\lambda_i)} \; v_{L,E,i} \; v_{R,E,n_E-1-i}^\dagger.\]

However, to better handle fermion anticommutation, the entangled orbitals at odd indices include an additional negative sign.

ixL: dict[str, slice] | None

Maps the labels "empty", "filled", "entangled" to column slices of the corresponding orbitals in vL, if that is computed.

ixR: dict[str, slice] | None

Maps the labels "empty", "filled", "entangled" to column slices of the corresponding orbitals in vR, if that is computed.

nL: int

Size of the left half of the system.

nR: int

Size of the right half of the system.

n_fermion: int

Number of fermions in the mean-field state.

property n_entangled: int

Number of entangled orbitals.

size(which='T')[source]

Size of the specified half or the whole of the system.

Parameters:

which (str) – Either “L” for left or “R” for right side or “T” (default) for total size.

Return type:

int

Returns:

nL, nR, or their sum, depending on which.

n_filled(which)[source]

Number of filled orbitals on the specified half of the system.

Based on vL or vR if they exist, otherwise inferred from n_fermion and the number of entangled and filled orbitals on the other side.

Parameters:

which (str) – Whether to return the number of filled orbitals to the left (“L”) or the right (“R”).

Return type:

int

Returns:

Number of filled orbitals on the specified side.

property vL_entangled: ndarray | None

Entangled left Schmidt mode orbitals, if computed.

property vR_entangled: ndarray | None

Entangled right Schmidt mode orbitals, if computed.

mode_vectors(which, entangled=False)[source]

Returns the Schmidt mode orbitals on the specified side.

Parameters:
  • which (str) – Either “L” for left or “R” for right side.

  • entangled (bool) – Whether to return the entangled (True) or all (False, default) eigenvectors.

Return type:

ndarray | None

Returns:

Either vL or vR, depending on which, truncated to entangled modes if entangled.

eigenvalues(which, entangled=False)[source]

Returns the Schmidt mode eigenvalues on the specified side.

Parameters:
  • which (str) – Either “L” for left or “R” for right side.

  • entangled (bool) – Whether to return the entangled (True) or all (False, default) eigenvalues.

Return type:

ndarray | None

Returns:

The eigenvalues corresponding to mode_vectors() with the same parameters.

property singular_values: ndarray | None

Singular values of the offdiagonal correlation matrix blocks.

If vL_entangled and vR_entangled are both known, satisfies

C_LR == vL_entangled @ diag(S) @ vR_entangled[:, ::-1].T.conj()

Otherwise, None.

classmethod from_correlation_matrix(C, x, trunc_par, *, which='LR', diag_tol=1e-08)[source]

SchmidtModes of a mean-field state with correlation matrix C for an entanglement cut between sites x-1 and x (zero-indexed).

We start by diagonalising the respective diagonal blocks. The eigenvectors give the Schmidt modes, the eigenvalues their relative weight in the entangled mode. We only treat modes with eigenvalues away from 0 or 1 by at least trunc_par.svd_min squared as entangled, as only these can contribute to a Schmidt value less than trunc_par.svd_min.

Parameters:
  • C (ndarray) – The correlation matrix, \(C_{ij} = \langle c_j^\dagger c_i\rangle\).

  • x (int) – Position of the entanglement cut.

  • trunc_par (dict | StoppingCondition) –

    Which Schmidt modes should be kept as entangled.

    Must be either a StoppingCondition object or a dictionary with matching keys.

  • which (str) –

    Whether to return left and/or right Schmidt modes.

    Must be a combination of "L" and "R".

  • diag_tol (float) – If which == "LR", largest allowed offdiagonal matrix element in diagonalised / SVD correlation submatrices before an error is raised.

Return type:

SchmidtModes

Note

  • If trunc_par.svd_min is not provided, a default of 1e-6 (i.e., a truncation threshold of 1e-12) is used.

  • If trunc_par.degeneracy_tol is not provided, the degeneracy tolerance defaults to 1e-12.

property e_ratio: ndarray

\(\log((1-\lambda)/\lambda\) for all eigenvalues in e.

embed_subsets(sets)[source]

Given an array of subsets of entangled orbitals occupied on the left side, generates the full sets of occupied orbitals on either side.

Parameters:

sets (bool ndarray (n, n_entangled)) –

Array of occupation numbers.

Each row specifies one Schmidt state by listing on which side of the entanglement cut each entangled orbital is filled: True if on the left side, False if on the right side.

Return type:

tuple[ndarray | None, ndarray | None]

Returns:

  • left_sets (bool ndarray (n, size[0]) | None) – Occupation of every left orbital in the input Schmidt states.

    Returned if vL is not None.

  • right_sets (bool ndarray (n, size[1]) | None) – Occupation of every right orbital in the input Schmidt states.

    Returned if vR is not None.

schmidt_values(sets)[source]

Schmidt values of the Schmidt vectors with given occupation numbers.

Parameters:

sets (bool ndarray (n, n_entangled)) –

Array of occupation numbers.

Each row specifies one Schmidt state by listing on which side of the entanglement cut each entangled orbital is filled: True if on the left side, False if on the right side.

Returns:

λ – Schmidt values corresponding to the input Schmidt states.

Return type:

ndarray (n,)

class temfpy.slater.SchmidtVectors(modes, left_sets, right_sets, schmidt_values, idx_L)[source]

Schmidt vectors of a Slater determinant.

The Schmidt decomposition of the state \(|\psi\rangle\) is given by

\[ \begin{align}\begin{aligned}|\psi\rangle &= \sum_\alpha \lambda_\alpha |L_\alpha\rangle \otimes_g |R_\alpha\rangle\\|L_\alpha\rangle &= \prod_a (d^\dagger_{L,a})^{n^L_{\alpha a}} |0\rangle\\|R_\alpha\rangle &= \prod_a (d^\dagger_{R,a})^{n^R_{\alpha a}} |0\rangle,\end{aligned}\end{align} \]

where \(\lambda_\alpha\) are the Schmidt values, \(d^\dagger_{L,a}\) and \(d^\dagger_{L,a}\) are the creation operators of the left and right Schmidt mode orbitals, and \(n^L_{\alpha a}\) and \(n^R_{\alpha a}\) are the occupation numbers of these orbitals in the Schmidt vectors.

modes: SchmidtModes

The mean-field orbitals underlying the Schmidt vectors.

left_sets: ndarray | None

bool (n_schmidt, nL) – Left Schmidt vectors.

Each row contains the occupation \(n^L_{\alpha a}\) of all left Schmidt modes in one left Schmidt vector \(|L_\alpha\rangle\), if vL is not None.

right_sets: ndarray | None

bool (n_schmidt, nR) – Right Schmidt vectors.

Each row contains the occupation \(n^R_{\alpha a}\) of all left Schmidt modes in one left Schmidt vector \(|R_\alpha\rangle\), if vR is not None.

schmidt_values: ndarray

(n_schmidt,) – Schmidt values \(\lambda_\alpha\) corresponding to each Schmidt vector.

Sorted in increasing order of charge of the left Schmidt vector and in decreasing order within each charge sector.

idx_L: dict[int, slice]

Maps the total charge to the left of the entanglement cut to the slice of sets/singular values with that charge.

That is, all Schmidt vectors in left_sets[idx_L[n]] contain n particles.

property n_schmidt: int

The number of Schmidt vectors.

property n_entangled: int

Number of entangled orbitals.

property nL: int

Size of the left half of the system.

property nR: int

Size of the right half of the system.

property n_fermion: int

Number of fermions in the mean-field state.

size(which='T')[source]

Size of the specified half or the whole of the system.

Parameters:

which (str) – Either “L” for left or “R” for right side or “T” (default) for total size.

Return type:

int

Returns:

the appropriate system size.

property vL: ndarray | None

Left Schmidt mode orbitals vL.

property vR: ndarray | None

Right Schmidt mode orbitals vR.

mode_vectors(which, entangled=False)[source]

Returns the Schmidt mode orbitals on the specified side.

Parameters:
  • which (str) – Either “L” for left or “R” for right side.

  • entangled (bool) – Whether to return the entangled (True) or all (False, default) eigenvectors.

Return type:

ndarray | None

Returns:

Either vL or vR, depending on which, truncated to entangled modes if entangled.

sets(which)[source]

Returns the sets of occupied orbitals on the specified side.

Parameters:

which (str) – Either “L” for left or “R” for right side.

Returns:

Either left_sets or right_sets, depending on which.

classmethod from_schmidt_modes(modes, trunc_par)[source]

The most significant SchmidtVectors from the given SchmidtModes.

Parameters:
  • modes (SchmidtModes) – The Schmidt modes.

  • trunc_par (dict | StoppingCondition) –

    Specifies which Schmidt states should be kept.

    Must be either a StoppingCondition object or a dictionary with matching keys.

    If modes contains left modes, the filtering function sectors is applied to the total number of particles to the left, otherwise, to the total number of particles to the right.

Return type:

SchmidtVectors

classmethod from_correlation_matrix(C, x, trunc_par, *, which='LR', diag_tol=1e-08)[source]

Most significant SchmidtVectors of a Slater determinant with correlation matrix C for an entanglement cut between sites x-1 and x (zero-indexed).

Parameters:
  • C (ndarray) – The correlation matrix, \(C_{ij} = \langle c_j^\dagger c_i\rangle\).

  • x (int) – Position of the entanglement cut.

  • trunc_par (dict | StoppingCondition) –

    Specifies which Schmidt states should be kept.

    Must be either a StoppingCondition object or a dictionary with matching keys.

    If left Schmidt modes are calculated, the filtering function sectors is applied to the total number of particles to the left, otherwise, to the total number of particles to the right.

  • which (str) –

    Whether to return left and/or right Schmidt modes.

    Must be a combination of "L" and "R".

  • diag_tol (float) – If which == "LR", largest allowed offdiagonal matrix element in diagonalised / SVD correlation submatrices before an error is raised.

Return type:

SchmidtVectors

Note

  • If trunc_par.svd_min is not provided, the truncation threshold defaults to 1e-6.

  • If trunc_par.degeneracy_tol is not provided, the degeneracy tolerance defaults to 1e-12.

class temfpy.slater.MPSTensorData(mode, physical_leg, det_always, sometimes_matrix, idx_bra, idx_ket, new_sets_bra, new_sets_ket, qtotal)[source]

Data for computing one MPS tensor of a Slater determinant.

  • If mode is "left", contains an implicit description of the left canonical tensor

    \[A^{n_i}_{\alpha\beta} = (\langle n_i | \otimes_g \langle L^{(i-1)}_\alpha|) | L^{(i)}_\beta \rangle.\]
  • If mode is "right", contains an implicit description of the right canonical tensor

    \[B^{n_i}_{\beta\alpha} = (\langle R^{(i)}_\alpha | \otimes_g \langle n_i |) | R^{(i-1)}_\beta \rangle.\]

Schmidt vector overlaps for equal-length chains can also be computed:

\[ \begin{align}\begin{aligned}A_{\alpha\beta} &= \langle L'_\alpha | L_\beta \rangle\\B_{\beta\alpha} &= \langle R'_\beta | R_\alpha \rangle\end{aligned}\end{align} \]

For Slater determinants, such overlaps are the determinants of the overlaps of the single-particle orbital wave functions. Many of these orbitals are shared between every Schmidt vector, so we can compute the determinants efficiently using the identity

\[\begin{split}\det \begin{bmatrix}A & B \\ C & D\end{bmatrix} = \det(A) \det\left(D - C A^{-1} B\right) = \det(D) \det\left(A - B D^{-1} C\right).\end{split}\]

Namely, if the block \(A\) or block \(D\) contains the overlaps of the always occupied orbitals, its determinant is only computed once. Furthermore, each determinant entry \(\left(D - C A^{-1} B\right)_{ij}\) / \(\left(A - B D^{-1} C\right)_{ij}\) depends only on “bra” orbital i and “ket” orbital j, so they can be precomputed for all pairs of sometimes-occupied orbitals.

  • For left Schmidt vectors, the always occupied orbitals are listed before the entangled ones (cf. SchmidtModes.vL). Therefore, we use the first form of the identity if mode == "left".

  • For right Schmidt vectors, the always occupied orbitals are listed after the entangled ones (cf. SchmidtModes.vR). Therefore, we use the second form of the identity if mode == "right".

mode: str

Whether the overlap is between "left" or "right" Schmidt vectors.

physical_leg: bool

Whether an MPS tensor with a physical leg (True) or an array of overlaps (False) is to be computed.

det_always: float | complex

Overlap determinant of the always occupied orbitals, \(\det(A)\) or \(\det(D)\).

sometimes_matrix: ndarray

Entries of the matrix \(\left(D - C A^{-1} B\right)\) or \(\left(A - B D^{-1} C\right)\) for all pairs of sometimes-occupied orbitals.

idx_bra: dict[int, slice]

idx_L of the bra Schmidt vector.

idx_ket: dict[int, slice]

idx_L of the ket Schmidt vector.

new_sets_bra: ndarray

Bra Schmidt vectors as occupation numbers of the sometimes-occupied orbitals.

Used to index the rows of sometimes_matrix.

If physical is True, it is double the length of sets and contains all Schmidt vectors with the on-site degree of freedom once empty, one filled. The overall array is still sorted by total charge to the left; within each sector, we first take the “Schmidt vectors” with empty on-site orbital.

new_sets_ket: ndarray

Ket Schmidt vectors as occupation numbers of the sometimes-occupied orbitals.

Used to index the columns of sometimes_matrix.

qtotal: int

Total charge of the tensor to ensure matching fermion numbers in Schmidt vectors.

  • For mode == "left", always 0.

  • For mode == "right", equals the difference of n_fermion between the ket and bra Schmidt vectors.

property idx_physical: int | None

Row index of the onsite degree of freedom in sometimes_matrix or None if there is no such degree of freedom.

classmethod from_schmidt_vectors(Schmidt_bra, Schmidt_ket, mode)[source]

Constructs MPSTensorData from Schmidt vectors on the two entanglement cuts next to a site.

Depending on the value of mode, it uses either “left” or “right” Schmidt vectors, resulting in a left or right canonical MPS tensor, respectively. In both cases, Schmidt_bra corresponds to Schmidt vectors on the shorter chain.

Parameters:
  • Schmidt_bra (SchmidtVectors) –

    Schmidt vectors corresponding to the bra states in the overlap.

    That is, for the entanglement cut to the left if mode=="left" or to the right if mode="right".

  • Schmidt_ket (SchmidtVectors) –

    Schmidt vectors corresponding to the ket states in the overlap.

    That is, for the entanglement cut to the right if mode=="left" or to the left if mode="right".

  • mode (str) –

    Whether to construct the tensor from left or right Schmidt vectors.

    Must be either “left” or “right”.

Return type:

MPSTensorData

to_npc_array()[source]

The MPS tensor as a TeNPy Array object.

Return type:

Array

Functions

temfpy.slater.correlation_matrix(H, N=None)[source]

Ground-state correlation matrix of a mean-field Hamiltonian.

Parameters:
  • H (ndarray) – Real-space mean-field Hamiltonian.

  • N (int | None) –

    Number of occupied orbitals.

    If not specified (default), all orbitals with negative energy are filled.

Return type:

tuple[ndarray, int]

Returns:

C: ndarray

The correlation matrix, \(C_{ij} = \langle c_j^\dagger c_i\rangle\).

N: int

The number of occupied orbitals.

temfpy.slater.C_to_MPS(C, trunc_par, *, diag_tol=1e-08, ortho_center=None)[source]

MPS representation of a Slater determinant from its correlation matrix.

Parameters:
  • C (ndarray) – The correlation matrix, \(C_{ij} = \langle c_j^\dagger c_i\rangle\).

  • trunc_par (dict | StoppingCondition) –

    Specifies which Schmidt states should be kept.

    Must be either a StoppingCondition object or a dictionary with matching keys.

    Only specify the field sectors if you know what you are doing!!

  • diag_tol (float) – Largest allowed offdiagonal matrix element in diagonalised / SVD correlation submatrices before an error is raised.

  • ortho_center (int) – Orthogonality centre of the mixed canonical MPS. Midpoint of the chain by default.

Return type:

MPS

Returns:

The wave function as a TeNPy MPS object.

Note

  • If trunc_par.svd_min is not provided, the truncation threshold defaults to 1e-6.

  • If trunc_par.degeneracy_tol is not provided, the degeneracy tolerance defaults to 1e-12.

temfpy.slater.C_to_iMPS(C_short, C_long, trunc_par, sites_per_cell, cut, *, diag_tol=1e-08, unitary_tol=1e-06, schmidt_tol=1e-06)[source]

iMPS representation of a Slater determinant from correlation matrices.

The two correlation matrices are expected to represent the ground states of a gapped, translation invariant Hamiltonian on two system sizes that differ by one repeating unit cell.

The method is analogous to iMPS.MPS_to_iMPS(), with two differences:

  • No explicit MPS tensors are computed for the environment of the iMPS unit cell. Instead, the Schmidt vector overlaps needed for gauge fixing are computed using the Slater determinant overlap formulas implemented in MPSTensorData.

  • The rightmost tensor is computed directly using the right Schmidt vectors of the shorter chain. This means that no separate iMPSErrors are returned for the right side.

Parameters:
  • C_short (ndarray) – The correlation matrix, \(C_{ij} = \langle c_j^\dagger c_i\rangle\), for the shorter chain.

  • C_long (ndarray) – The correlation matrix for the longer chain.

  • trunc_par (dict | StoppingCondition) –

    Specifies which Schmidt states should be kept.

    Must be either a StoppingCondition object or a dictionary with matching keys.

    Only specify the field sectors if you know what you are doing!!

  • sites_per_cell (int) – Size of the iMPS unit cell.

  • cut (int) – First site of the repeating unit cell in C_long.

  • diag_tol (float) – Largest allowed offdiagonal matrix element in diagonalised / SVD correlation submatrices before an error is raised.

  • unitary_tol (float) – Maximum deviation of the gauge rotation matrices from unitarity before a warning is raised.

  • schmidt_tol (float) – Maximum mixing of unequal Schmidt values by the gauge rotation matrices before a warning is raised.

Return type:

tuple[MPS, iMPSError]

Returns:

  • iMPS (MPS) – iMPS with unit cell size sites_per_cell, constructed from the additional unit cell of mps_long.

  • validation_metric (iMPSError) – Errors introduced during the conversion.

Note

  • If trunc_par.svd_min is not provided, the truncation threshold defaults to 1e-6.

  • If trunc_par.degeneracy_tol is not provided, the degeneracy tolerance defaults to 1e-12.