Generalised equation-of-motion coupled cluster.

ebcc.eom.geom.GEOM(ebcc, options=None, **kwargs)

Bases: BaseEOM

Generalised equation-of-motion coupled cluster.

Initialise the EOM object.

Parameters:
  • ebcc (BaseEBCC) –

    Parent EBCC object.

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

    Options for the EOM calculation.

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

    Additional keyword arguments used to update options.

Source code in ebcc/eom/base.py
def __init__(
    self,
    ebcc: BaseEBCC,
    options: Optional[BaseOptions] = None,
    **kwargs: Any,
) -> None:
    """Initialise the EOM object.

    Args:
        ebcc: Parent `EBCC` object.
        options: Options for the EOM calculation.
        **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.ebcc = ebcc
    self.space = ebcc.space
    self.ansatz = ebcc.ansatz
    self.log = ebcc.log

    # Attributes:
    self.converged = False
    self.e: NDArray[T] = np.zeros((0,), dtype=types[float])
    self.v: NDArray[T] = np.zeros((0, 0), dtype=types[float])

    # Logging:
    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" > nroots:  {ANSI.y}{self.options.nroots}{ANSI.R}")
    self.log.info(f" > e_tol:  {ANSI.y}{self.options.e_tol}{ANSI.R}")
    self.log.info(f" > max_iter:  {ANSI.y}{self.options.max_iter}{ANSI.R}")
    self.log.info(f" > max_space:  {ANSI.y}{self.options.max_space}{ANSI.R}")
    self.log.debug("")

ebcc.eom.geom.IP_GEOM(ebcc, options=None, **kwargs)

Bases: GEOM, BaseIP_EOM

Generalised ionisation potential equation-of-motion coupled cluster.

Initialise the EOM object.

Parameters:
  • ebcc (BaseEBCC) –

    Parent EBCC object.

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

    Options for the EOM calculation.

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

    Additional keyword arguments used to update options.

Source code in ebcc/eom/base.py
def __init__(
    self,
    ebcc: BaseEBCC,
    options: Optional[BaseOptions] = None,
    **kwargs: Any,
) -> None:
    """Initialise the EOM object.

    Args:
        ebcc: Parent `EBCC` object.
        options: Options for the EOM calculation.
        **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.ebcc = ebcc
    self.space = ebcc.space
    self.ansatz = ebcc.ansatz
    self.log = ebcc.log

    # Attributes:
    self.converged = False
    self.e: NDArray[T] = np.zeros((0,), dtype=types[float])
    self.v: NDArray[T] = np.zeros((0, 0), dtype=types[float])

    # Logging:
    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" > nroots:  {ANSI.y}{self.options.nroots}{ANSI.R}")
    self.log.info(f" > e_tol:  {ANSI.y}{self.options.e_tol}{ANSI.R}")
    self.log.info(f" > max_iter:  {ANSI.y}{self.options.max_iter}{ANSI.R}")
    self.log.info(f" > max_space:  {ANSI.y}{self.options.max_space}{ANSI.R}")
    self.log.debug("")

ebcc.eom.geom.IP_GEOM.diag(eris=None)

Get the diagonal of the Hamiltonian.

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

    Electronic repulsion integrals.

Returns:
  • NDArray[T]

    Diagonal of the Hamiltonian.

Source code in ebcc/eom/geom.py
def diag(self, eris: Optional[ERIsInputType] = None) -> NDArray[T]:
    """Get the diagonal of the Hamiltonian.

    Args:
        eris: Electronic repulsion integrals.

    Returns:
        Diagonal of the Hamiltonian.
    """
    parts: Namespace[SpinArrayType] = util.Namespace()

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ip"
    ):
        parts[name] = self.ebcc.energy_sum(key)

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ip"):
        raise util.ModelNotImplemented

    return self.amplitudes_to_vector(parts)

ebcc.eom.geom.IP_GEOM.amplitudes_to_vector(amplitudes)

Construct a vector containing all of the IP-EOM amplitudes.

Parameters:
  • amplitudes (Namespace[SpinArrayType]) –

    IP-EOM amplitudes.

Returns:
  • NDArray[T]

    IP-EOM amplitudes as a vector.

Source code in ebcc/eom/geom.py
def amplitudes_to_vector(self, amplitudes: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the IP-EOM amplitudes.

    Args:
        amplitudes: IP-EOM amplitudes.

    Returns:
        IP-EOM amplitudes as a vector.
    """
    vectors = []

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ip"
    ):
        vectors.append(util.compress_axes(key, amplitudes[name]).ravel())

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ip"):
        raise util.ModelNotImplemented

    for name, key, nf, nb in self.ansatz.coupling_cluster_ranks(
        spin_type=self.spin_type, which="ip"
    ):
        raise util.ModelNotImplemented

    return np.concatenate(vectors)

ebcc.eom.geom.IP_GEOM.vector_to_amplitudes(vector)

Construct a namespace of IP-EOM amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    IP-EOM amplitudes as a vector.

Returns:
  • Namespace[SpinArrayType]

    IP-EOM amplitudes.

Source code in ebcc/eom/geom.py
def vector_to_amplitudes(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of IP-EOM amplitudes from a vector.

    Args:
        vector: IP-EOM amplitudes as a vector.

    Returns:
        IP-EOM amplitudes.
    """
    amplitudes: Namespace[SpinArrayType] = util.Namespace()
    i0 = 0

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ip"
    ):
        size = util.get_compressed_size(key, **{k: self.space.size(k) for k in set(key)})
        shape = tuple(self.space.size(k) for k in key)
        vn_tril = vector[i0 : i0 + size]
        vn = util.decompress_axes(key, vn_tril, shape=shape)
        amplitudes[name] = vn
        i0 += size

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ip"):
        raise util.ModelNotImplemented

    for name, key, nf, nb in self.ansatz.coupling_cluster_ranks(
        spin_type=self.spin_type, which="ip"
    ):
        raise util.ModelNotImplemented

    return amplitudes

ebcc.eom.geom.EA_GEOM(ebcc, options=None, **kwargs)

Bases: GEOM, BaseEA_EOM

Generalised electron affinity equation-of-motion coupled cluster.

Initialise the EOM object.

Parameters:
  • ebcc (BaseEBCC) –

    Parent EBCC object.

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

    Options for the EOM calculation.

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

    Additional keyword arguments used to update options.

Source code in ebcc/eom/base.py
def __init__(
    self,
    ebcc: BaseEBCC,
    options: Optional[BaseOptions] = None,
    **kwargs: Any,
) -> None:
    """Initialise the EOM object.

    Args:
        ebcc: Parent `EBCC` object.
        options: Options for the EOM calculation.
        **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.ebcc = ebcc
    self.space = ebcc.space
    self.ansatz = ebcc.ansatz
    self.log = ebcc.log

    # Attributes:
    self.converged = False
    self.e: NDArray[T] = np.zeros((0,), dtype=types[float])
    self.v: NDArray[T] = np.zeros((0, 0), dtype=types[float])

    # Logging:
    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" > nroots:  {ANSI.y}{self.options.nroots}{ANSI.R}")
    self.log.info(f" > e_tol:  {ANSI.y}{self.options.e_tol}{ANSI.R}")
    self.log.info(f" > max_iter:  {ANSI.y}{self.options.max_iter}{ANSI.R}")
    self.log.info(f" > max_space:  {ANSI.y}{self.options.max_space}{ANSI.R}")
    self.log.debug("")

ebcc.eom.geom.EA_GEOM.diag(eris=None)

Get the diagonal of the Hamiltonian.

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

    Electronic repulsion integrals.

Returns:
  • NDArray[T]

    Diagonal of the Hamiltonian.

Source code in ebcc/eom/geom.py
def diag(self, eris: Optional[ERIsInputType] = None) -> NDArray[T]:
    """Get the diagonal of the Hamiltonian.

    Args:
        eris: Electronic repulsion integrals.

    Returns:
        Diagonal of the Hamiltonian.
    """
    parts: Namespace[SpinArrayType] = util.Namespace()

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ea"
    ):
        parts[name] = -self.ebcc.energy_sum(key)

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ea"):
        raise util.ModelNotImplemented

    return self.amplitudes_to_vector(parts)

ebcc.eom.geom.EA_GEOM.amplitudes_to_vector(amplitudes)

Construct a vector containing all of the EA-EOM amplitudes.

Parameters:
  • amplitudes (Namespace[SpinArrayType]) –

    EA-EOM amplitudes.

Returns:
  • NDArray[T]

    EA-EOM amplitudes as a vector.

Source code in ebcc/eom/geom.py
def amplitudes_to_vector(self, amplitudes: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the EA-EOM amplitudes.

    Args:
        amplitudes: EA-EOM amplitudes.

    Returns:
        EA-EOM amplitudes as a vector.
    """
    vectors = []

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ea"
    ):
        vectors.append(util.compress_axes(key, amplitudes[name]).ravel())

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ea"):
        raise util.ModelNotImplemented

    for name, key, nf, nb in self.ansatz.coupling_cluster_ranks(
        spin_type=self.spin_type, which="ea"
    ):
        raise util.ModelNotImplemented

    return np.concatenate(vectors)

ebcc.eom.geom.EA_GEOM.vector_to_amplitudes(vector)

Construct a namespace of EA-EOM amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    EA-EOM amplitudes as a vector.

Returns:
  • Namespace[SpinArrayType]

    EA-EOM amplitudes.

Source code in ebcc/eom/geom.py
def vector_to_amplitudes(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of EA-EOM amplitudes from a vector.

    Args:
        vector: EA-EOM amplitudes as a vector.

    Returns:
        EA-EOM amplitudes.
    """
    amplitudes: Namespace[SpinArrayType] = util.Namespace()
    i0 = 0

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ea"
    ):
        size = util.get_compressed_size(key, **{k: self.space.size(k) for k in set(key)})
        shape = tuple(self.space.size(k) for k in key)
        vn_tril = vector[i0 : i0 + size]
        vn = util.decompress_axes(key, vn_tril, shape=shape)
        amplitudes[name] = vn
        i0 += size

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ea"):
        raise util.ModelNotImplemented

    for name, key, nf, nb in self.ansatz.coupling_cluster_ranks(
        spin_type=self.spin_type, which="ea"
    ):
        raise util.ModelNotImplemented

    return amplitudes

ebcc.eom.geom.EE_GEOM(ebcc, options=None, **kwargs)

Bases: GEOM, BaseEE_EOM

Generalised electron-electron equation-of-motion coupled cluster.

Initialise the EOM object.

Parameters:
  • ebcc (BaseEBCC) –

    Parent EBCC object.

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

    Options for the EOM calculation.

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

    Additional keyword arguments used to update options.

Source code in ebcc/eom/base.py
def __init__(
    self,
    ebcc: BaseEBCC,
    options: Optional[BaseOptions] = None,
    **kwargs: Any,
) -> None:
    """Initialise the EOM object.

    Args:
        ebcc: Parent `EBCC` object.
        options: Options for the EOM calculation.
        **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.ebcc = ebcc
    self.space = ebcc.space
    self.ansatz = ebcc.ansatz
    self.log = ebcc.log

    # Attributes:
    self.converged = False
    self.e: NDArray[T] = np.zeros((0,), dtype=types[float])
    self.v: NDArray[T] = np.zeros((0, 0), dtype=types[float])

    # Logging:
    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" > nroots:  {ANSI.y}{self.options.nroots}{ANSI.R}")
    self.log.info(f" > e_tol:  {ANSI.y}{self.options.e_tol}{ANSI.R}")
    self.log.info(f" > max_iter:  {ANSI.y}{self.options.max_iter}{ANSI.R}")
    self.log.info(f" > max_space:  {ANSI.y}{self.options.max_space}{ANSI.R}")
    self.log.debug("")

ebcc.eom.geom.EE_GEOM.diag(eris=None)

Get the diagonal of the Hamiltonian.

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

    Electronic repulsion integrals.

Returns:
  • NDArray[T]

    Diagonal of the Hamiltonian.

Source code in ebcc/eom/geom.py
def diag(self, eris: Optional[ERIsInputType] = None) -> NDArray[T]:
    """Get the diagonal of the Hamiltonian.

    Args:
        eris: Electronic repulsion integrals.

    Returns:
        Diagonal of the Hamiltonian.
    """
    parts: Namespace[SpinArrayType] = util.Namespace()

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ee"
    ):
        parts[name] = -self.ebcc.energy_sum(key)

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ee"):
        raise util.ModelNotImplemented

    return self.amplitudes_to_vector(parts)

ebcc.eom.geom.EE_GEOM.amplitudes_to_vector(amplitudes)

Construct a vector containing all of the EE-EOM amplitudes.

Parameters:
  • amplitudes (Namespace[SpinArrayType]) –

    EE-EOM amplitudes.

Returns:
  • NDArray[T]

    EE-EOM amplitudes as a vector.

Source code in ebcc/eom/geom.py
def amplitudes_to_vector(self, amplitudes: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the EE-EOM amplitudes.

    Args:
        amplitudes: EE-EOM amplitudes.

    Returns:
        EE-EOM amplitudes as a vector.
    """
    vectors = []

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ee"
    ):
        vectors.append(util.compress_axes(key, amplitudes[name]).ravel())

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ee"):
        raise util.ModelNotImplemented

    for name, key, nf, nb in self.ansatz.coupling_cluster_ranks(
        spin_type=self.spin_type, which="ee"
    ):
        raise util.ModelNotImplemented

    return np.concatenate(vectors)

ebcc.eom.geom.EE_GEOM.vector_to_amplitudes(vector)

Construct a namespace of EE-EOM amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    EE-EOM amplitudes as a vector.

Returns:
  • Namespace[SpinArrayType]

    EE-EOM amplitudes.

Source code in ebcc/eom/geom.py
def vector_to_amplitudes(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of EE-EOM amplitudes from a vector.

    Args:
        vector: EE-EOM amplitudes as a vector.

    Returns:
        EE-EOM amplitudes.
    """
    amplitudes: Namespace[SpinArrayType] = util.Namespace()
    i0 = 0

    for name, key, n in self.ansatz.fermionic_cluster_ranks(
        spin_type=self.spin_type, which="ee"
    ):
        size = util.get_compressed_size(key, **{k: self.space.size(k) for k in set(key)})
        shape = tuple(self.space.size(k) for k in key)
        vn_tril = vector[i0 : i0 + size]
        vn = util.decompress_axes(key, vn_tril, shape=shape)
        amplitudes[name] = vn
        i0 += size

    for name, key, n in self.ansatz.bosonic_cluster_ranks(spin_type=self.spin_type, which="ee"):
        raise util.ModelNotImplemented

    for name, key, nf, nb in self.ansatz.coupling_cluster_ranks(
        spin_type=self.spin_type, which="ee"
    ):
        raise util.ModelNotImplemented

    return amplitudes