61 template <
typename T> nda::array<T, 2>
symmetrize(nda::array<T, 2>
const &X)
const {
62 auto [n_alpha, n_sigma] = X.shape();
63 nda::array<T, 2> result(n_alpha, n_sigma);
64 for (
auto [a, s] : result.indices()) { result(a, s) = nda::zeros<dcomplex>(X(a, s).shape()); }
65 auto n_symm = double(this->ops.size());
66 for (
auto const &sym_op : this->
ops) {
67 for (
auto &&[ialpha, jalpha, mat] : zip(range(n_alpha), sym_op.permutation, sym_op.mats)) {
68 for (
auto sigma : range(n_sigma)) {
69 result(jalpha, sigma) += mat * (sym_op.time_inv ? transpose(X(ialpha, sigma)) : X(ialpha, sigma)) * dagger(mat) / n_symm;
82 block2_gf<Mesh, matrix_valued>
symmetrize(block2_gf<Mesh, matrix_valued>
const &Gin,
auto const &atomic_decomposition)
const {
86 auto n_sigma = Gout.size2();
87 auto n_symm = double(this->ops.size());
90 enumerated_sub_slices(atomic_decomposition) | stdv::transform([](
auto &&x) {
return std::get<1>(x); }) | tl::to<std::vector>();
93 for (
auto sigma : range(n_sigma)) {
94 for (
auto const &op : this->
ops) {
95 auto const &mat = op.mats[alpha];
96 auto R_jalpha = range_list[op.permutation[alpha]];
97 for (
auto om : Gin(0, sigma).mesh()) {
98 auto A = nda::matrix<dcomplex>{Gin(0, sigma)[om](R_alpha, R_alpha)};
99 Gout(0, sigma)[om](R_jalpha, R_jalpha) += mat * (op.time_inv ? transpose(A) : A) * dagger(mat) / n_symm;