10. Maxent for matrix-valued Green’s functions

In this notebook we benchmark the “poorman” method for MaxEnt continuation of matrix-valued Green’s functions. To this end we consider a Green’s function that is a 2x2 matrix. First we define a diagonal matrix for the spectral function, then we rotate it to get also off-diagonal elements, and transform it to the imaginary axis. Then we do an analytical continuation for this matrix-valued Green’s function. In the very end we compare the determinants of the spectral matrices.

[1]:
import sys
import numpy as np
import matplotlib.pyplot as plt
#%matplotlib inline

sys.path.insert(0, '/home/josef/Programs/ana_cont')
from ana_cont import continuation as cont
[2]:
true_w = np.linspace(-5.,5.,num=5001, endpoint=True)
beta = 40.
niw = 20
wn = np.pi/beta * (2.*np.arange(niw) + 1.)
def gauss_peak(center, width):
    return np.exp(-(true_w-center)**2/(2.*width**2)) / (width*np.sqrt(2.*np.pi))
true_spec_1 = 0.5*(gauss_peak(1., 0.2) + gauss_peak(2.,0.7))
true_spec_2 = 0.5*(gauss_peak(-1., 0.25) + gauss_peak(-2.1, 0.6))

spec_matrix = np.zeros((2,2,true_w.shape[0]))
spec_matrix[0,0] = true_spec_1
spec_matrix[1,1] = true_spec_2

rot_ang = 0.1
rot_mat = np.array([[np.cos(rot_ang), np.sin(rot_ang)],[-np.sin(rot_ang), np.cos(rot_ang)]])

true_spec_rot = np.einsum('ij,jkw,kl', rot_mat, spec_matrix, rot_mat.transpose())

plt.plot(true_w, true_spec_1, color='black')
plt.plot(true_w, true_spec_2, color='black')
plt.plot(true_w, true_spec_rot[0,0], label='diag1', ls='--')
plt.plot(true_w, true_spec_rot[1,1], label='diag2', ls='--')
plt.plot(true_w, true_spec_rot[0,1], label='offd1', ls='--')
plt.plot(true_w, true_spec_rot[1,0], label='offd2', ls='--')
plt.legend()
plt.show()


kernel = 1./(1j*wn[:,None] - true_w[None,:])
giw = np.trapz(kernel[None,None,:,:]*true_spec_rot[:,:,None,:], true_w, axis=3)
plt.plot(wn, giw[1,1].real, ls='--')
plt.plot(wn, giw[1,1].imag)
plt.show()
_images/poorman_test_2_0.png
_images/poorman_test_2_1.png
[3]:
wgrid = np.linspace(-4, 4, num=400)
#model = np.ones_like(wgrid)
#model = np.exp(-(wgrid-0.9)**2) * (wgrid-0.9)**2
model_diag = np.exp(-0.5*wgrid**2)
model_diag /= np.trapz(model_diag, wgrid)
errfac = 0.00001
err = errfac * np.ones_like(wn)
#perfect_model = np.abs(np.interp(wgrid, true_w, true_spec))
[4]:
probl_00 = cont.AnalyticContinuationProblem(im_axis=wn, re_axis=wgrid,
                                            im_data=giw[0,0], kernel_mode='freq_fermionic')
probl_11 = cont.AnalyticContinuationProblem(im_axis=wn, re_axis=wgrid,
                                            im_data=giw[1,1], kernel_mode='freq_fermionic')
probl_01 = cont.AnalyticContinuationProblem(im_axis=wn, re_axis=wgrid,
                                            im_data=giw[0,1], kernel_mode='freq_fermionic')
[5]:
sol_00,sol_all_00 = probl_00.solve(method='maxent_svd', alpha_determination='chi2kink',
                                   optimizer='newton', stdev=err, model=model_diag,
                                   alpha_start=1e18, alpha_end=1e-10, fit_position=2.,
                                   offdiag=False, interactive=True)
sol_11,sol_all_11 = probl_11.solve(method='maxent_svd', alpha_determination='chi2kink',
                                   optimizer='newton', stdev=err, model=model_diag,
                                   alpha_start=1e18, alpha_end=1e-10, fit_position=2.,
                                   offdiag=False, interactive=True)
400 data points on real axis
40 data points on imaginary axis
31 significant singular values
Precomputation of coefficient matrices...
log10(alpha) = 18.00,   chi2 = 6.684e+10,   S = -3.486e-15,   nfev = 1,   norm = 1.000
log10(alpha) = 17.00,   chi2 = 6.684e+10,   S = -3.484e-13,   nfev = 1,   norm = 1.000
log10(alpha) = 16.00,   chi2 = 6.684e+10,   S = -3.484e-11,   nfev = 1,   norm = 1.000
log10(alpha) = 15.00,   chi2 = 6.683e+10,   S = -3.483e-09,   nfev = 3,   norm = 1.000
log10(alpha) = 14.00,   chi2 = 6.670e+10,   S = -3.471e-07,   nfev = 10,   norm = 1.000
log10(alpha) = 13.00,   chi2 = 6.548e+10,   S = -3.364e-05,   nfev = 13,   norm = 0.995
log10(alpha) = 12.00,   chi2 = 5.578e+10,   S = -2.554e-03,   nfev = 16,   norm = 0.962
log10(alpha) = 11.00,   chi2 = 2.542e+10,   S = -6.564e-02,   nfev = 24,   norm = 0.846
log10(alpha) = 10.00,   chi2 = 4.428e+09,   S = -3.971e-01,   nfev = 26,   norm = 0.820
log10(alpha) = 9.00,    chi2 = 2.413e+08,   S = -9.238e-01,   nfev = 41,   norm = 0.923
log10(alpha) = 8.00,    chi2 = 5.062e+06,   S = -1.164e+00,   nfev = 52,   norm = 0.970
log10(alpha) = 7.00,    chi2 = 3.906e+05,   S = -1.212e+00,   nfev = 32,   norm = 0.980
log10(alpha) = 6.00,    chi2 = 5.671e+04,   S = -1.261e+00,   nfev = 27,   norm = 0.989
log10(alpha) = 5.00,    chi2 = 3.039e+03,   S = -1.326e+00,   nfev = 35,   norm = 0.996
log10(alpha) = 4.00,    chi2 = 1.029e+02,   S = -1.357e+00,   nfev = 37,   norm = 0.999
log10(alpha) = 3.00,    chi2 = 5.118e+00,   S = -1.369e+00,   nfev = 25,   norm = 1.000
log10(alpha) = 2.00,    chi2 = 2.034e-01,   S = -1.374e+00,   nfev = 22,   norm = 1.000
log10(alpha) = 1.00,    chi2 = 1.316e-02,   S = -1.376e+00,   nfev = 20,   norm = 1.000
log10(alpha) = 0.00,    chi2 = 1.313e-03,   S = -1.378e+00,   nfev = 59,   norm = 1.000
log10(alpha) = -1.00,   chi2 = 1.248e-04,   S = -1.379e+00,   nfev = 19,   norm = 1.000
log10(alpha) = -2.00,   chi2 = 4.717e-06,   S = -1.380e+00,   nfev = 16,   norm = 1.000
log10(alpha) = -3.00,   chi2 = 1.491e-07,   S = -1.381e+00,   nfev = 29,   norm = 1.000
log10(alpha) = -4.00,   chi2 = 3.705e-09,   S = -1.381e+00,   nfev = 49,   norm = 1.000
log10(alpha) = -5.00,   chi2 = 2.046e-09,   S = -1.381e+00,   nfev = 14,   norm = 1.000
log10(alpha) = -6.00,   chi2 = 2.120e-09,   S = -1.381e+00,   nfev = 4,   norm = 1.000
log10(alpha) = -7.00,   chi2 = 1.969e-09,   S = -1.381e+00,   nfev = 1,   norm = 1.000
log10(alpha) = -8.00,   chi2 = 1.929e-09,   S = -1.381e+00,   nfev = 1,   norm = 1.000
log10(alpha) = -9.00,   chi2 = 1.929e-09,   S = -1.381e+00,   nfev = 1,   norm = 1.000
log10(alpha) = -10.00,  chi2 = 1.929e-09,   S = -1.381e+00,   nfev = 1,   norm = 1.000
Fit parameters [-9.77015836 21.41371487  3.12901759  0.28476624]
Optimal log alpha -3.8942867665688183
log10(alpha) = -3.89,   chi2 = 4.106e-09,   S = -1.381e+00,   nfev = 39,   norm = 1.000
_images/poorman_test_5_1.png
400 data points on real axis
40 data points on imaginary axis
31 significant singular values
Precomputation of coefficient matrices...
log10(alpha) = 18.00,   chi2 = 6.693e+10,   S = -3.517e-15,   nfev = 1,   norm = 1.000
log10(alpha) = 17.00,   chi2 = 6.693e+10,   S = -3.522e-13,   nfev = 1,   norm = 1.000
log10(alpha) = 16.00,   chi2 = 6.693e+10,   S = -3.522e-11,   nfev = 1,   norm = 1.000
log10(alpha) = 15.00,   chi2 = 6.692e+10,   S = -3.521e-09,   nfev = 3,   norm = 1.000
log10(alpha) = 14.00,   chi2 = 6.679e+10,   S = -3.510e-07,   nfev = 10,   norm = 1.000
log10(alpha) = 13.00,   chi2 = 6.556e+10,   S = -3.400e-05,   nfev = 13,   norm = 0.995
log10(alpha) = 12.00,   chi2 = 5.577e+10,   S = -2.577e-03,   nfev = 16,   norm = 0.961
log10(alpha) = 11.00,   chi2 = 2.534e+10,   S = -6.570e-02,   nfev = 25,   norm = 0.840
log10(alpha) = 10.00,   chi2 = 4.478e+09,   S = -3.949e-01,   nfev = 25,   norm = 0.807
log10(alpha) = 9.00,    chi2 = 2.575e+08,   S = -9.298e-01,   nfev = 50,   norm = 0.909
log10(alpha) = 8.00,    chi2 = 6.270e+06,   S = -1.188e+00,   nfev = 26,   norm = 0.963
log10(alpha) = 7.00,    chi2 = 4.438e+05,   S = -1.251e+00,   nfev = 34,   norm = 0.980
log10(alpha) = 6.00,    chi2 = 4.015e+04,   S = -1.304e+00,   nfev = 39,   norm = 0.991
log10(alpha) = 5.00,    chi2 = 1.821e+03,   S = -1.349e+00,   nfev = 32,   norm = 0.997
log10(alpha) = 4.00,    chi2 = 6.876e+01,   S = -1.368e+00,   nfev = 36,   norm = 1.000
log10(alpha) = 3.00,    chi2 = 4.825e+00,   S = -1.376e+00,   nfev = 40,   norm = 1.000
log10(alpha) = 2.00,    chi2 = 2.401e-01,   S = -1.381e+00,   nfev = 18,   norm = 1.000
log10(alpha) = 1.00,    chi2 = 1.113e-02,   S = -1.383e+00,   nfev = 28,   norm = 1.000
log10(alpha) = 0.00,    chi2 = 5.290e-04,   S = -1.385e+00,   nfev = 41,   norm = 1.000
log10(alpha) = -1.00,   chi2 = 4.537e-05,   S = -1.385e+00,   nfev = 27,   norm = 1.000
log10(alpha) = -2.00,   chi2 = 2.646e-06,   S = -1.386e+00,   nfev = 27,   norm = 1.000
log10(alpha) = -3.00,   chi2 = 1.122e-07,   S = -1.386e+00,   nfev = 48,   norm = 1.000
log10(alpha) = -4.00,   chi2 = 3.433e-09,   S = -1.386e+00,   nfev = 33,   norm = 1.000
log10(alpha) = -5.00,   chi2 = 1.920e-09,   S = -1.387e+00,   nfev = 10,   norm = 1.000
log10(alpha) = -6.00,   chi2 = 2.211e-09,   S = -1.387e+00,   nfev = 24,   norm = 1.000
log10(alpha) = -7.00,   chi2 = 2.207e-09,   S = -1.387e+00,   nfev = 3,   norm = 1.000
log10(alpha) = -8.00,   chi2 = 2.198e-09,   S = -1.387e+00,   nfev = 1,   norm = 1.000
log10(alpha) = -9.00,   chi2 = 2.198e-09,   S = -1.387e+00,   nfev = 1,   norm = 1.000
log10(alpha) = -10.00,  chi2 = 2.198e-09,   S = -1.387e+00,   nfev = 1,   norm = 1.000
Fit parameters [-9.62078515 21.21741168  3.26551673  0.29376997]
Optimal log alpha -3.542531165072654
log10(alpha) = -3.54,   chi2 = 2.176e-08,   S = -1.386e+00,   nfev = 57,   norm = 1.000
_images/poorman_test_5_3.png
[6]:
model_offd = np.sqrt(sol_00.A_opt * sol_11.A_opt)
plt.plot(true_w, true_spec_rot[0,0], color='blue', ls='--', label='true 1')
plt.plot(true_w, true_spec_rot[1,1], color='red', ls='--', label='true 2')
plt.plot(wgrid, sol_00.A_opt, color='blue', label='maxent 1')
plt.plot(wgrid, sol_11.A_opt, color='red', label='maxent 2')
plt.plot(wgrid, model_offd, color='green', label='default model for offdiag')
plt.legend()
plt.show()

plt.plot(true_w, true_spec_rot[0,0], color='blue', ls='--')
plt.plot(true_w, true_spec_rot[1,1], color='red', ls='--')
plt.plot(wgrid, sol_00.A_opt, color='blue')
plt.plot(wgrid, sol_11.A_opt, color='red')
plt.plot(wgrid, model_offd, color='green')
plt.xlim(-1,1)
plt.show()
_images/poorman_test_6_0.png
_images/poorman_test_6_1.png
[7]:
sol_01, sol_all_01 = probl_01.solve(method='maxent_svd', alpha_determination='chi2kink', optimizer='newton',
                                    stdev=err, model=model_offd, offdiag=True,
                                    preblur=False, blur_width=0.05, # preblur not necessary
                                    alpha_start=1e15, alpha_end=1e-15,
                                    interactive=True)
400 data points on real axis
40 data points on imaginary axis
31 significant singular values
Precomputation of coefficient matrices...
log10(alpha) = 15.00,   chi2 = 1.400e+09,   S = -1.084e-11,   nfev = 1,   norm = -0.000
log10(alpha) = 14.00,   chi2 = 1.400e+09,   S = -1.083e-09,   nfev = 7,   norm = -0.000
log10(alpha) = 13.00,   chi2 = 1.396e+09,   S = -1.080e-07,   nfev = 11,   norm = -0.000
log10(alpha) = 12.00,   chi2 = 1.358e+09,   S = -1.051e-05,   nfev = 14,   norm = -0.000
log10(alpha) = 11.00,   chi2 = 1.050e+09,   S = -8.125e-04,   nfev = 17,   norm = -0.000
log10(alpha) = 10.00,   chi2 = 2.152e+08,   S = -1.669e-02,   nfev = 27,   norm = -0.001
log10(alpha) = 9.00,    chi2 = 6.829e+06,   S = -3.987e-02,   nfev = 31,   norm = -0.001
log10(alpha) = 8.00,    chi2 = 1.440e+05,   S = -4.670e-02,   nfev = 28,   norm = 0.000
log10(alpha) = 7.00,    chi2 = 2.595e+03,   S = -4.806e-02,   nfev = 24,   norm = 0.000
log10(alpha) = 6.00,    chi2 = 7.595e+01,   S = -4.832e-02,   nfev = 18,   norm = -0.000
log10(alpha) = 5.00,    chi2 = 1.753e+00,   S = -4.840e-02,   nfev = 18,   norm = 0.000
log10(alpha) = 4.00,    chi2 = 3.800e-02,   S = -4.841e-02,   nfev = 14,   norm = 0.000
log10(alpha) = 3.00,    chi2 = 2.703e-03,   S = -4.842e-02,   nfev = 14,   norm = -0.000
log10(alpha) = 2.00,    chi2 = 2.762e-04,   S = -4.842e-02,   nfev = 13,   norm = -0.000
log10(alpha) = 1.00,    chi2 = 9.035e-06,   S = -4.842e-02,   nfev = 13,   norm = -0.000
log10(alpha) = 0.00,    chi2 = 2.630e-06,   S = -4.843e-02,   nfev = 12,   norm = 0.000
log10(alpha) = -1.00,   chi2 = 7.289e-07,   S = -4.843e-02,   nfev = 19,   norm = 0.000
log10(alpha) = -2.00,   chi2 = 2.025e-07,   S = -4.844e-02,   nfev = 15,   norm = 0.000
log10(alpha) = -3.00,   chi2 = 9.426e-09,   S = -4.846e-02,   nfev = 18,   norm = 0.000
log10(alpha) = -4.00,   chi2 = 1.758e-10,   S = -4.847e-02,   nfev = 16,   norm = 0.000
log10(alpha) = -5.00,   chi2 = 2.416e-11,   S = -4.847e-02,   nfev = 16,   norm = 0.000
log10(alpha) = -6.00,   chi2 = 2.226e-11,   S = -4.847e-02,   nfev = 5,   norm = 0.000
log10(alpha) = -7.00,   chi2 = 2.234e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -8.00,   chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -9.00,   chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -10.00,  chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -11.00,  chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -12.00,  chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -13.00,  chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -14.00,  chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
log10(alpha) = -15.00,  chi2 = 2.218e-11,   S = -4.847e-02,   nfev = 1,   norm = 0.000
Fit parameters [-11.00254549  22.10493514   4.48412579   0.28317217]
Optimal log alpha -4.344425497997804
log10(alpha) = -4.34,   chi2 = 5.710e-11,   S = -4.847e-02,   nfev = 10,   norm = 0.000
_images/poorman_test_7_1.png
[8]:
plt.plot(wgrid, sol_01.A_opt, color='green', label='maxent')
plt.plot(true_w, true_spec_rot[0,1], color='green', ls='--', label='true')
plt.legend()
plt.show()

plt.plot(wgrid, sol_01.A_opt, color='green', label='maxent')
plt.plot(true_w, true_spec_rot[0,1], color='green', ls='--', label='true')
plt.xlim(-1,1)
plt.legend()
plt.show()
_images/poorman_test_8_0.png
_images/poorman_test_8_1.png
[9]:
spec_rot = np.zeros((2,2,sol_00.A_opt.shape[0]))
spec_rot[0,0] = sol_00.A_opt
spec_rot[1,1] = sol_11.A_opt
spec_rot[0,1] = sol_01.A_opt
spec_rot[1,0] = sol_01.A_opt # 10 and 01 are identical

true_det = true_spec_1 * true_spec_2
true_det = np.linalg.det(true_spec_rot.transpose((2,0,1)))
det = np.linalg.det(spec_rot.transpose((2,0,1)))

plt.plot(true_w, true_det, label='true')
plt.plot(wgrid, det, label='cont')
plt.legend()
plt.show()
_images/poorman_test_9_0.png

Conclusion: The poorman method actually works impressively well.

[ ]: