27 template <
typename Mesh>
30 auto n_mesh = Gimp[0].mesh().size();
31 auto n_blocks = Gimp.size();
33 std::vector<std::vector<long>> groups;
34 std::vector<bool> used(n_blocks,
false);
36 auto are_matrices_equal = [threshold, n_mesh](
auto const &A,
auto const &B) {
37 if (A.target_shape() != B.target_shape())
return false;
38 long n0 = A.target_shape()[0];
39 for (
auto mesh_idx : range(n_mesh)) {
40 auto const &Am = A(mesh_idx);
41 auto const &Bm = B(mesh_idx);
42 for (
size_t i = 0; i < n0; ++i) {
43 for (
size_t j = 0; j < i + 1; ++j) {
44 if (std::abs(Am(i, j) - Bm(i, j)) > threshold)
return false;
51 for (
auto i = 0; i < n_blocks; ++i) {
53 std::vector<long> current_group = {i};
55 for (
auto j = i + 1; j < n_blocks; ++j) {
56 if (!used[j] && are_matrices_equal(Gimp[i], Gimp[j])) {
57 current_group.push_back(j);
61 groups.push_back(std::move(current_group));
78 template <
typename Mesh> block_gf<Mesh, matrix_valued>
symmetrize(block_gf<Mesh, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls) {
80 auto const &mesh = gsymm[0].mesh();
82 for (
auto const °_bl : deg_bls) {
83 auto n_deg = deg_bl.size();
84 auto dim = g[deg_bl[0]].target_shape()[0];
86 auto gtmp = gf{mesh, {dim, dim}};
87 for (
auto bl : deg_bl) { gtmp += g[bl]; }
91 for (
auto bl : deg_bl) { gsymm[bl] = gtmp; }
108 template <
typename Mesh> gf<Mesh, matrix_valued>
symmetrize(gf<Mesh, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls) {
110 auto const &mesh = gsymm.mesh();
112 for (
auto const °_bl : deg_bls) {
113 auto n_deg = deg_bl.size();
116 auto gtmp_data = nda::zeros<dcomplex>(mesh.size());
117 for (
auto ibl : deg_bl) { gtmp_data += g.data()(
r_all, ibl, ibl); }
119 for (
auto ibl : deg_bl) { gsymm.data()(
r_all, ibl, ibl) = gtmp_data; }
122 auto gtmp_data_off = nda::zeros<dcomplex>(mesh.size());
123 auto n_off = n_deg * (n_deg - 1);
124 for (
auto ibl : deg_bl) {
125 for (
auto jbl : deg_bl) {
126 if (ibl != jbl) { gtmp_data_off += g.data()(
r_all, ibl, jbl); }
129 gtmp_data_off /= n_off;
130 for (
auto ibl : deg_bl) {
131 for (
auto jbl : deg_bl) {
132 if (ibl != jbl) { gsymm.data()(
r_all, ibl, jbl) = gtmp_data_off; }
149 inline std::vector<nda::matrix<dcomplex>>
symmetrize(std::vector<nda::matrix<dcomplex>>
const &bl_mat, std::vector<std::vector<long>> deg_bls) {
151 std::vector<nda::matrix<dcomplex>> bl_mat_symm = bl_mat;
153 for (
auto const °_bl : deg_bls) {
154 auto n_deg = deg_bl.size();
155 auto dim = bl_mat[deg_bl[0]].shape()[0];
157 auto bl_mat_tmp = nda::zeros<dcomplex>(dim, dim);
158 for (
auto bl : deg_bl) { bl_mat_tmp += bl_mat[bl]; }
160 bl_mat_tmp /=
static_cast<double>(n_deg);
162 for (
auto bl : deg_bl) { bl_mat_symm[bl] = bl_mat_tmp; }
173 template block_gf<imfreq, matrix_valued>
symmetrize(block_gf<imfreq, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
174 template block_gf<imtime, matrix_valued>
symmetrize(block_gf<imtime, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
175 template block_gf<dlr_imfreq, matrix_valued>
symmetrize(block_gf<dlr_imfreq, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
176 template block_gf<dlr_imtime, matrix_valued>
symmetrize(block_gf<dlr_imtime, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
178 template gf<imfreq, matrix_valued>
symmetrize(gf<imfreq, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
179 template gf<imtime, matrix_valued>
symmetrize(gf<imtime, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
180 template gf<dlr_imfreq, matrix_valued>
symmetrize(gf<dlr_imfreq, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
181 template gf<dlr_imtime, matrix_valued>
symmetrize(gf<dlr_imtime, matrix_valued>
const &g, std::vector<std::vector<long>> deg_bls);
block_gf< Mesh, matrix_valued > symmetrize(block_gf< Mesh, matrix_valued > const &g, std::vector< std::vector< long > > deg_bls)
Symmetrize the blocks of a block Green's function given a list of it's degenerate blocks.
std::vector< std::vector< long > > analyze_degenerate_blocks(block_gf< Mesh, matrix_valued > const &Gimp, double threshold=1.e-5)
Find the generate blocks of a block GF by analyzing or using the union-find algorithm.
static constexpr auto r_all