qrunch.chemistry.integral_builders.lazy_ri_integrals

Lazy two-body electron repulsion integrals that defer computation until needed.

Classes

LazyRestrictedResolutionOfTheIdentityIntegrals

Lazy wrapper that defers two-body integral computation until the integrals are actually accessed.

LazyUnrestrictedResolutionOfTheIdentityIntegrals

Lazy wrapper that defers two-body integral computation until the integrals are actually accessed.

class LazyRestrictedResolutionOfTheIdentityIntegrals

Bases: RestrictedTwoBodyElectronRepulsionIntegralsProtocol, LazyIntegralsProtocol

Lazy wrapper that defers two-body integral computation until the integrals are actually accessed.

This class stores the ingredients needed to compute two-body electron repulsion integrals (molecular orbitals, molecular configuration, and an integral builder) and only materializes the integrals when they are first accessed.

The assumption is that it is the active space modifier that will need it first, and thus the subset of integrals needed for the active space will be computed directly without ever building the full N^4 tensor.

__init__(molecular_orbitals: RestrictedMolecularOrbitals, molecular_configuration: MolecularConfiguration, integral_builder: ResolutionOfTheIdentityIntegralBuilder, contraction_batch_size: int = 32) None

Initialize lazy integrals with the ingredients for deferred computation.

Parameters:
Return type:

None

active_space(active_orbitals: tuple[int, ...], reduction_tolerance: float = 1e-10) RestrictedTwoBodyElectronRepulsionIntegralsProtocol

Return the active space integrals by computing only the needed subset.

Instead of materializing the full tensor and extracting a sub-block, this method computes integrals directly for the requested active orbitals via calculate_for_orbital_subset().

This is the standard way to obtain integrals from the lazy wrapper. Alternative is the force_computation method which materializes the full tensor.

Parameters:
  • active_orbitals (tuple[int, ...]) – Active orbital indices.

  • reduction_tolerance (float) – Relative threshold for pruning.

Return type:

RestrictedTwoBodyElectronRepulsionIntegralsProtocol

property alpha_alpha: ndarray[tuple[Any, ...], dtype[float64]]

Return the alpha-alpha integrals, materializing if needed.

property beta_alpha: ndarray[tuple[Any, ...], dtype[float64]]

Return the beta-alpha integrals, materializing if needed.

property beta_beta: ndarray[tuple[Any, ...], dtype[float64]]

Return the beta-beta integrals, materializing if needed.

classmethod decode(data: dict[str, Any]) LazyRestrictedResolutionOfTheIdentityIntegrals

Decode a dictionary to an instance.

Parameters:

data (dict[str, Any]) – The dictionary representation.

Return type:

LazyRestrictedResolutionOfTheIdentityIntegrals

einsum(component: Literal['aa', 'bb', 'mixed'], einsum_str: str, *operands: ndarray[tuple[Any, ...], dtype[float64]], index_slices: tuple[slice, slice, slice, slice] | None = None, **kwargs: Any) ndarray[tuple[Any, ...], dtype[float64]]

Perform einsum, computing only the minimal orbital subset needed.

When index_slices are provided, this method inspects them to determine the maximum orbital index referenced, computes (or retrieves from cache) a subset tensor covering [0, max_index), and delegates the einsum to that smaller tensor. The index_slices are passed through unchanged since the subset tensor preserves the same indexing for orbitals [0, max_index).

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • einsum_str (str) – The einsum string.

  • *operands (ndarray[tuple[Any, ...], dtype[float64]]) – Additional ndarrays.

  • index_slices (tuple[slice, slice, slice, slice] | None) – Optional slices to apply to the 4-index tensor.

  • **kwargs (Any) – Passed through to np.einsum.

Return type:

ndarray[tuple[Any, …], dtype[float64]]

encode() dict[str, Any]

Encode the instance into a dictionary.

Return type:

dict[str, Any]

force_computation() RestrictedTwoBodyElectronRepulsionIntegralsProtocol

Force computation of the full integral tensor and return it.

Return type:

RestrictedTwoBodyElectronRepulsionIntegralsProtocol

internal_contracted_left(component: Literal['aa', 'bb', 'mixed'], active_range: slice, inactive_range: slice) ndarray[tuple[Any, ...], dtype[float64]]

Contract over the two leftmost indices: \(g_{iipq} \to g_{pq}\).

Computes result[p,q] = sum_A sum_i L_left[A,i,i] * L_right[A,p,q] directly from the packed AO Cholesky factors in a single chunked pass.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • active_range (slice) – Slice selecting active MO columns for the free pair (p, q).

  • inactive_range (slice) – Slice selecting inactive MO columns for the contracted pair (i).

Return type:

ndarray[tuple[Any, …], dtype[float64]]

internal_contracted_middle(component: Literal['aa', 'bb', 'mixed'], active_range: slice, inactive_range: slice) ndarray[tuple[Any, ...], dtype[float64]]

Contract over the two middle indices: \(g_{piiq} \to g_{pq}\).

Computes result[p,q] = sum_A sum_i L_left[A,p,i] * L_right[A,i,q] directly from the packed AO Cholesky factors in a single chunked pass.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • active_range (slice) – Slice selecting active MO columns for the free pair (p, q).

  • inactive_range (slice) – Slice selecting inactive MO columns for the contracted pair (i).

Return type:

ndarray[tuple[Any, …], dtype[float64]]

internal_contracted_right(component: Literal['aa', 'bb', 'mixed'], active_range: slice, inactive_range: slice) ndarray[tuple[Any, ...], dtype[float64]]

Contract over the two rightmost indices: \(g_{pqii} \to g_{pq}\).

Computes result[p,q] = sum_A L_left[A,p,q] * sum_i L_right[A,i,i] directly from the packed AO Cholesky factors in a single chunked pass, never materialising the full MO-basis Cholesky tensor.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • active_range (slice) – Slice selecting active MO columns for the free pair (p, q).

  • inactive_range (slice) – Slice selecting inactive MO columns for the contracted pair (i).

Return type:

ndarray[tuple[Any, …], dtype[float64]]

internal_trace_contracted_middle(component: Literal['aa', 'bb', 'mixed'], orbital_range: slice) float

Compute \(\sum_{p,i} g_{piip}\) for the given orbital range and component.

Delegates to the RI builder for an efficient single-pass chunked computation.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • orbital_range (slice) – Slice selecting orbital indices for both the free and contracted pairs.

Return type:

float

internal_trace_contracted_right(component: Literal['aa', 'bb', 'mixed'], orbital_range: slice) float

Compute \(\sum_{p,i} g_{ppii}\) for the given orbital range and component.

Delegates to the RI builder for an efficient single-pass chunked computation.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • orbital_range (slice) – Slice selecting orbital indices for both the free and contracted pairs.

Return type:

float

property is_restricted: Literal[True]

Return True since this is restricted.

property molecular_configuration: MolecularConfiguration

Return the stored molecular configuration.

property molecular_orbitals: RestrictedMolecularOrbitals

Return the stored molecular orbitals.

property number_of_orbitals: int

Return the number of orbitals.

rotate(rotation_matrices: tuple[ndarray[tuple[Any, ...], dtype[float64]], ...]) LazyRestrictedResolutionOfTheIdentityIntegrals

Rotate the integrals lazily by composing the rotation into the stored MO coefficients.

Mathematically, rotating the materialised integrals by \(R\) is equivalent to replacing the MO coefficient matrix \(C\) with \(C R\), since the AO to MO transformation is linear in the MO coefficients. We therefore avoid materialising the full \(N^4\) tensor and simply return a new lazy instance whose stored MO coefficients have been multiplied by the rotation matrix on the right.

Parameters:

rotation_matrices (tuple[ndarray[tuple[Any, ...], dtype[float64]], ...]) – Tuple containing a single 2-dimensional square rotation matrix. Should match the structure given by the output of rotation_matrix_structure().

Return type:

LazyRestrictedResolutionOfTheIdentityIntegrals

rotation_matrix_structure() list[RotationBlockDefinition]

Get information on which blocks should be non-zero in the rotation matrix.

Return type:

list[RotationBlockDefinition]

property shape: tuple[int, int, int, int]

Return the shape of the 4-index tensor.

two_body_energy(number_of_occupied_orbitals: int) float

Compute the restricted two_electron Hartree-Fock energy..

Parameters:

number_of_occupied_orbitals (int) – The number of occupied alpha orbitals.

Return type:

float

class LazyUnrestrictedResolutionOfTheIdentityIntegrals

Bases: UnrestrictedTwoBodyElectronRepulsionIntegralsProtocol, LazyIntegralsProtocol

Lazy wrapper that defers two-body integral computation until the integrals are actually accessed.

This class stores the ingredients needed to compute two-body electron repulsion integrals (molecular orbitals, molecular configuration, and an integral builder) and only materializes the integrals when they are first accessed.

The assumption is that it is the active space modifier that will need it first, and thus the subset of integrals needed for the active space will be computed directly without ever building the full N^4 tensor.

__init__(molecular_orbitals: UnrestrictedMolecularOrbitals, molecular_configuration: MolecularConfiguration, integral_builder: ResolutionOfTheIdentityIntegralBuilder, contraction_batch_size: int = 32) None

Initialize lazy integrals with the ingredients for deferred computation.

Parameters:
Return type:

None

active_space(active_orbitals: tuple[int, ...], reduction_tolerance: float = 1e-10) UnrestrictedTwoBodyElectronRepulsionIntegralsProtocol

Return the active space integrals by computing only the needed subset.

Instead of materializing the full tensor and extracting a sub-block, this method computes integrals directly for the requested active orbitals via calculate_for_orbital_subset().

This is the standard way to obtain integrals from the lazy wrapper. Alternative is the force_computation method which materializes the full tensor.

Parameters:
  • active_orbitals (tuple[int, ...]) – Active orbital indices.

  • reduction_tolerance (float) – Relative threshold for pruning.

Return type:

UnrestrictedTwoBodyElectronRepulsionIntegralsProtocol

property alpha_alpha: ndarray[tuple[Any, ...], dtype[float64]]

Return the alpha-alpha integrals, materializing if needed.

property beta_alpha: ndarray[tuple[Any, ...], dtype[float64]]

Return the beta-alpha integrals, materializing if needed.

property beta_beta: ndarray[tuple[Any, ...], dtype[float64]]

Return the beta-beta integrals, materializing if needed.

classmethod decode(data: dict[str, Any]) LazyUnrestrictedResolutionOfTheIdentityIntegrals

Decode a dictionary to an instance.

Parameters:

data (dict[str, Any]) – The dictionary representation.

Return type:

LazyUnrestrictedResolutionOfTheIdentityIntegrals

einsum(component: Literal['aa', 'bb', 'mixed'], einsum_str: str, *operands: ndarray[tuple[Any, ...], dtype[float64]], index_slices: tuple[slice, slice, slice, slice] | None = None, **kwargs: Any) ndarray[tuple[Any, ...], dtype[float64]]

Perform einsum, computing only the minimal orbital subset needed.

When index_slices are provided, this method inspects them to determine the maximum orbital index referenced, computes (or retrieves from cache) a subset tensor covering [0, max_index), and delegates the einsum to that smaller tensor. The index_slices are passed through unchanged since the subset tensor preserves the same indexing for orbitals [0, max_index).

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • einsum_str (str) – The einsum string.

  • *operands (ndarray[tuple[Any, ...], dtype[float64]]) – Additional ndarrays.

  • index_slices (tuple[slice, slice, slice, slice] | None) – Optional slices to apply to the 4-index tensor.

  • **kwargs (Any) – Passed through to np.einsum.

Return type:

ndarray[tuple[Any, …], dtype[float64]]

encode() dict[str, Any]

Encode the instance into a dictionary.

Return type:

dict[str, Any]

force_computation() UnrestrictedTwoBodyElectronRepulsionIntegralsProtocol

Force computation of the full integral tensor and return it.

Return type:

UnrestrictedTwoBodyElectronRepulsionIntegralsProtocol

internal_contracted_left(component: Literal['aa', 'bb', 'mixed'], active_range: slice, inactive_range: slice) ndarray[tuple[Any, ...], dtype[float64]]

Contract over the two leftmost indices: \(g_{iipq} \to g_{pq}\).

Computes result[p,q] = sum_A sum_i L_left[A,i,i] * L_right[A,p,q] directly from the packed AO Cholesky factors in a single chunked pass.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • active_range (slice) – Slice selecting active MO columns for the free pair (p, q).

  • inactive_range (slice) – Slice selecting inactive MO columns for the contracted pair (i).

Return type:

ndarray[tuple[Any, …], dtype[float64]]

internal_contracted_middle(component: Literal['aa', 'bb', 'mixed'], active_range: slice, inactive_range: slice) ndarray[tuple[Any, ...], dtype[float64]]

Contract over the two middle indices: \(g_{piiq} \to g_{pq}\).

Computes result[p,q] = sum_A sum_i L_left[A,p,i] * L_right[A,i,q] directly from the packed AO Cholesky factors in a single chunked pass.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • active_range (slice) – Slice selecting active MO columns for the free pair (p, q).

  • inactive_range (slice) – Slice selecting inactive MO columns for the contracted pair (i).

Return type:

ndarray[tuple[Any, …], dtype[float64]]

internal_contracted_right(component: Literal['aa', 'bb', 'mixed'], active_range: slice, inactive_range: slice) ndarray[tuple[Any, ...], dtype[float64]]

Contract over the two rightmost indices: \(g_{pqii} \to g_{pq}\).

Computes result[p,q] = sum_A L_left[A,p,q] * sum_i L_right[A,i,i] directly from the packed AO Cholesky factors in a single chunked pass, never materialising the full MO-basis Cholesky tensor.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • active_range (slice) – Slice selecting active MO columns for the free pair (p, q).

  • inactive_range (slice) – Slice selecting inactive MO columns for the contracted pair (i).

Return type:

ndarray[tuple[Any, …], dtype[float64]]

internal_trace_contracted_middle(component: Literal['aa', 'bb', 'mixed'], orbital_range: slice) float

Compute \(\sum_{p,i} g_{piip}\) for the given orbital range and component.

Delegates to the RI builder for an efficient single-pass chunked computation.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • orbital_range (slice) – Slice selecting orbital indices for both the free and contracted pairs.

Return type:

float

internal_trace_contracted_right(component: Literal['aa', 'bb', 'mixed'], orbital_range: slice) float

Compute \(\sum_{p,i} g_{ppii}\) for the given orbital range and component.

Delegates to the RI builder for an efficient single-pass chunked computation.

Parameters:
  • component (Literal['aa', 'bb', 'mixed']) – Which integral component to use “aa”, “bb”, or “mixed”.

  • orbital_range (slice) – Slice selecting orbital indices for both the free and contracted pairs.

Return type:

float

property is_restricted: Literal[False]

Return False since this is unrestricted.

property molecular_configuration: MolecularConfiguration

Return the stored molecular configuration.

property molecular_orbitals: UnrestrictedMolecularOrbitals

Return the stored molecular orbitals.

property number_of_orbitals: int

Return the number of orbitals.

rotate(rotation_matrices: tuple[ndarray[tuple[Any, ...], dtype[float64]], ...]) LazyUnrestrictedResolutionOfTheIdentityIntegrals

Rotate the integrals lazily by composing the rotations into the stored MO coefficients.

Mathematically, rotating the materialised integrals by \((R_\alpha, R_\beta)\) is equivalent to replacing the MO coefficient matrices \(C_\alpha\) and \(C_\beta\) with \(C_\alpha R_\alpha\) and \(C_\beta R_\beta\), since the AO to MO transformation is linear in the MO coefficients. We therefore avoid materialising the full \(N^4\) tensor and return a new lazy instance whose stored MO coefficients have been multiplied by the rotation matrices on the right.

Parameters:

rotation_matrices (tuple[ndarray[tuple[Any, ...], dtype[float64]], ...]) – Tuple containing two 2-dimensional square rotation matrices (R_alpha, R_beta). Should match the structure given by the output of rotation_matrix_structure().

Return type:

LazyUnrestrictedResolutionOfTheIdentityIntegrals

rotation_matrix_structure() list[RotationBlockDefinition]

Get information on which blocks should be non-zero in the rotation matrix.

Return type:

list[RotationBlockDefinition]

property shape: tuple[int, int, int, int]

Return the shape of the 4-index tensor.

two_body_energy(number_of_occupied_alpha_orbitals: int, number_of_occupied_beta_orbitals: int) float

Compute the unrestricted two-electron Hartree-Fock energy.

Parameters:
  • number_of_occupied_alpha_orbitals (int) – The number of occupied alpha orbitals.

  • number_of_occupied_beta_orbitals (int) – The number of occupied beta orbitals.

Return type:

float