57 inline std::vector<std::vector<long>>
analyze_degenerate_blocks(block_gf<imfreq, matrix_valued>
const &Gimp,
double threshold = 1.e-5) {
58 auto find_degenerate = [&](
auto const &G) {
59 auto are_matrices_equal = [threshold](
auto const &A,
auto const &B) {
60 if (A.shape() != B.shape())
return false;
61 return nda::all(nda::map([threshold](
auto x) {
return x < threshold; })(abs(A - B)));
64 auto midpt =
static_cast<long>(G[0].mesh().size() / 2);
65 auto mats = G | stdv::transform([midpt](
auto const &g) {
return nda::matrix<dcomplex>{g(midpt)}; }) | tl::to<std::vector>();
67 auto uf = detail::union_find(mats.size());
69 std::map<long, std::vector<long>> groups_map;
70 for (
long i = 0; i < mats.size(); ++i) {
71 for (
long j = i + 1; j < mats.size(); ++j) {
72 if (are_matrices_equal(mats[i], mats[j])) uf.unite(i, j);
74 groups_map[uf.find(i)].emplace_back(i);
77 return groups_map | stdv::values | stdv::filter([](
auto const &g) {
return g.size() > 1; }) | tl::to<std::vector>();
79 return find_degenerate(Gimp) | stdv::transform([](
auto &x) {
return x | stdv::transform([](
auto &y) {
return y; }) | tl::to<std::vector>(); })
80 | tl::to<std::vector>();
93 inline block_gf<imfreq, matrix_valued>
symmetrize_gf(block_gf<imfreq, matrix_valued>
const &Gin, std::vector<std::vector<long>> degenerate_blocks) {
95 auto mesh = Gsymm[0].mesh();
96 for (
auto degenerate : degenerate_blocks) {
97 auto n_deg = degenerate.size();
98 auto dim = Gin[degenerate[0]].target_shape()[0];
99 auto gtmp = gf{mesh, {dim, dim}};
100 for (
auto deg_bl : degenerate) { gtmp += Gin[deg_bl] / n_deg; }
101 for (
auto deg_bl : degenerate) { Gsymm[deg_bl] = gtmp; }
block_gf< imfreq, matrix_valued > symmetrize_gf(block_gf< imfreq, matrix_valued > const &Gin, std::vector< std::vector< long > > degenerate_blocks)
Symmetrize the blocks of a Green's function given a list of it's degenerate blocks.
std::vector< std::vector< long > > analyze_degenerate_blocks(block_gf< imfreq, matrix_valued > const &Gimp, double threshold=1.e-5)
Find the generate blocks of a BlockGf by analyzing G(τ=0) or G(iω₀) using the union-find algorithm.