Iteration 0001 — b93246c4bf06 (accepted)¶
GitHub commit: b93246c4bf06 Published branch: fermilink-optimize/pyscf-davidson
Change summary¶
Use root-specific Ritz values for LR Davidson residual preconditioning, including vectorized shifts in the shared TD preconditioner
Acceptance rationale¶
22.7% primary-metric improvement with all correctness guardrails passing and no hard-reject condition.
Guardrails & metrics¶
field |
value |
|---|---|
decision |
ACCEPTED |
correctness |
ok |
correctness mode |
field_tolerances |
hard reject |
no |
guardrail errors |
0 |
incumbent commit |
|
candidate commit |
|
incumbent metric |
128.753 |
candidate metric |
99.5699 |
baseline metric |
128.753 |
Δ vs incumbent |
+22.666% (lower-is-better sign) |
changed files |
pyscf/tdscf/_lr_eig.py, pyscf/tdscf/rhf.py |
Diffstat¶
pyscf/tdscf/_lr_eig.py | 4 ++--
pyscf/tdscf/rhf.py | 10 ++++++++--
2 files changed, 10 insertions(+), 4 deletions(-)
Diff¶
diff --git a/pyscf/tdscf/_lr_eig.py b/pyscf/tdscf/_lr_eig.py
index 1dc58e649..2acd5e230 100644
--- a/pyscf/tdscf/_lr_eig.py
+++ b/pyscf/tdscf/_lr_eig.py
@@ -198,7 +198,7 @@ def eigh(aop, x0, precond, tol_residual=1e-5, lindep=1e-12, nroots=1,
# remove subspace linear dependency
for k, xk in enumerate(xt):
if dx_norm[k] > tol_residual:
- xt[k] = precond(xk, e[0])
+ xt[k] = precond(xk, w[k])
xt -= xs.conj().dot(xt.T).T.dot(xs)
xt_norm = np.linalg.norm(xt, axis=1)
@@ -426,7 +426,7 @@ def eig(aop, x0, precond, tol_residual=1e-5, nroots=1, x0sym=None, pick=None,
# remove subspace linear dependency
for k, xk in enumerate(xt):
if dx_norm[k] > tol_residual:
- xt[k] = precond(xk, e[0])
+ xt[k] = precond(xk, w[k])
xt -= xs.conj().dot(xt.T).T.dot(xs)
c = _conj_dot(xs, xt)
diff --git a/pyscf/tdscf/rhf.py b/pyscf/tdscf/rhf.py
index 90b6260dc..2d33dba79 100644
--- a/pyscf/tdscf/rhf.py
+++ b/pyscf/tdscf/rhf.py
@@ -875,8 +875,14 @@ class TDBase(lib.StreamObject):
def get_precond(self, hdiag):
def precond(x, e, *args):
if isinstance(e, numpy.ndarray):
- e = e[0]
- diagd = hdiag - (e-self.level_shift)
+ e = numpy.asarray(e)
+ if e.ndim == 0 or numpy.ndim(x) == 1:
+ e = e.ravel()[0]
+ diagd = hdiag - (e-self.level_shift)
+ else:
+ diagd = hdiag - (e[:,None]-self.level_shift)
+ else:
+ diagd = hdiag - (e-self.level_shift)
diagd[abs(diagd)<1e-8] = 1e-8
return x/diagd
return precond