dyson.representations.lehmann#

Container for a Lehmann representation.

Functions

shift_energies(lehmann, shift)

Shift the energies of a Lehmann representation using a context manager.

Classes

Lehmann(energies, couplings[, chempot, sort])

Lehman representation.

dyson.representations.lehmann.shift_energies(lehmann: Lehmann, shift: float) Iterator[None][source]#

Shift the energies of a Lehmann representation using a context manager.

Parameters:
  • lehmann – The Lehmann representation to shift.

  • shift – The amount to shift the energies by.

Yields:

None

class dyson.representations.lehmann.Lehmann(energies: ndarray, couplings: ndarray, chempot: float = 0.0, sort: bool = True)[source]#

Bases: BaseRepresentation

Lehman representation.

The Lehmann representation is a set of poles \(\epsilon_k\) and couplings \(v_{pk}\) that can be downfolded into a frequency-dependent function as

\[\sum_{k} \frac{v_{pk} u_{qk}^*}{\omega - \epsilon_k},\]

where the couplings are between the poles \(k\) and the physical space \(p\) and \(q\), and may be non-Hermitian. The couplings \(v\) are right-handed vectors, and \(u\) are left-handed vectors.

Note that the order of the couplings is (left, right), whilst they act in the order (right, left) in the numerator. The naming convention is chosen to be consistent with the eigenvalue decomposition, where \(v\) may be an eigenvector acting on the right of a matrix, and \(u\) is an eigenvector acting on the left of a matrix.

classmethod from_pyscf(auxspace: pyscf.agf2.aux.AuxSpace | Lehmann) Lehmann[source]#

Construct a Lehmann representation from a PySCF auxiliary space.

Parameters:

auxspace – The auxiliary space.

Returns:

A Lehmann representation.

classmethod from_empty(nphys: int) Lehmann[source]#

Construct an empty Lehmann representation.

Parameters:

nphys – The number of physical degrees of freedom.

Returns:

An empty Lehmann representation.

sort_() None[source]#

Sort the poles by energy.

Note

The object is sorted in place.

property energies: ndarray#

Get the energies.

property couplings: ndarray#

Get the couplings.

property chempot: float#

Get the chemical potential.

property hermitian: bool#

Get a boolean indicating if the system is Hermitian.

unpack_couplings() tuple[ndarray, ndarray][source]#

Unpack the couplings.

Returns:

A tuple of left and right couplings.

property nphys: int#

Get the number of physical degrees of freedom.

property naux: int#

Get the number of auxiliary degrees of freedom.

property dtype: dtype#

Get the data type of the couplings.

mask(mask: ndarray | slice, deep: bool = True) Lehmann[source]#

Return a part of the Lehmann representation according to a mask.

Parameters:
  • mask – The mask to apply.

  • deep – Whether to return a deep copy of the energies and couplings.

Returns:

A new Lehmann representation including only the masked states.

physical(weight: float = 0.1, deep: bool = True) Lehmann[source]#

Return the physical (large weight) part of the Lehmann representation.

Parameters:
  • weight – The weight to use for the physical part.

  • deep – Whether to return a deep copy of the energies and couplings.

Returns:

A new Lehmann representation including only the physical part.

occupied(deep: bool = True) Lehmann[source]#

Return the occupied part of the Lehmann representation.

Parameters:

deep – Whether to return a deep copy of the energies and couplings.

Returns:

A new Lehmann representation including only the occupied part.

virtual(deep: bool = True) Lehmann[source]#

Return the virtual part of the Lehmann representation.

Parameters:

deep – Whether to return a deep copy of the energies and couplings.

Returns:

A new Lehmann representation including only the virtual part.

copy(chempot: float | None = None, deep: bool = True) Lehmann[source]#

Return a copy of the Lehmann representation.

Parameters:
  • chempot – The chemical potential to use for the copy. If None, the original chemical potential is used.

  • deep – Whether to return a deep copy of the energies and couplings.

Returns:

A new Lehmann representation.

rotate_couplings(rotation: ndarray | tuple[ndarray, ndarray]) Lehmann[source]#

Rotate the couplings and return a new Lehmann representation.

For rotation matrix \(R\), the couplings are rotated as

\[\tilde{\mathbf{v}} = R^\dagger \mathbf{v}, \quad \tilde{\mathbf{u}} = R^\dagger \mathbf{u},\]

where \(v\) are the right couplings and \(u\) are the left couplings.

Parameters:

rotation – The rotation matrix to apply to the couplings. If the matrix has three dimensions, the first dimension is used to rotate the left couplings, and the second dimension is used to rotate the right couplings.

Returns:

A new Lehmann representation with the couplings rotated into the new basis.

moments(order: int | Iterable[int], reduction: Reduction = Reduction.NONE) Array[source]#

Calculate the moment(s) of the Lehmann representation.

The moments are defined as

\[T_{pq}^{n} = \sum_{k} v_{pk} u_{qk}^* \epsilon_k^n,\]

where \(T_{pq}^{n}\) is the moment of order \(n\) in the physical space. In terms of the frequency-dependency, the moments can be written as the integral

\[T_{pq}^{n} = \int_{-\infty}^{\infty} d\omega \, \left[ \sum_{k} \frac{v_{pk} u_{qk}^*}{\omega - \epsilon_k} \right] \, \omega^n,\]

where the integral is over the entire real line for central moments.

Parameters:
  • order – The order(s) of the moment(s).

  • reduction – The reduction to apply to the moments.

Returns:

The moment(s) of the Lehmann representation.

moment(order: int | Iterable[int], reduction: Reduction = Reduction.NONE) Array#

Calculate the moment(s) of the Lehmann representation.

The moments are defined as

\[T_{pq}^{n} = \sum_{k} v_{pk} u_{qk}^* \epsilon_k^n,\]

where \(T_{pq}^{n}\) is the moment of order \(n\) in the physical space. In terms of the frequency-dependency, the moments can be written as the integral

\[T_{pq}^{n} = \int_{-\infty}^{\infty} d\omega \, \left[ \sum_{k} \frac{v_{pk} u_{qk}^*}{\omega - \epsilon_k} \right] \, \omega^n,\]

where the integral is over the entire real line for central moments.

Parameters:
  • order – The order(s) of the moment(s).

  • reduction – The reduction to apply to the moments.

Returns:

The moment(s) of the Lehmann representation.

chebyshev_moments(order: int | Iterable[int], scaling: tuple[float, float] | None = None, scale_couplings: bool = False) Array[source]#

Calculate the Chebyshev polynomial moment(s) of the Lehmann representation.

The Chebyshev moments are defined as

\[T_{pq}^{n} = \sum_{k} v_{pk} u_{qk}^* P_n(\epsilon_k),\]

where \(P_n(x)\) is the Chebyshev polynomial of order \(n\).

Parameters:
  • order – The order(s) of the moment(s).

  • scaling – Scaling factors to ensure the energy scale of the Lehmann representation is in [-1, 1]. The scaling is applied as (energies - scaling[1]) / scaling[0]. If None, the default scaling is computed as (max(energies) - min(energies)) / (2.0 - 1e-3) and (max(energies) + min(energies)) / 2.0, respectively.

  • scale_couplings – Scale the couplings as well as the energy spectrum. This is generally necessary for Chebyshev moments of a self-energy, but not for a Green’s function.

Returns:

The Chebyshev polynomial moment(s) of the Lehmann representation.

chebyshev_moment(order: int | Iterable[int], scaling: tuple[float, float] | None = None, scale_couplings: bool = False) Array#

Calculate the Chebyshev polynomial moment(s) of the Lehmann representation.

The Chebyshev moments are defined as

\[T_{pq}^{n} = \sum_{k} v_{pk} u_{qk}^* P_n(\epsilon_k),\]

where \(P_n(x)\) is the Chebyshev polynomial of order \(n\).

Parameters:
  • order – The order(s) of the moment(s).

  • scaling – Scaling factors to ensure the energy scale of the Lehmann representation is in [-1, 1]. The scaling is applied as (energies - scaling[1]) / scaling[0]. If None, the default scaling is computed as (max(energies) - min(energies)) / (2.0 - 1e-3) and (max(energies) + min(energies)) / 2.0, respectively.

  • scale_couplings – Scale the couplings as well as the energy spectrum. This is generally necessary for Chebyshev moments of a self-energy, but not for a Green’s function.

Returns:

The Chebyshev polynomial moment(s) of the Lehmann representation.

matrix(physical: ndarray, chempot: bool | float = False) ndarray[source]#

Build the dense supermatrix form of the Lehmann representation.

The supermatrix is defined as

\[\begin{split}\begin{bmatrix} \mathbf{f} & \mathbf{v} \\ \mathbf{u}^\dagger & \boldsymbol{\epsilon} \mathbf{I} \end{bmatrix},\end{split}\]

where \(\mathbf{f}\) is the physical space part of the supermatrix, provided as an argument.

Parameters:
  • physical – The matrix to use for the physical space part of the supermatrix.

  • chempot – Whether to include the chemical potential in the supermatrix. If True, the chemical potential from chempot is used. If a float is given, that value is used.

Returns:

The supermatrix form of the Lehmann representation.

diagonal(physical: ndarray, chempot: bool | float = False) ndarray[source]#

Build the diagonal supermatrix form of the Lehmann representation.

The diagonal supermatrix is defined as

\[\begin{bmatrix} \mathrm{diag}(\mathbf{f}) & \boldsymbol{\epsilon} \end{bmatrix},\]

where \(\mathbf{f}\) is the physical space part of the supermatrix, provided as an argument.

Parameters:
  • physical – The matrix to use for the physical space part of the supermatrix.

  • chempot – Whether to include the chemical potential in the supermatrix. If True, the chemical potential from chempot is used. If a float is given, that value is used.

Returns:

The diagonal supermatrix form of the Lehmann representation.

matvec(physical: ndarray, vector: ndarray, chempot: bool | float = False) ndarray[source]#

Apply the supermatrix to a vector.

The matrix-vector product is defined as

\[\begin{split}\begin{bmatrix} \mathbf{x}_\mathrm{phys} \\ \mathbf{x}_\mathrm{aux} \end{bmatrix} = \begin{bmatrix} \mathbf{f} & \mathbf{v} \\ \mathbf{u}^\dagger & \mathbf{\epsilon} \mathbf{I} \end{bmatrix} \begin{bmatrix} \mathbf{r}_\mathrm{phys} \\ \mathbf{r}_\mathrm{aux} \end{bmatrix},\end{split}\]

where \(\mathbf{f}\) is the physical space part of the supermatrix, and the input vector \(\mathbf{r}\) is spans both the physical and auxiliary spaces.

Parameters:
  • physical – The matrix to use for the physical space part of the supermatrix.

  • vector – The vector to apply the supermatrix to.

  • chempot – Whether to include the chemical potential in the supermatrix. If True, the chemical potential from chempot is used. If a float is given, that value is used.

Returns:

The result of applying the supermatrix to the vector.

diagonalise_matrix(physical: ndarray, chempot: bool | float = False, overlap: ndarray | None = None) tuple[ndarray, ndarray][source]#

Diagonalise the supermatrix.

The eigenvalue problem is defined as

\[\begin{split}\begin{bmatrix} \mathbf{f} & \mathbf{v} \\ \mathbf{u}^\dagger & \mathbf{\epsilon} \mathbf{1} \end{bmatrix} \begin{bmatrix} \mathbf{x}_\mathrm{phys} \\ \mathbf{x}_\mathrm{aux} \end{bmatrix} = E \begin{bmatrix} \mathbf{x}_\mathrm{phys} \\ \mathbf{x}_\mathrm{aux} \end{bmatrix},\end{split}\]

where \(\mathbf{f}\) is the physical space part of the supermatrix, and the eigenvectors \(\mathbf{x}\) span both the physical and auxiliary spaces.

Parameters:
  • physical – The matrix to use for the physical space part of the supermatrix.

  • chempot – Whether to include the chemical potential in the supermatrix. If True, the chemical potential from chempot is used. If a float is given, that value is used.

  • overlap – The overlap matrix to use for the physical space part of the supermatrix. If None, the identity matrix is used.

Returns:

The eigenvalues and eigenvectors of the supermatrix.

Note

If a non-identity overlap matrix is provided, this is equivalent to performing a generalised eigenvalue decomposition of the supermatrix, with the overlap in the auxiliary space assumed to be the identity.

diagonalise_matrix_with_projection(physical: ndarray, chempot: bool | float = False, overlap: ndarray | None = None) tuple[ndarray, ndarray][source]#

Diagonalise the supermatrix and project the eigenvectors into the physical space.

The projection of the eigenvectors is

\[\mathbf{x}_\mathrm{phys} = \mathbf{P}_\mathrm{phys} \mathbf{x},\]

where \(\mathbf{P}_\mathrm{phys}\) is the projection operator onto the physical space, which can be written as

\[\begin{split}\mathbf{P}_\mathrm{phys} = \begin{bmatrix} \mathbf{I} & 0 \\ 0 & 0 \end{bmatrix},\end{split}\]

within the supermatrix block structure of matrix().

Parameters:
  • physical – The matrix to use for the physical space part of the supermatrix.

  • chempot – Whether to include the chemical potential in the supermatrix. If True, the chemical potential from chempot is used. If a float is given, that value is used.

  • overlap – The overlap matrix to use for the physical space part of the supermatrix. If None, the identity matrix is used.

Returns:

The eigenvalues and eigenvectors of the supermatrix, with the eigenvectors projected into the physical space.

See also

diagonalise_matrix() for the full eigenvalue decomposition of the supermatrix.

weights(occupancy: float = 1.0) ndarray[source]#

Get the weights of the residues in the Lehmann representation.

The weights are defined as

\[w_k = \sum_{p} v_{pk} u_{pk}^*,\]

where \(w_k\) is the weight of residue \(k\).

Parameters:

occupancy – The occupancy of the states.

Returns:

The weights of each state.

as_orbitals(occupancy: float = 1.0, mo_coeff: ndarray | None = None) tuple[ndarray, ndarray, ndarray][source]#

Convert the Lehmann representation to an orbital representation.

Parameters:
  • occupancy – The occupancy of the states.

  • mo_coeff – The molecular orbital coefficients. If given, the couplings will have their physical dimension rotated into the AO basis according to these coefficients.

Returns:

The energies, coefficients, and occupancies of the states.

Note

This representation is intended to be compatible with PySCF’s mean-field representation of molecular orbitals.

as_perturbed_mo_energy() ndarray[source]#

Return an array of \(N_\mathrm{phys}\) pole energies according to best overlap.

The pole energies are selected as

\[\epsilon_p = \epsilon_k \quad \text{where} \quad k = \arg\max_{k} |v_{pk} u_{pk}^*|,\]

where \(\epsilon_p\) is the energy of the physical state \(p\), and \(k\) is the index of a pole in the Lehmann representation.

Returns:

The selected energies.

Note

The return value of this function is intended to be compatible with pyscf.scf.hf.SCF.mo_energy, i.e. it represents a reduced quasiparticle picture consisting of \(N_\mathrm{phys}\) energies that are picked from the poles of the Lehmann representation, according to the best overlap with the MO of the same index.

as_static_potential(mo_energy: ndarray, eta: float = 0.01) ndarray[source]#

Convert the Lehmann representation to a static potential.

The static potential is defined as

\[V_{pq} = \mathrm{Re}\left[ \sum_{k} \frac{v_{pk} u_{qk}^*}{\epsilon_p - \epsilon_k \pm i \eta} \right].\]
Parameters:
  • mo_energy – The molecular orbital energies.

  • eta – The broadening parameter.

Returns:

The static potential.

Note

The static potential in this format is common in methods such as quasiparticle self-consistent \(GW\) calculations.

split_physical(nocc: int) tuple[Lehmann, Lehmann][source]#

Split the physical domain of Lehmann representation into occupied and virtual parts.

Parameters:

nocc – The number of occupied states.

Returns:

The Lehmann representation coupled with the occupied and virtual parts, as separate Lehmann representations.

Note

The Fermi level (value at which the parts are separated) is defined by the chemical potential chempot.

combine_physical(other: Lehmann) Lehmann[source]#

Combine the physical domain of two Lehmann representations.

Parameters:

other – The other Lehmann representation to combine with.

Returns:

A new Lehmann representation that is the combination of the two.

Raises:

ValueError – If the two representations have different chemical potentials.

concatenate(other: Lehmann) Lehmann[source]#

Concatenate two Lehmann representations.

Parameters:

other – The other Lehmann representation to concatenate.

Returns:

A new Lehmann representation that is the concatenation of the two.

Raises:

ValueError – If the two representations have different physical dimensions or chemical potentials.