Commit 180855fe authored by Joseph Weston's avatar Joseph Weston
Browse files

set tolerance for zero eigenvalues proportional to norm of selfenergy

The broadening matrix (gamma) itself has norm ~0 when there are no
open modes, meaning that the tolerance we are checking against is
always too small in this case. Instead we check against the norm
of the selfenergy, which is nonzero even when there are no open modes.
parent 456ead15
...@@ -991,15 +991,18 @@ class GreensFunction(BlockResult): ...@@ -991,15 +991,18 @@ class GreensFunction(BlockResult):
# For reflection we have to be more careful # For reflection we have to be more careful
gamma = 1j * (self.lead_info[lead_in] - gamma = 1j * (self.lead_info[lead_in] -
self.lead_info[lead_in].conj().T) self.lead_info[lead_in].conj().T)
sigma = self.lead_info[lead_in]
gf = self.submatrix(lead_out, lead_in) gf = self.submatrix(lead_out, lead_in)
# The number of channels is given by the number of # The number of channels is given by the number of
# nonzero eigenvalues of Gamma # nonzero eigenvalues of Gamma
# rationale behind the threshold from # rationale behind the threshold from
# Golub; van Loan, chapter 5.5.8 # Golub; van Loan, chapter 5.5.8
# We use ‖Σ‖, not ‖Γ‖, for the tolerance as ‖Γ‖~0 when there
# are no open modes.
eps = np.finfo(gamma.dtype).eps * 1000 eps = np.finfo(gamma.dtype).eps * 1000
N = np.sum(np.linalg.eigvalsh(gamma) > N = np.sum(np.linalg.eigvalsh(gamma) >
eps * np.linalg.norm(gamma, np.inf)) eps * np.linalg.norm(sigma, np.inf))
result += 2 * np.trace(np.dot(gamma, gf)).imag + N result += 2 * np.trace(np.dot(gamma, gf)).imag + N
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment