Base classes for ebcc.cc.

ebcc.cc.base.T = floating module-attribute

Defines the type for the eris argument in functions.

ebcc.cc.base.ERIsInputType = Any module-attribute

Defines the type for arrays, including spin labels.

ebcc.cc.base.SpinArrayType = Any module-attribute

Defines the type for the spaces, including spin labels.

ebcc.cc.base.BaseOptions(e_tol=1e-08, t_tol=1e-08, max_iter=200, diis_space=9, diis_min_space=1, damping=0.0, shift=True) dataclass

Bases: _BaseOptions

Options for EBCC calculations.

Parameters:
  • e_tol (float, default: 1e-08 ) –

    Threshold for convergence in the correlation energy.

  • t_tol (float, default: 1e-08 ) –

    Threshold for convergence in the amplitude norm.

  • max_iter (int, default: 200 ) –

    Maximum number of iterations.

  • diis_space (int, default: 9 ) –

    Number of amplitudes to use in DIIS extrapolation.

  • diis_min_space (int, default: 1 ) –

    Minimum number of amplitudes to use in DIIS extrapolation.

  • damping (float, default: 0.0 ) –

    Damping factor for DIIS extrapolation.

  • shift (bool, default: True ) –

    Shift the boson operators such that the Hamiltonian is normal-ordered with respect to a coherent state. This removes the bosonic coupling to the static mean-field density, introducing a constant energy shift.

ebcc.cc.base.BaseEBCC(mf, log=None, ansatz='CCSD', options=None, space=None, omega=None, g=None, G=None, mo_coeff=None, mo_occ=None, fock=None, **kwargs)

Bases: ABC

Base class for electron-boson coupled cluster.

Initialise the EBCC object.

Parameters:
  • mf (SCF) –

    PySCF mean-field object.

  • log (Optional[Logger], default: None ) –

    Log to write output to. Default is the global logger, outputting to stderr.

  • ansatz (Optional[Union[Ansatz, str]], default: 'CCSD' ) –

    Overall ansatz.

  • options (Optional[BaseOptions], default: None ) –

    Options for the EBCC calculation.

  • space (Optional[SpaceType], default: None ) –

    Space containing the frozen, correlated, and active fermionic spaces. Default assumes all electrons are correlated.

  • omega (Optional[NDArray[T]], default: None ) –

    Bosonic frequencies.

  • g (Optional[NDArray[T]], default: None ) –

    Electron-boson coupling matrix corresponding to the bosonic annihilation operator :math:g_{bpq} p^\dagger q b. The creation part is assumed to be the fermionic conjugate transpose to retain Hermiticity in the Hamiltonian.

  • G (Optional[NDArray[T]], default: None ) –

    Boson non-conserving term :math:G_{b} (b^\dagger + b).

  • mo_coeff (Optional[NDArray[T]], default: None ) –

    Molecular orbital coefficients. Default is the mean-field coefficients.

  • mo_occ (Optional[NDArray[T]], default: None ) –

    Molecular orbital occupation numbers. Default is the mean-field occupation.

  • fock (Optional[BaseFock], default: None ) –

    Fock matrix. Default is the mean-field Fock matrix.

  • **kwargs (Any, default: {} ) –

    Additional keyword arguments used to update options.

Source code in ebcc/cc/base.py
def __init__(
    self,
    mf: SCF,
    log: Optional[Logger] = None,
    ansatz: Optional[Union[Ansatz, str]] = "CCSD",
    options: Optional[BaseOptions] = None,
    space: Optional[SpaceType] = None,
    omega: Optional[NDArray[T]] = None,
    g: Optional[NDArray[T]] = None,
    G: Optional[NDArray[T]] = None,
    mo_coeff: Optional[NDArray[T]] = None,
    mo_occ: Optional[NDArray[T]] = None,
    fock: Optional[BaseFock] = None,
    **kwargs: Any,
) -> None:
    r"""Initialise the EBCC object.

    Args:
        mf: PySCF mean-field object.
        log: Log to write output to. Default is the global logger, outputting to `stderr`.
        ansatz: Overall ansatz.
        options: Options for the EBCC calculation.
        space: Space containing the frozen, correlated, and active fermionic spaces. Default
            assumes all electrons are correlated.
        omega: Bosonic frequencies.
        g: Electron-boson coupling matrix corresponding to the bosonic annihilation operator
            :math:`g_{bpq} p^\dagger q b`. The creation part is assumed to be the fermionic
            conjugate transpose to retain Hermiticity in the Hamiltonian.
        G: Boson non-conserving term :math:`G_{b} (b^\dagger + b)`.
        mo_coeff: Molecular orbital coefficients. Default is the mean-field coefficients.
        mo_occ: Molecular orbital occupation numbers. Default is the mean-field occupation.
        fock: Fock matrix. Default is the mean-field Fock matrix.
        **kwargs: Additional keyword arguments used to update `options`.
    """
    # Options:
    if options is None:
        options = self.Options()
    self.options = options
    for key, val in kwargs.items():
        setattr(self.options, key, val)

    # Parameters:
    self.log = default_log if log is None else log
    self.mf = self._convert_mf(mf)
    self._mo_coeff: Optional[NDArray[T]] = (
        np.asarray(mo_coeff, dtype=types[float]) if mo_coeff is not None else None
    )
    self._mo_occ: Optional[NDArray[T]] = (
        np.asarray(mo_occ, dtype=types[float]) if mo_occ is not None else None
    )

    # Ansatz:
    if isinstance(ansatz, Ansatz):
        self.ansatz = ansatz
    elif isinstance(ansatz, str):
        self.ansatz = Ansatz.from_string(
            ansatz, density_fitting=getattr(self.mf, "with_df", None) is not None
        )
    else:
        raise TypeError("ansatz must be an Ansatz object or a string.")
    self._eqns = self.ansatz._get_eqns(self.spin_type)

    # Space:
    if space is not None:
        self.space = space
    else:
        self.space = self.init_space()

    # Boson parameters:
    if bool(self.fermion_coupling_rank) != bool(self.boson_coupling_rank):
        raise ValueError(
            "Fermionic and bosonic coupling ranks must both be zero, or both non-zero."
        )
    self.omega = np.asarray(omega, dtype=types[float]) if omega is not None else None
    self.bare_g = np.asarray(g, dtype=types[float]) if g is not None else None
    self.bare_G = np.asarray(G, dtype=types[float]) if G is not None else None
    if self.boson_ansatz != "":
        self.g = self.get_g()
        self.G = self.get_mean_field_G()
    else:
        assert self.nbos == 0
        self.options.shift = False
        self.g = None
        self.G = None

    # Fock matrix:
    if fock is None:
        self.fock = self.get_fock()
    else:
        self.fock = fock

    # Attributes:
    self.e_corr = 0.0
    self.amplitudes = util.Namespace()
    self.converged = False
    self.lambdas = util.Namespace()
    self.converged_lambda = False

    # Logging:
    init_logging(self.log)
    self.log.info(f"\n{ANSI.B}{ANSI.U}{self.name}{ANSI.R}")
    self.log.debug(f"{ANSI.B}{'*' * len(self.name)}{ANSI.R}")
    self.log.debug("")
    self.log.info(f"{ANSI.B}Options{ANSI.R}:")
    self.log.info(f" > e_tol:  {ANSI.y}{self.options.e_tol}{ANSI.R}")
    self.log.info(f" > t_tol:  {ANSI.y}{self.options.t_tol}{ANSI.R}")
    self.log.info(f" > max_iter:  {ANSI.y}{self.options.max_iter}{ANSI.R}")
    self.log.info(f" > diis_space:  {ANSI.y}{self.options.diis_space}{ANSI.R}")
    self.log.info(f" > diis_min_space:  {ANSI.y}{self.options.diis_min_space}{ANSI.R}")
    self.log.info(f" > damping:  {ANSI.y}{self.options.damping}{ANSI.R}")
    self.log.debug("")
    self.log.info(f"{ANSI.B}Ansatz{ANSI.R}: {ANSI.m}{self.ansatz}{ANSI.R}")
    self.log.debug("")
    self.log.info(f"{ANSI.B}Space{ANSI.R}: {ANSI.m}{self.space}{ANSI.R}")
    self.log.debug("")
    if self.boson_ansatz != "":
        self.log.info(f"{ANSI.B}Bosons{ANSI.R}: {ANSI.m}{self.nbos}{ANSI.R}")
        self.log.info(" > Energy shift due to polaritonic basis:  %.10f", self.const)
        self.log.debug("")

ebcc.cc.base.BaseEBCC.spin_type abstractmethod property

Get a string representation of the spin type.

ebcc.cc.base.BaseEBCC.name property

Get the name of the method.

ebcc.cc.base.BaseEBCC.fermion_ansatz property

Get a string representation of the fermion ansatz.

ebcc.cc.base.BaseEBCC.boson_ansatz property

Get a string representation of the boson ansatz.

ebcc.cc.base.BaseEBCC.fermion_coupling_rank property

Get an integer representation of the fermion coupling rank.

ebcc.cc.base.BaseEBCC.boson_coupling_rank property

Get an integer representation of the boson coupling rank.

ebcc.cc.base.BaseEBCC.xi abstractmethod property

Get the shift in the bosonic operators to diagonalise the photon Hamiltonian.

Returns:
  • NDArray[T]

    Shift in the bosonic operators.

ebcc.cc.base.BaseEBCC.const property

Get the shift in energy from moving to the polaritonic basis.

Returns:
  • float

    Constant energy shift due to the polaritonic basis.

ebcc.cc.base.BaseEBCC.mo_coeff property

Get the molecular orbital coefficients.

Returns:
  • NDArray[T]

    Molecular orbital coefficients.

ebcc.cc.base.BaseEBCC.mo_occ property

Get the molecular orbital occupation numbers.

Returns:
  • NDArray[T]

    Molecular orbital occupation numbers.

ebcc.cc.base.BaseEBCC.nmo abstractmethod property

Get the number of molecular orbitals.

Returns:
  • Any

    Number of molecular orbitals.

ebcc.cc.base.BaseEBCC.nocc abstractmethod property

Get the number of occupied molecular orbitals.

Returns:
  • Any

    Number of occupied molecular orbitals.

ebcc.cc.base.BaseEBCC.nvir abstractmethod property

Get the number of virtual molecular orbitals.

Returns:
  • Any

    Number of virtual molecular orbitals.

ebcc.cc.base.BaseEBCC.nbos property

Get the number of bosonic modes.

Returns:
  • int

    Number of bosonic modes.

ebcc.cc.base.BaseEBCC.e_tot property

Get the total energy (mean-field plus correlation).

Returns:
  • float

    Total energy.

ebcc.cc.base.BaseEBCC.t1 property

Get the T1 amplitudes.

ebcc.cc.base.BaseEBCC.t2 property

Get the T2 amplitudes.

ebcc.cc.base.BaseEBCC.t3 property

Get the T3 amplitudes.

ebcc.cc.base.BaseEBCC.l1 property

Get the L1 amplitudes.

ebcc.cc.base.BaseEBCC.l2 property

Get the L2 amplitudes.

ebcc.cc.base.BaseEBCC.l3 property

Get the L3 amplitudes.

ebcc.cc.base.BaseEBCC.kernel(eris=None)

Run the coupled cluster calculation.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def kernel(self, eris: Optional[ERIsInputType] = None) -> float:
    """Run the coupled cluster calculation.

    Args:
        eris: Electron repulsion integrals.

    Returns:
        Correlation energy.
    """
    timer = util.Timer()

    # Get the ERIs:
    eris = self.get_eris(eris)

    # Get the amplitude guesses:
    amplitudes = self.amplitudes
    if not amplitudes:
        amplitudes = self.init_amps(eris=eris)

    # Get the initial energy:
    e_cc = self.energy(amplitudes=amplitudes, eris=eris)

    self.log.output("Solving for excitation amplitudes.")
    self.log.debug("")
    self.log.info(
        f"{ANSI.B}{'Iter':>4s} {'Energy (corr.)':>16s} {'Energy (tot.)':>18s} "
        f"{'Δ(Energy)':>13s} {'Δ(Ampl.)':>13s}{ANSI.R}"
    )
    self.log.info("%4d %16.10f %18.10f", 0, e_cc, e_cc + self.mf.e_tot)

    if not self.ansatz.is_one_shot:
        # Set up damping:
        damping = self.Damping(options=self.options)

        converged = False
        for niter in range(1, self.options.max_iter + 1):
            # Update the amplitudes, extrapolate with DIIS and calculate change:
            amplitudes_prev = amplitudes
            amplitudes = self.update_amps(amplitudes=amplitudes, eris=eris)
            vector = self.amplitudes_to_vector(amplitudes)
            vector = damping(vector)
            amplitudes = self.vector_to_amplitudes(vector)
            dt = np.linalg.norm(
                np.abs(vector - self.amplitudes_to_vector(amplitudes_prev)), ord=np.inf
            )

            # Update the energy and calculate change:
            e_prev = e_cc
            e_cc = self.energy(amplitudes=amplitudes, eris=eris)
            de = abs(e_prev - e_cc)

            # Log the iteration:
            converged_e = bool(de < self.options.e_tol)
            converged_t = bool(dt < self.options.t_tol)
            self.log.info(
                f"%4d %16.10f %18.10f {[ANSI.r, ANSI.g][int(converged_e)]}%13.3e{ANSI.R}"
                f" {[ANSI.r, ANSI.g][int(converged_t)]}%13.3e{ANSI.R}",
                niter,
                e_cc,
                e_cc + self.mf.e_tot,
                de,
                dt,
            )

            # Check for convergence:
            converged = converged_e and converged_t
            if converged:
                self.log.debug("")
                self.log.output(f"{ANSI.g}Converged{ANSI.R}.")
                break
        else:
            self.log.debug("")
            self.log.warning(f"{ANSI.r}Failed to converge{ANSI.R}.")

        # Include perturbative correction if required:
        if self.ansatz.has_perturbative_correction:
            self.log.debug("")
            self.log.info("Computing perturbative energy correction.")
            e_pert = self.energy_perturbative(amplitudes=amplitudes, eris=eris)
            e_cc += e_pert
            self.log.info("E(pert) = %.10f", e_pert)

    else:
        converged = True

    # Update attributes:
    self.e_corr = e_cc
    self.amplitudes = amplitudes
    self.converged = converged

    self.log.debug("")
    self.log.output("E(corr) = %.10f", self.e_corr)
    self.log.output("E(tot)  = %.10f", self.e_corr + self.mf.e_tot)
    self.log.debug("")
    self.log.debug("Time elapsed: %s", timer.format_time(timer()))
    self.log.debug("")

    return e_cc

ebcc.cc.base.BaseEBCC.solve_lambda(amplitudes=None, eris=None)

Solve for the lambda amplitudes.

Parameters:
Source code in ebcc/cc/base.py
def solve_lambda(
    self,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    eris: Optional[ERIsInputType] = None,
) -> None:
    """Solve for the lambda amplitudes.

    Args:
        amplitudes: Cluster amplitudes.
        eris: Electron repulsion integrals.
    """
    timer = util.Timer()

    # Get the ERIs:
    eris = self.get_eris(eris)

    # Get the amplitudes:
    amplitudes = self.amplitudes
    if not amplitudes:
        amplitudes = self.init_amps(eris=eris)

    # If needed, get the perturbative part of the lambda amplitudes:
    lambdas_pert = None
    if self.ansatz.has_perturbative_correction:
        lambdas_pert = self.update_lams(eris=eris, amplitudes=amplitudes, perturbative=True)

    # Get the initial lambda amplitudes:
    lambdas = self.lambdas
    if not lambdas:
        lambdas = self.init_lams(amplitudes=amplitudes)

    self.log.output("Solving for de-excitation (lambda) amplitudes.")
    self.log.debug("")
    self.log.info(f"{ANSI.B}{'Iter':>4s} {'Δ(Ampl.)':>13s}{ANSI.R}")

    # Set up damping:
    damping = self.Damping(options=self.options)

    converged = False
    for niter in range(1, self.options.max_iter + 1):
        # Update the lambda amplitudes, extrapolate with DIIS and calculate change:
        lambdas_prev = lambdas
        lambdas = self.update_lams(
            amplitudes=amplitudes,
            lambdas=lambdas,
            lambdas_pert=lambdas_pert,
            eris=eris,
        )
        vector = self.lambdas_to_vector(lambdas)
        vector = damping(vector)
        lambdas = self.vector_to_lambdas(vector)
        dl = np.linalg.norm(np.abs(vector - self.lambdas_to_vector(lambdas_prev)), ord=np.inf)

        # Log the iteration:
        converged = bool(dl < self.options.t_tol)
        self.log.info(f"%4d {[ANSI.r, ANSI.g][int(converged)]}%13.3e{ANSI.R}", niter, dl)

        # Check for convergence:
        if converged:
            self.log.debug("")
            self.log.output(f"{ANSI.g}Converged{ANSI.R}.")
            break
    else:
        self.log.debug("")
        self.log.warning(f"{ANSI.r}Failed to converge{ANSI.R}.")

    self.log.debug("")
    self.log.debug("Time elapsed: %s", timer.format_time(timer()))
    self.log.debug("")
    self.log.debug("")

    # Update attributes:
    self.lambdas = lambdas
    self.converged_lambda = converged

ebcc.cc.base.BaseEBCC.ip_eom(**kwargs) abstractmethod

Get the IP-EOM object.

Parameters:
  • **kwargs (Any, default: {} ) –

    Additional keyword arguments.

Returns:
  • Any

    IP-EOM object.

Source code in ebcc/cc/base.py
@abstractmethod
def ip_eom(self, **kwargs: Any) -> Any:
    """Get the IP-EOM object.

    Args:
        **kwargs: Additional keyword arguments.

    Returns:
        IP-EOM object.
    """
    pass

ebcc.cc.base.BaseEBCC.ea_eom(**kwargs) abstractmethod

Get the EA-EOM object.

Parameters:
  • **kwargs (Any, default: {} ) –

    Additional keyword arguments.

Returns:
  • Any

    EA-EOM object.

Source code in ebcc/cc/base.py
@abstractmethod
def ea_eom(self, **kwargs: Any) -> Any:
    """Get the EA-EOM object.

    Args:
        **kwargs: Additional keyword arguments.

    Returns:
        EA-EOM object.
    """
    pass

ebcc.cc.base.BaseEBCC.ee_eom(**kwargs) abstractmethod

Get the EE-EOM object.

Parameters:
  • **kwargs (Any, default: {} ) –

    Additional keyword arguments.

Returns:
  • Any

    EE-EOM object.

Source code in ebcc/cc/base.py
@abstractmethod
def ee_eom(self, **kwargs: Any) -> Any:
    """Get the EE-EOM object.

    Args:
        **kwargs: Additional keyword arguments.

    Returns:
        EE-EOM object.
    """
    pass

ebcc.cc.base.BaseEBCC.brueckner(*args, **kwargs)

Run a Brueckner orbital coupled cluster calculation.

The coupled cluster object will be updated in-place.

Parameters:
  • *args (Any, default: () ) –

    Arguments to pass to the Brueckner object.

  • **kwargs (Any, default: {} ) –

    Keyword arguments to pass to the Brueckner object.

Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def brueckner(self, *args: Any, **kwargs: Any) -> float:
    """Run a Brueckner orbital coupled cluster calculation.

    The coupled cluster object will be updated in-place.

    Args:
        *args: Arguments to pass to the Brueckner object.
        **kwargs: Keyword arguments to pass to the Brueckner object.

    Returns:
        Correlation energy.
    """
    bcc = self.Brueckner(self, *args, **kwargs)
    return bcc.kernel()

ebcc.cc.base.BaseEBCC.external_correction(*args, **kwargs)

Run an externally corrected coupled cluster calculation.

Parameters:
  • *args (Any, default: () ) –

    Arguments to pass to the external correction object.

  • **kwargs (Any, default: {} ) –

    Keyword arguments to pass to the external correction object.

Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def external_correction(self, *args: Any, **kwargs: Any) -> float:
    """Run an externally corrected coupled cluster calculation.

    Args:
        *args: Arguments to pass to the external correction object.
        **kwargs: Keyword arguments to pass to the external correction object.

    Returns:
        Correlation energy.
    """
    with self.ExternalCorrection(self, *args, **kwargs):
        return self.kernel()

ebcc.cc.base.BaseEBCC.tailor(*args, **kwargs)

Run a tailored coupled cluster calculation.

Parameters:
  • *args (Any, default: () ) –

    Arguments to pass to the tailored object.

  • **kwargs (Any, default: {} ) –

    Keyword arguments to pass to the tailored object.

Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def tailor(self, *args: Any, **kwargs: Any) -> float:
    """Run a tailored coupled cluster calculation.

    Args:
        *args: Arguments to pass to the tailored object.
        **kwargs: Keyword arguments to pass to the tailored object.

    Returns:
        Correlation energy.
    """
    with self.Tailor(self, *args, **kwargs):
        return self.kernel()

ebcc.cc.base.BaseEBCC.write(file)

Write the EBCC object to a file.

Parameters:
  • file (str) –

    File to write the object to.

Source code in ebcc/cc/base.py
def write(self, file: str) -> None:
    """Write the EBCC object to a file.

    Args:
        file: File to write the object to.
    """
    writer = Dump(file)
    writer.write(self)

ebcc.cc.base.BaseEBCC.read(file, log=None) classmethod

Read the EBCC object from a file.

Parameters:
  • file (str) –

    File to read the object from.

  • log (Optional[Logger], default: None ) –

    Logger to use for new object.

Returns:
Source code in ebcc/cc/base.py
@classmethod
def read(cls, file: str, log: Optional[Logger] = None) -> BaseEBCC:
    """Read the EBCC object from a file.

    Args:
        file: File to read the object from.
        log: Logger to use for new object.

    Returns:
        EBCC object.
    """
    reader = Dump(file)
    return reader.read(cls=cls, log=log)

ebcc.cc.base.BaseEBCC.init_amps(eris=None) abstractmethod

Initialise the cluster amplitudes.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def init_amps(self, eris: Optional[ERIsInputType] = None) -> Namespace[SpinArrayType]:
    """Initialise the cluster amplitudes.

    Args:
        eris: Electron repulsion integrals.

    Returns:
        Initial cluster amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.init_lams(amplitudes=None) abstractmethod

Initialise the cluster lambda amplitudes.

Parameters:
Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def init_lams(
    self, amplitudes: Optional[Namespace[SpinArrayType]] = None
) -> Namespace[SpinArrayType]:
    """Initialise the cluster lambda amplitudes.

    Args:
        amplitudes: Cluster amplitudes.

    Returns:
        Initial cluster lambda amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.energy(eris=None, amplitudes=None)

Calculate the correlation energy.

Parameters:
Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def energy(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
) -> float:
    """Calculate the correlation energy.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.

    Returns:
        Correlation energy.
    """
    func, kwargs = self._load_function(
        "energy",
        eris=eris,
        amplitudes=amplitudes,
    )
    res: float = np.real(ensure_scalar(func(**kwargs)))
    return astype(res, float)

ebcc.cc.base.BaseEBCC.energy_perturbative(eris=None, amplitudes=None, lambdas=None)

Calculate the perturbative correction to the correlation energy.

Parameters:
Returns:
  • float

    Perturbative energy correction.

Source code in ebcc/cc/base.py
def energy_perturbative(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
) -> float:
    """Calculate the perturbative correction to the correlation energy.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.

    Returns:
        Perturbative energy correction.
    """
    func, kwargs = self._load_function(
        "energy_perturbative",
        eris=eris,
        amplitudes=amplitudes,
        lambdas=lambdas,
    )
    res: float = np.real(ensure_scalar(func(**kwargs)))
    return res

ebcc.cc.base.BaseEBCC.update_amps(eris=None, amplitudes=None) abstractmethod

Update the cluster amplitudes.

Parameters:
Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def update_amps(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
) -> Namespace[SpinArrayType]:
    """Update the cluster amplitudes.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.

    Returns:
        Updated cluster amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.update_lams(eris=None, amplitudes=None, lambdas=None, lambdas_pert=None, perturbative=False) abstractmethod

Update the cluster lambda amplitudes.

Parameters:
  • eris (ERIsInputType, default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • lambdas_pert (Optional[Namespace[SpinArrayType]], default: None ) –

    Perturbative cluster lambda amplitudes.

  • perturbative (bool, default: False ) –

    Flag to include perturbative correction.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def update_lams(
    self,
    eris: ERIsInputType = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    lambdas_pert: Optional[Namespace[SpinArrayType]] = None,
    perturbative: bool = False,
) -> Namespace[SpinArrayType]:
    """Update the cluster lambda amplitudes.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        lambdas_pert: Perturbative cluster lambda amplitudes.
        perturbative: Flag to include perturbative correction.

    Returns:
        Updated cluster lambda amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.make_sing_b_dm(eris=None, amplitudes=None, lambdas=None)

Make the single boson density matrix :math:\langle b \rangle.

Parameters:
Returns:
  • NDArray[T]

    Single boson density matrix.

Source code in ebcc/cc/base.py
def make_sing_b_dm(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
) -> NDArray[T]:
    r"""Make the single boson density matrix :math:`\langle b \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.

    Returns:
        Single boson density matrix.
    """
    func, kwargs = self._load_function(
        "make_sing_b_dm",
        eris=eris,
        amplitudes=amplitudes,
        lambdas=lambdas,
    )
    res: NDArray[T] = func(**kwargs)
    return res

ebcc.cc.base.BaseEBCC.make_rdm1_b(eris=None, amplitudes=None, lambdas=None, unshifted=True, hermitise=True)

Make the one-particle boson reduced density matrix :math:\langle b^+ c \rangle.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • unshifted (bool, default: True ) –

    If self.options.shift is True, return the unshifted density matrix. Has no effect if self.options.shift is False.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • NDArray[T]

    One-particle boson reduced density matrix.

Source code in ebcc/cc/base.py
def make_rdm1_b(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    unshifted: bool = True,
    hermitise: bool = True,
) -> NDArray[T]:
    r"""Make the one-particle boson reduced density matrix :math:`\langle b^+ c \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        unshifted: If `self.options.shift` is `True`, return the unshifted density matrix. Has
            no effect if `self.options.shift` is `False`.
        hermitise: Hermitise the density matrix.

    Returns:
        One-particle boson reduced density matrix.
    """
    func, kwargs = self._load_function(
        "make_rdm1_b",
        eris=eris,
        amplitudes=amplitudes,
        lambdas=lambdas,
    )
    dm: NDArray[T] = func(**kwargs)

    if hermitise:
        dm = (dm + np.transpose(dm)) * 0.5

    if unshifted and self.options.shift:
        xi = self.xi
        dm_b = util.einsum("ni->i", self.make_sing_b_dm())
        dm -= util.einsum("ij,i->ij", np.eye(dm.shape[0]), xi * dm_b - xi**2.0)

    return dm

ebcc.cc.base.BaseEBCC.make_rdm1_f(eris=None, amplitudes=None, lambdas=None, hermitise=True) abstractmethod

Make the one-particle fermionic reduced density matrix :math:\langle i^+ j \rangle.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • Any

    One-particle fermion reduced density matrix.

Source code in ebcc/cc/base.py
@abstractmethod
def make_rdm1_f(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    hermitise: bool = True,
) -> Any:
    r"""Make the one-particle fermionic reduced density matrix :math:`\langle i^+ j \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        hermitise: Hermitise the density matrix.

    Returns:
        One-particle fermion reduced density matrix.
    """
    pass

ebcc.cc.base.BaseEBCC.make_rdm2_f(eris=None, amplitudes=None, lambdas=None, hermitise=True) abstractmethod

Make the two-particle fermionic reduced density matrix :math:\langle i^+j^+lk \rangle.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • Any

    Two-particle fermion reduced density matrix.

Source code in ebcc/cc/base.py
@abstractmethod
def make_rdm2_f(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    hermitise: bool = True,
) -> Any:
    r"""Make the two-particle fermionic reduced density matrix :math:`\langle i^+j^+lk \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        hermitise: Hermitise the density matrix.

    Returns:
        Two-particle fermion reduced density matrix.
    """
    pass

ebcc.cc.base.BaseEBCC.make_eb_coup_rdm(eris=None, amplitudes=None, lambdas=None, unshifted=True, hermitise=True) abstractmethod

Make the electron-boson coupling reduced density matrix.

.. math:: \langle b^+ i^+ j \rangle

and

.. math:: \langle b i^+ j \rangle

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • unshifted (bool, default: True ) –

    If self.options.shift is True, return the unshifted density matrix. Has no effect if self.options.shift is False.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • Any

    Electron-boson coupling reduced density matrix.

Source code in ebcc/cc/base.py
@abstractmethod
def make_eb_coup_rdm(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    unshifted: bool = True,
    hermitise: bool = True,
) -> Any:
    r"""Make the electron-boson coupling reduced density matrix.

    .. math::
        \langle b^+ i^+ j \rangle

    and

    .. math::
        \langle b i^+ j \rangle

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        unshifted: If `self.options.shift` is `True`, return the unshifted density matrix. Has
            no effect if `self.options.shift` is `False`.
        hermitise: Hermitise the density matrix.

    Returns:
        Electron-boson coupling reduced density matrix.
    """
    pass

ebcc.cc.base.BaseEBCC.energy_sum(*args, signs_dict=None) abstractmethod

Get a direct sum of energies.

Parameters:
  • *args (str, default: () ) –

    Energies to sum. Subclass should specify a subscript, and optionally spins.

  • signs_dict (Optional[dict[str, str]], default: None ) –

    Signs of the energies in the sum. Default sets ("o", "O", "i") to be positive, and ("v", "V", "a", "b") to be negative.

Returns:
  • NDArray[T]

    Sum of energies.

Source code in ebcc/cc/base.py
@abstractmethod
def energy_sum(self, *args: str, signs_dict: Optional[dict[str, str]] = None) -> NDArray[T]:
    """Get a direct sum of energies.

    Args:
        *args: Energies to sum. Subclass should specify a subscript, and optionally spins.
        signs_dict: Signs of the energies in the sum. Default sets `("o", "O", "i")` to be
            positive, and `("v", "V", "a", "b")` to be negative.

    Returns:
        Sum of energies.
    """
    pass

ebcc.cc.base.BaseEBCC.amplitudes_to_vector(amplitudes) abstractmethod

Construct a vector containing all of the amplitudes used in the given ansatz.

Parameters:
Returns:
  • NDArray[T]

    Cluster amplitudes as a vector.

Source code in ebcc/cc/base.py
@abstractmethod
def amplitudes_to_vector(self, amplitudes: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the amplitudes used in the given ansatz.

    Args:
        amplitudes: Cluster amplitudes.

    Returns:
        Cluster amplitudes as a vector.
    """
    pass

ebcc.cc.base.BaseEBCC.vector_to_amplitudes(vector) abstractmethod

Construct a namespace of amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    Cluster amplitudes as a vector.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def vector_to_amplitudes(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of amplitudes from a vector.

    Args:
        vector: Cluster amplitudes as a vector.

    Returns:
        Cluster amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.lambdas_to_vector(lambdas) abstractmethod

Construct a vector containing all of the lambda amplitudes used in the given ansatz.

Parameters:
Returns:
  • NDArray[T]

    Cluster lambda amplitudes as a vector.

Source code in ebcc/cc/base.py
@abstractmethod
def lambdas_to_vector(self, lambdas: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the lambda amplitudes used in the given ansatz.

    Args:
        lambdas: Cluster lambda amplitudes.

    Returns:
        Cluster lambda amplitudes as a vector.
    """
    pass

ebcc.cc.base.BaseEBCC.vector_to_lambdas(vector) abstractmethod

Construct a namespace of lambda amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    Cluster lambda amplitudes as a vector.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def vector_to_lambdas(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of lambda amplitudes from a vector.

    Args:
        vector: Cluster lambda amplitudes as a vector.

    Returns:
        Cluster lambda amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.init_space() abstractmethod

Initialise the fermionic space.

Returns:
  • SpaceType

    Fermionic space. All fermionic degrees of freedom are assumed to be correlated.

Source code in ebcc/cc/base.py
@abstractmethod
def init_space(self) -> SpaceType:
    """Initialise the fermionic space.

    Returns:
        Fermionic space. All fermionic degrees of freedom are assumed to be correlated.
    """
    pass

ebcc.cc.base.BaseEBCC.get_fock()

Get the Fock matrix.

Returns:
Source code in ebcc/cc/base.py
def get_fock(self) -> BaseFock:
    """Get the Fock matrix.

    Returns:
        Fock matrix.
    """
    return self.Fock(
        self.mf,
        space=(self.space, self.space),
        mo_coeff=(self.mo_coeff, self.mo_coeff),
        g=self.g,
        shift=self.options.shift,
        xi=self.xi if self.boson_ansatz else None,
    )

ebcc.cc.base.BaseEBCC.get_eris(eris=None)

Get the electron repulsion integrals.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Input electron repulsion integrals.

Returns:
  • BaseERIs

    Electron repulsion integrals.

Source code in ebcc/cc/base.py
def get_eris(self, eris: Optional[ERIsInputType] = None) -> BaseERIs:
    """Get the electron repulsion integrals.

    Args:
        eris: Input electron repulsion integrals.

    Returns:
        Electron repulsion integrals.
    """
    use_df = getattr(self.mf, "with_df", None) is not None
    if isinstance(eris, BaseERIs):
        return eris
    elif eris is not None:
        raise TypeError(f"`eris` must be an `BaseERIs` object, got {eris.__class__.__name__}.")
    elif use_df:
        return self.CDERIs(
            self.mf,
            space=(self.space, self.space, self.space, self.space),
            mo_coeff=(self.mo_coeff, self.mo_coeff, self.mo_coeff, self.mo_coeff),
        )
    else:
        return self.ERIs(
            self.mf,
            space=(self.space, self.space, self.space, self.space),
            mo_coeff=(self.mo_coeff, self.mo_coeff, self.mo_coeff, self.mo_coeff),
        )

ebcc.cc.base.BaseEBCC.get_g()

Get the blocks of the electron-boson coupling matrix.

This matrix corresponds to the bosonic annihilation operator.

Returns:
Source code in ebcc/cc/base.py
def get_g(self) -> BaseElectronBoson:
    """Get the blocks of the electron-boson coupling matrix.

    This matrix corresponds to the bosonic annihilation operator.

    Returns:
        Electron-boson coupling matrix.
    """
    if self.bare_g is None:
        raise ValueError("Bare electron-boson coupling matrix not provided.")
    return self.ElectronBoson(
        self.mf,
        self.bare_g,
        (self.space, self.space),
        (self.mo_coeff, self.mo_coeff),
    )

ebcc.cc.base.BaseEBCC.get_mean_field_G() abstractmethod

Get the mean-field boson non-conserving term.

Returns:
  • Any

    Mean-field boson non-conserving term.

Source code in ebcc/cc/base.py
@abstractmethod
def get_mean_field_G(self) -> Any:
    """Get the mean-field boson non-conserving term.

    Returns:
        Mean-field boson non-conserving term.
    """
    pass