r"""Module containing the Schrieffer-Wolff transformation functionality in Python."""
# Copyright © 2021-2024 HQS Quantum Simulations GmbH. All Rights Reserved.
import sys
import textwrap
import numpy as np
from typing import Optional
from hqs_spin_mapper.spin_mapper_protocols import (
Supports_SW_Transformation,
InsufficientProtocolError,
)
try:
import hqs_spin_mapper.linear_algebraic_schrieffer_wolff as sw
except ImportError as e:
if "mkl" in str(e):
print(
textwrap.dedent(
"""\
===== ERROR: Missing MKL =====
The Intel Math Kernel Library (MKL) could not be found. Please ensure
that the MKL is installed properly.
When using HQStage, run
hqstage envs install-mkl
to install the MKL. In other cases, please consult the manual."""
),
file=sys.stderr,
)
sys.exit(1)
else:
raise
__all__ = [
"schrieffer_wolff",
]
[docs]
def schrieffer_wolff(
transformable_system: Supports_SW_Transformation,
number_bath_operators_for_contraction: int = 1,
_vector_space_cap: int = 1500000,
_max_krylov_space_dimension: int = 200,
rdm1_uu: Optional[np.ndarray] = None,
rdm1_dd: Optional[np.ndarray] = None,
rdm1_ud: Optional[np.ndarray] = None,
) -> None:
r"""Interface function for the Schrieffer-Wolff transformation functionality.
The function takes the tensor description of the Hamiltonian and interfaces with a C++
code that turns this description into a Fermions.ExpressionSpinful and then proceeds to perform
a Schrieffer-Wolff transformation. The computed generator can be used to transform potential
remaining terms of the original Hamiltonian.
Args:
transformable_system (Supports_SW_Transformation): Container object for the system data
number_bath_operators_for_contraction (int): Number of contractions to be performed
_vector_space_cap (int): Limit for the size of the vector space
_sv_cutoff (float): Relative cutoff for the singular values
_max_krylov_space_dimension (int): Maximum size of the Krylov subspace of the solver
rdm1_uu (Optional[np.ndarray]): Used for 1-RDM decoupling (currently deactivated)
rdm1_dd (Optional[np.ndarray]): Used for 1-RDM decoupling (currently deactivated)
rdm1_ud (Optional[np.ndarray]): Used for 1-RDM decoupling (currently deactivated)
Raises:
InsufficientProtocolError: transformable_system does not satisfy Supports_SW_Transformation
ValueError: No spin-like orbital indices were specified
"""
if not isinstance(transformable_system, Supports_SW_Transformation):
raise InsufficientProtocolError(transformable_system, Supports_SW_Transformation)
if len(transformable_system.spin_indices) == 0:
raise ValueError("A non-zero amount of spin-like orbitals is required!")
dim = transformable_system.system_size
spin_indices = transformable_system.spin_indices
prefactor_cutoff = transformable_system.prefactor_cutoff
hamiltonians = transformable_system.hamiltonians
# Call the linear algebraic Schrieffer-Wolff functionality implemented in C++
# This function turns the input tensors into Fermions.ExpressionSpinful,
# determines the generator S and returns it alongside the transformed Hamiltonian.
H_SW, S = sw.schrieffer_wolff(
H0_uu=hamiltonians.H0_uu,
H0_dd=hamiltonians.H0_dd,
H0_ud=hamiltonians.H0_ud,
HU=hamiltonians.HU.reshape(pow(dim, 4)),
spins=spin_indices,
prefactor_cutoff=prefactor_cutoff,
number_bath_operators_for_contraction=number_bath_operators_for_contraction,
_vector_space_cap=_vector_space_cap,
_max_krylov_space_dimension=_max_krylov_space_dimension,
rdm1_uu=rdm1_uu,
rdm1_dd=rdm1_dd,
rdm1_ud=rdm1_ud,
)
transformable_system.transformed_hamiltonian = H_SW
transformable_system.generator = S