33 std::vector<std::vector<idx_t>> c_vec, cdag_vec;
36 auto const &G0_tau_mesh = G0_tau[0].mesh();
37 auto const &M_tau_mesh = tau_mesh;
40 for (
auto &det : qmc_config.dets) {
43 auto x_to_mesh = [beta = params.beta, &M_tau_mesh](c_t
const &c_i) {
44 return idx_t{M_tau_mesh.to_index(closest_mesh_pt(beta -
double(c_i.tau))), c_i.u, c_i.tau};
47 auto y_to_mesh = [beta = params.beta, &G0_tau_mesh](cdag_t
const &cdag_j) {
48 return idx_t{G0_tau_mesh.to_index(closest_mesh_pt(beta -
double(cdag_j.tau))), cdag_j.u, cdag_j.tau};
52 c_vec.push_back(make_vector_from_range(transform(det.get_x_internal_order(), x_to_mesh)));
53 cdag_vec.push_back(make_vector_from_range(transform(det.get_y_internal_order(), y_to_mesh)));
57 std::vector<matrix<dcomplex>> GM_vec(params.n_blocks());
60 for (
int bl : range(params.n_blocks())) {
62 auto const &det = qmc_config.dets[bl];
63 int det_size = det.size();
65 if (det.size() == 0)
continue;
67 auto const &cdag = cdag_vec[bl];
68 int bl_size = G0_tau[bl].target_shape()[0];
69 auto G = matrix<dcomplex>(bl_size, det_size);
71 for (
int b_u : range(bl_size))
72 for (
int j : range(det_size)) G(b_u, j) = G0_tau[bl][cdag[j].tau_idx](b_u, cdag[j].u);
74 GM_vec[bl] = G * det.inverse_matrix_internal_order();
78 for (
int bl1 : range(params.n_blocks())) {
80 int det1_size = qmc_config.dets[bl1].size();
83 if (det1_size == 0)
continue;
85 auto const &GM1 = GM_vec[bl1];
86 auto const &c1 = c_vec[bl1];
87 int bl1_size = G0_tau[bl1].target_shape()[0];
90 auto &M3pp_tau = M3pp_tau_(bl1, bl1);
91 auto &M3pp_delta = M3pp_delta_(bl1, bl1);
93 for (
auto [j, l, i, k] : product_range(bl1_size, bl1_size, det1_size, det1_size)) {
95 if (c1[i].tau_pt == c1[k].tau_pt) {
96 M3pp_delta[cdag_vec[bl1][i].tau_idx](c1[i].u, j, c1[k].u, l) += -sign * GM1(l, i) * GM1(j, k);
99 M3pp_tau[c1[i].tau_idx, c1[k].tau_idx](c1[i].u, j, c1[k].u, l) += -sign * GM1(l, i) * GM1(j, k);
103 for (
int bl2 : range(params.n_blocks())) {
105 int det2_size = qmc_config.dets[bl2].size();
108 if (det2_size == 0)
continue;
110 auto const &GM2 = GM_vec[bl2];
111 auto const &c2 = c_vec[bl2];
112 int bl2_size = G0_tau[bl2].target_shape()[0];
113 auto &M3pp_tau_bl = M3pp_tau_(bl1, bl2);
114 auto &M3pp_delta_bl = M3pp_delta_(bl1, bl2);
117 for (
auto [j, l, i, k] : product_range(bl1_size, bl2_size, det1_size, det2_size)) {
119 if (c1[i].tau_pt == c2[k].tau_pt) {
120 M3pp_delta_bl[cdag_vec[bl1][i].tau_idx](c1[i].u, j, c2[k].u, l) += sign * GM1(j, i) * GM2(l, k);
122 M3pp_tau_bl[c1[i].tau_idx, c2[k].tau_idx](c1[i].u, j, c2[k].u, l) += sign * GM1(j, i) * GM2(l, k);
131 Z = mpi::all_reduce(Z, comm);
132 M3pp_tau_ = mpi::all_reduce(M3pp_tau_, comm);
133 M3pp_delta_ = mpi::all_reduce(M3pp_delta_, comm);
136 int n = params.n_tau_M3 - 1;
137 double dtau = params.beta / n;
138 M3pp_tau_ = M3pp_tau_ / (Z * dtau * dtau);
140 int n_del = params.n_tau - 1;
141 double dtau_del = params.beta / n_del;
142 M3pp_delta_ = M3pp_delta_ / (Z * dtau_del);
146 for (
auto [M, M_del] : zip(M3pp_tau_, M3pp_delta_)) {