Unrestricted equation-of-motion coupled cluster.
ebcc.eom.ueom.UEOM(ebcc, options=None, **kwargs)
Bases: BaseEOM
Unrestricted equation-of-motion coupled cluster.
Initialise the EOM object.
Parameters: |
|
---|
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.ueom.IP_UEOM(ebcc, options=None, **kwargs)
Bases: UEOM
, BaseIP_EOM
Unrestricted ionisation potential equation-of-motion coupled cluster.
Initialise the EOM object.
Parameters: |
|
---|
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.ueom.IP_UEOM.diag(eris=None)
Get the diagonal of the Hamiltonian.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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"
):
spin_part: SpinArrayType = util.Namespace()
for comb in util.generate_spin_combinations(n, excited=True):
spin_part[comb] = self.ebcc.energy_sum(key, comb)
parts[name] = spin_part
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.ueom.IP_UEOM.amplitudes_to_vector(amplitudes)
Construct a vector containing all of the IP-EOM amplitudes.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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"
):
for spin in util.generate_spin_combinations(n, excited=True, unique=True):
vn = amplitudes[name][spin]
subscript, _ = util.combine_subscripts(key, spin)
vectors.append(np.ravel(util.compress_axes(subscript, vn)))
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.ueom.IP_UEOM.vector_to_amplitudes(vector)
Construct a namespace of IP-EOM amplitudes from a vector.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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
sizes: dict[tuple[str, ...], int] = {
(o, s): self.space[i].size(o) for o in "ovOVia" for i, s in enumerate("ab")
}
for name, key, n in self.ansatz.fermionic_cluster_ranks(
spin_type=self.spin_type, which="ip"
):
amp: SpinArrayType = util.Namespace()
for spin in util.generate_spin_combinations(n, excited=True, unique=True):
subscript, csizes = util.combine_subscripts(key, spin, sizes=sizes)
size = util.get_compressed_size(subscript, **csizes)
shape = tuple(self.space["ab".index(s)].size(k) for s, k in zip(spin, key))
vn_tril = vector[i0 : i0 + size]
factor = max(
spin[:n].count(s) for s in set(spin[:n])
) # FIXME why? untested for n > 2
vn = util.decompress_axes(subscript, vn_tril, shape=shape) / factor
amp[spin] = vn
i0 += size
amplitudes[name] = amp
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
assert i0 == len(vector)
return amplitudes
ebcc.eom.ueom.EA_UEOM(ebcc, options=None, **kwargs)
Bases: UEOM
, BaseEA_EOM
Unrestricted electron affinity equation-of-motion coupled cluster.
Initialise the EOM object.
Parameters: |
|
---|
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.ueom.EA_UEOM.diag(eris=None)
Get the diagonal of the Hamiltonian.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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"
):
spin_part: SpinArrayType = util.Namespace()
for comb in util.generate_spin_combinations(n, excited=True):
spin_part[comb] = -self.ebcc.energy_sum(key, comb)
parts[name] = spin_part
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.ueom.EA_UEOM.amplitudes_to_vector(amplitudes)
Construct a vector containing all of the EA-EOM amplitudes.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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"
):
for spin in util.generate_spin_combinations(n, excited=True, unique=True):
vn = amplitudes[name][spin]
subscript, _ = util.combine_subscripts(key, spin)
vectors.append(np.ravel(util.compress_axes(subscript, vn)))
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.ueom.EA_UEOM.vector_to_amplitudes(vector)
Construct a namespace of EA-EOM amplitudes from a vector.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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
sizes: dict[tuple[str, ...], int] = {
(o, s): self.space[i].size(o) for o in "ovOVia" for i, s in enumerate("ab")
}
for name, key, n in self.ansatz.fermionic_cluster_ranks(
spin_type=self.spin_type, which="ea"
):
amp: SpinArrayType = util.Namespace()
for spin in util.generate_spin_combinations(n, excited=True, unique=True):
subscript, csizes = util.combine_subscripts(key, spin, sizes=sizes)
size = util.get_compressed_size(subscript, **csizes)
shape = tuple(self.space["ab".index(s)].size(k) for s, k in zip(spin, key))
vn_tril = vector[i0 : i0 + size]
factor = max(
spin[:n].count(s) for s in set(spin[:n])
) # FIXME why? untested for n > 2
vn = util.decompress_axes(subscript, vn_tril, shape=shape) / factor
amp[spin] = vn
i0 += size
amplitudes[name] = amp
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
assert i0 == len(vector)
return amplitudes
ebcc.eom.ueom.EE_UEOM(ebcc, options=None, **kwargs)
Bases: UEOM
, BaseEE_EOM
Unrestricted electron-electron equation-of-motion coupled cluster.
Initialise the EOM object.
Parameters: |
|
---|
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.ueom.EE_UEOM.diag(eris=None)
Get the diagonal of the Hamiltonian.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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"
):
spin_part: SpinArrayType = util.Namespace()
for comb in util.generate_spin_combinations(n, unique=True):
spin_part[comb] = self.ebcc.energy_sum(key, comb)
parts[name] = spin_part
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.ueom.EE_UEOM.amplitudes_to_vector(amplitudes)
Construct a vector containing all of the EE-EOM amplitudes.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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"
):
for spin in util.generate_spin_combinations(n, unique=True):
vn = amplitudes[name][spin]
subscript, _ = util.combine_subscripts(key, spin)
vectors.append(np.ravel(util.compress_axes(subscript, vn)))
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.ueom.EE_UEOM.vector_to_amplitudes(vector)
Construct a namespace of EE-EOM amplitudes from a vector.
Parameters: |
|
---|
Returns: |
|
---|
Source code in ebcc/eom/ueom.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
sizes: dict[tuple[str, ...], int] = {
(o, s): self.space[i].size(o) for o in "ovOVia" for i, s in enumerate("ab")
}
for name, key, n in self.ansatz.fermionic_cluster_ranks(
spin_type=self.spin_type, which="ee"
):
amp: SpinArrayType = util.Namespace()
for spin in util.generate_spin_combinations(n, unique=True):
subscript, csizes = util.combine_subscripts(key, spin, sizes=sizes)
size = util.get_compressed_size(subscript, **csizes)
shape = tuple(self.space["ab".index(s)].size(k) for s, k in zip(spin, key))
vn_tril = vector[i0 : i0 + size]
factor = max(
spin[:n].count(s) for s in set(spin[:n])
) # FIXME why? untested for n > 2
vn = util.decompress_axes(subscript, vn_tril, shape=shape) / factor
amp[spin] = vn
i0 += size
amplitudes[name] = amp
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
assert i0 == len(vector)
return amplitudes