triqs.gfs.dlr_crm_dyson_solver.minimize_dyson

triqs.gfs.dlr_crm_dyson_solver.minimize_dyson(G0_dlr, G_dlr, Sigma_moments, method='trust-constr', options={'disp': True, 'finite_diff_rel_step': 1e-20, 'gtol': 1e-32, 'maxiter': 5000, 'xtol': 1e-100}, **kwargs)[source]

Solve Dyson’s equation in the DLR basis by constrained residual minimization.

Defines Dyson’s equation as an optimization problem,

\[G - G_0 - G_0\,\Sigma\,G = 0,\]

and solves it on the DLR (discrete Lehmann representation) nodes via scipy.optimize.minimize(). The solver optimizes only the dynamic part of the self-energy \(\Sigma_{\mathrm{dyn}}(i\nu) = \Sigma(i\nu) - \Sigma_0\), where \(\Sigma_0\) is the Hartree shift. When the second moment \(\Sigma_1\) is supplied, it is enforced as a non-linear constraint on the optimizer.

When G_dlr / G0_dlr are BlockGf, the solve is dispatched block by block.

Parameters:
G0_dlrGf or BlockGf

Non-interacting Green’s function defined on a MeshDLR, MeshDLRImTime or MeshDLRImFreq mesh.

G_dlrGf or BlockGf

Interacting Green’s function on the same mesh family as G0_dlr.

Sigma_momentslist of numpy.ndarray, or dict of list of numpy.ndarray

High-frequency moments of \(\Sigma\). Sigma_moments[0] is the Hartree shift \(\Sigma_0\) (the constant part of \(\Sigma\)). When supplied, Sigma_moments[1] is used as a non-linear constraint on the optimizer. For a BlockGf input, a dict keyed by block name is expected.

methodstr, optional

Optimization method forwarded to scipy.optimize.minimize(). Default 'trust-constr' — one of the few methods that supports non-linear constraints.

optionsdict, optional

Options forwarded to scipy.optimize.minimize(). Default dict(maxiter=5000, disp=True, gtol=1e-32, xtol=1e-100, finite_diff_rel_step=1e-20).

Returns:
Sigma_DLRGf or BlockGf

Optimized self-energy defined on a MeshDLRImFreq mesh.

Sigma_0numpy.ndarray or dict of numpy.ndarray

Hartree shift (per block when the input is a BlockGf).

residualfloat or dict of float

\(L_2\) norm of the Dyson residual \(G - G_0 - G_0\,\Sigma\,G\) (per block when the input is a BlockGf).

Notes

The method is described in https://arxiv.org/abs/2310.01266. The moments can be computed directly in the impurity solver (see the cthyb high frequency moments tutorial) or approximated by fitting the tail of the self-energy obtained from the usual Dyson equation.

Examples

Approximate the moments from a tail fit and pass them to the solver:

>>> S_iw = inverse(G0_iw) - inverse(G_iw)
>>> tail, err = S_iw.fit_hermitian_tail()
>>> S_iw_dlr, Sigma_HF, residual = minimize_dyson(
...     G0_dlr=G0_dlr, G_dlr=G_dlr, Sigma_moments=tail[0:1])

The input G_dlr can be obtained via fit_gf_dlr from a noisy imaginary-time Green’s function, or by directly sampling the DLR mesh points from a full MeshImFreq G_iw object:

>>> for iwn in G_dlr_iw.mesh:
...     G_dlr_iw[iwn] = G_full_iw(iwn)