From ce7d9db309d0f72bd258660f5a531e7c30078a79 Mon Sep 17 00:00:00 2001 From: Oliver Backhouse Date: Thu, 30 Oct 2025 22:39:46 +0000 Subject: [PATCH 1/5] Fix combination of dyson approximations --- dyson/representations/spectral.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dyson/representations/spectral.py b/dyson/representations/spectral.py index a02c2bb..815cba7 100644 --- a/dyson/representations/spectral.py +++ b/dyson/representations/spectral.py @@ -257,11 +257,16 @@ def combine(self, *args: Spectral, chempot: float | None = None) -> Spectral: ) nphys = args[0].nphys - # Sum the overlap and static self-energy matrices -- double counting is not an issue - # with shared static parts because the overlap matrix accounts for the separation + # Sum the overlap and static self-energy matrices static = sum([arg.get_static_self_energy() for arg in args], np.zeros((nphys, nphys))) overlap = sum([arg.get_overlap() for arg in args], np.zeros((nphys, nphys))) + # Orthogonalise under the metric of the overlap matrix + hermitian = all(arg.hermitian for arg in args) + orth, _ = util.matrix_power(overlap, -0.5, hermitian=hermitian, return_error=False) + static = orth @ static @ orth + overlap = orth @ overlap @ orth + # Check the chemical potentials if chempot is None: if any(arg.chempot is not None for arg in args): From b5a6ad9f4bf31da57716b32dc308710e319d4ae5 Mon Sep 17 00:00:00 2001 From: Basil Ibrahim Date: Tue, 25 Nov 2025 16:20:20 +0000 Subject: [PATCH 2/5] Allow specification of overlap and static self-energy when combining spectral representations --- dyson/representations/spectral.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dyson/representations/spectral.py b/dyson/representations/spectral.py index a02c2bb..6df72a1 100644 --- a/dyson/representations/spectral.py +++ b/dyson/representations/spectral.py @@ -238,8 +238,8 @@ def get_greens_function(self, chempot: float | None = None) -> Lehmann: chempot = 0.0 return Lehmann(*self.get_dyson_orbitals(), chempot=chempot) - def combine(self, *args: Spectral, chempot: float | None = None) -> Spectral: - """Combine multiple spectral representations. + def combine(self, *args: Spectral, chempot: float | None = None, static: Array | None = None, overlap: Array | None = None) -> Spectral: + """Combine multiple spectral representations by concatenating self-energies. Args: args: Spectral representations to combine. @@ -259,8 +259,8 @@ def combine(self, *args: Spectral, chempot: float | None = None) -> Spectral: # Sum the overlap and static self-energy matrices -- double counting is not an issue # with shared static parts because the overlap matrix accounts for the separation - static = sum([arg.get_static_self_energy() for arg in args], np.zeros((nphys, nphys))) - overlap = sum([arg.get_overlap() for arg in args], np.zeros((nphys, nphys))) + static = static if static is not None else sum([arg.get_static_self_energy() for arg in args], np.zeros((nphys, nphys))) + overlap = overlap if overlap is not None else sum([arg.get_overlap() for arg in args], np.zeros((nphys, nphys))) # Check the chemical potentials if chempot is None: @@ -344,4 +344,4 @@ def __eq__(self, other: object) -> bool: def __hash__(self) -> int: """Hash the object.""" - return hash((tuple(self.eigvals), tuple(self.eigvecs.flatten()), self.nphys, self.chempot)) + return hash((tuple(self.eigvals), tuple(self.eigvecs.flatten()), self.nphys, self.chempot)) \ No newline at end of file From e4d7b39b786925171dbc17b1f1004394e086b049 Mon Sep 17 00:00:00 2001 From: Basil Ibrahim Date: Tue, 25 Nov 2025 16:22:21 +0000 Subject: [PATCH 3/5] Add python 3.13 3.14 --- .github/workflows/ci.yaml | 5 +++-- pyproject.toml | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7651699..f3bb010 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,10 +14,11 @@ jobs: fail-fast: false matrix: include: - - {python-version: "3.10", os: ubuntu-latest} - {python-version: "3.11", os: ubuntu-latest} - {python-version: "3.12", os: ubuntu-latest} - - {python-version: "3.12", os: macos-latest} + - {python-version: "3.13", os: ubuntu-latest} + - {python-version: "3.14", os: ubuntu-latest} + - {python-version: "3.14", os: macos-latest} steps: - uses: actions/checkout@v2 diff --git a/pyproject.toml b/pyproject.toml index d5b864e..1b145e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,10 +19,10 @@ classifiers = [ "Topic :: Scientific/Engineering", "Topic :: Software Development", "Programming Language :: Python", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX :: Linux", ] From 4799855b0206b31567f24dc522de9380a7fd4f4c Mon Sep 17 00:00:00 2001 From: Basil Ibrahim Date: Tue, 25 Nov 2025 16:25:25 +0000 Subject: [PATCH 4/5] Formatting --- dyson/representations/spectral.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/dyson/representations/spectral.py b/dyson/representations/spectral.py index 6df72a1..560347c 100644 --- a/dyson/representations/spectral.py +++ b/dyson/representations/spectral.py @@ -238,13 +238,23 @@ def get_greens_function(self, chempot: float | None = None) -> Lehmann: chempot = 0.0 return Lehmann(*self.get_dyson_orbitals(), chempot=chempot) - def combine(self, *args: Spectral, chempot: float | None = None, static: Array | None = None, overlap: Array | None = None) -> Spectral: + def combine( + self, + *args: Spectral, + chempot: float | None = None, + overlap: Array | None = None, + static: Array | None = None, + ) -> Spectral: """Combine multiple spectral representations by concatenating self-energies. Args: args: Spectral representations to combine. chempot: Chemical potential to be used in the Lehmann representations of the self-energy and Green's function. + overlap: Overlap matrix for the physical space. If ``None``, the overlap matrices of the + inputs are summed. + static: Static part of the self-energy. If ``None``, the static parts of the inputs are + summed. Returns: Combined spectral representation. @@ -259,8 +269,11 @@ def combine(self, *args: Spectral, chempot: float | None = None, static: Array | # Sum the overlap and static self-energy matrices -- double counting is not an issue # with shared static parts because the overlap matrix accounts for the separation - static = static if static is not None else sum([arg.get_static_self_energy() for arg in args], np.zeros((nphys, nphys))) - overlap = overlap if overlap is not None else sum([arg.get_overlap() for arg in args], np.zeros((nphys, nphys))) + if overlap is None: + overlap = sum(arg.get_overlap() for arg in args) + + if static is None: + static = sum(arg.get_static_self_energy() for arg in args) # Check the chemical potentials if chempot is None: @@ -344,4 +357,4 @@ def __eq__(self, other: object) -> bool: def __hash__(self) -> int: """Hash the object.""" - return hash((tuple(self.eigvals), tuple(self.eigvecs.flatten()), self.nphys, self.chempot)) \ No newline at end of file + return hash((tuple(self.eigvals), tuple(self.eigvecs.flatten()), self.nphys, self.chempot)) From 76caa9ab77eb67804e6ff12c233ea6a41d659e03 Mon Sep 17 00:00:00 2001 From: Basil Ibrahim Date: Tue, 25 Nov 2025 16:33:11 +0000 Subject: [PATCH 5/5] New line --- dyson/representations/spectral.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dyson/representations/spectral.py b/dyson/representations/spectral.py index 0cf849e..3f069ba 100644 --- a/dyson/representations/spectral.py +++ b/dyson/representations/spectral.py @@ -280,7 +280,7 @@ def combine( orth, _ = util.matrix_power(overlap, -0.5, hermitian=hermitian, return_error=False) static = orth @ static @ orth overlap = orth @ overlap @ orth - + # Check the chemical potentials if chempot is None: if any(arg.chempot is not None for arg in args):