42 template <
typename T> nda::array<T, 2>
symmetrize(nda::array<T, 2>
const &X)
const {
43 auto [n_alpha, n_sigma] = X.shape();
44 nda::array<T, 2> result(n_alpha, n_sigma);
45 for (
auto [a, s] : result.indices()) { result(a, s) = nda::zeros<dcomplex>(X(a, s).shape()); }
46 auto n_symm = double(this->ops.size());
47 for (
auto const &sym_op : this->
ops) {
48 for (
auto &&[ialpha, jalpha, mat] : zip(range(n_alpha), sym_op.permutation, sym_op.mats)) {
49 for (
auto sigma : range(n_sigma)) {
50 result(jalpha, sigma) += mat * (sym_op.time_inv ? transpose(X(ialpha, sigma)) : X(ialpha, sigma)) * dagger(mat) / n_symm;
63 block2_gf<Mesh, matrix_valued>
symmetrize(block2_gf<Mesh, matrix_valued>
const &Gin,
auto const &atomic_decomposition)
const {
67 auto n_sigma = Gout.size2();
68 auto n_symm = double(this->ops.size());
71 enumerated_sub_slices(atomic_decomposition) | stdv::transform([](
auto &&x) {
return std::get<1>(x); }) | tl::to<std::vector>();
74 for (
auto sigma : range(n_sigma)) {
75 for (
auto const &op : this->
ops) {
76 auto const &mat = op.mats[alpha];
77 auto R_jalpha = range_list[op.permutation[alpha]];
78 for (
auto om : Gin(0, sigma).mesh()) {
79 auto A = nda::matrix<dcomplex>{Gin(0, sigma)[om](R_alpha, R_alpha)};
80 Gout(0, sigma)[om](R_jalpha, R_jalpha) += mat * (op.time_inv ? transpose(A) : A) * dagger(mat) / n_symm;