13namespace triqs::modest::detail {
14 auto constexpr r_all = nda::range::all;
16 template <
int Rank>
constexpr bool has_frequency = (Rank == 3 || Rank == 5);
19 template <
typename T>
auto extract_diagonal(nda::array<T, 2>
const &M, nda::range r) {
return M(r, r); }
20 template <
typename T>
void embed_diagonal(nda::array<T, 2> &M, nda::range r, nda::array<T, 2>
const &block) { M(r, r) = block; }
23 template <
typename T>
auto extract_diagonal(nda::array<T, 3>
const &M, nda::range r) {
return M(r_all, r, r); }
24 template <
typename T>
void embed_diagonal(nda::array<T, 3> &M, nda::range r, nda::array<T, 3>
const &block) { M(r_all, r, r) = block; }
27 template <
typename T>
auto extract_diagonal(nda::array<T, 4>
const &M, nda::range r) {
return M(r, r, r, r); }
28 template <
typename T>
void embed_diagonal(nda::array<T, 4> &M, nda::range r, nda::array<T, 4>
const &block) { M(r, r, r, r) = block; }
31 template <
typename T>
auto extract_diagonal(nda::array<T, 5>
const &M, nda::range r) {
return M(r_all, r, r, r, r); }
32 template <
typename T>
void embed_diagonal(nda::array<T, 5> &M, nda::range r, nda::array<T, 5>
const &block) { M(r_all, r, r, r, r) = block; }
35 template <
int Rank,
typename T>
auto make_zero_array(
long dim,
long n_w = 0) {
36 if constexpr (Rank == 2) {
37 return nda::zeros<T>(dim, dim);
38 }
else if constexpr (Rank == 3) {
39 return nda::zeros<T>(n_w, dim, dim);
40 }
else if constexpr (Rank == 4) {
41 return nda::zeros<T>(dim, dim, dim, dim);
42 }
else if constexpr (Rank == 5) {
43 return nda::zeros<T>(n_w, dim, dim, dim, dim);
48 template <
typename Mesh> std::vector<nda::array<dcomplex, 3>> make_data_view_from_block_gf(block_gf<Mesh, matrix_valued>
const &gf) {
49 std::vector<nda::array<dcomplex, 3>> data;
50 for (
auto block_idx = 0; block_idx < gf.size(); ++block_idx) { data.push_back(gf[block_idx].data()); }
55 template <
typename Mesh>
56 std::vector<std::vector<nda::array<dcomplex, 3>>> make_data_view_from_block_gfs(std::vector<block_gf<Mesh, matrix_valued>>
const &gfs) {
57 return gfs | stdv::transform([&](
auto g) {
return make_data_view_from_block_gf(g); }) | tl::to<std::vector>();
61 template <
typename Mesh> std::vector<nda::array<dcomplex, 3>> gather_blocks_to_data_view(block2_gf<Mesh, matrix_valued>
const &g) {
62 auto n_sigma = g.size2();
63 auto decomp =
get_struct(g).
dims(r_all, 0) | tl::to<std::vector>();
65 auto n_w = g(0, 0).mesh().size();
66 auto dim = stdr::fold_left(decomp, 0, std::plus<>());
68 auto data = range(n_sigma) | stdv::transform([dim, n_w](
auto) {
return nda::array<dcomplex, 3>(n_w, dim, dim); }) | tl::to<std::vector>();
69 for (
auto sigma : range(n_sigma)) {
70 for (
auto &&[index, sli] :
enumerated_sub_slices(decomp)) { data[sigma](r_all, sli, sli) = g(index, sigma).data(); }
75 template <
typename T>
auto gather_blocks_to_data_view(nda::array<nda::matrix<T>, 2>
const &M) {
76 auto n_sigma = M.extent(1);
77 auto decomp = range(M.extent(0)) | stdv::transform([&](
auto const &alpha) {
return M(alpha, 0).shape()[0]; }) | tl::to<std::vector>();
78 auto dim = stdr::fold_left(decomp, 0, std::plus<>());
79 nda::array<nda::array<T, 2>, 2> data(1, n_sigma);
80 for (
auto sigma : range(n_sigma)) {
81 data(0, sigma) = nda::zeros<T>(dim, dim);
82 for (
auto &&[index, sli] :
enumerated_sub_slices(decomp)) { data(0, sigma)(sli, sli) = M(index, sigma); }
88 template <
typename Mesh>
89 block_gf<Mesh, matrix_valued> make_block_gf_from_data_view(std::vector<nda::array<dcomplex, 3>>
const &data_view, gf_struct_t
const &gf_struct,
91 auto gf = block_gf<Mesh, matrix_valued>(mesh, gf_struct);
92 for (
auto &&[block_idx, block] : enumerate(data_view)) { gf[block_idx].data() = block; }
97 template <
typename Mesh>
98 block2_gf<Mesh, matrix_valued> make_block2_gf_from_data_view(std::vector<nda::array<dcomplex, 3>>
const &data_view, gf_struct2_t
const &gf_struct2,
101 auto n_sigma = gf2.size2();
102 auto sigma_embed_decomp =
get_struct(gf2).
dims(r_all, 0) | tl::to<std::vector>();
104 for (
auto sigma : range(n_sigma)) { gf2(alpha, sigma).data() = data_view[sigma](r_all, r_alpha, r_alpha); }
110 template <
typename T>
auto matrix_to_array(std::vector<std::vector<nda::matrix<T>>>
const &data) {
111 auto tmp_data = std::vector<std::vector<nda::array<T, 2>>>(data.size());
112 for (
auto imp : range(data.size())) {
113 for (
auto &&[block, block_data] : enumerate(data[imp])) { tmp_data[imp].emplace_back(block_data); }
119 template <
typename T>
auto array_to_matrix(std::vector<std::vector<nda::array<T, 2>>>
const &data) {
120 auto tmp_data = std::vector<std::vector<nda::matrix<T>>>(data.size());
121 for (
auto imp : range(data.size())) {
122 for (
auto &&[block, block_data] : enumerate(data[imp])) { tmp_data[imp].emplace_back(block_data); }
128 template <
typename T>
auto data_array_to_block2_array(std::vector<nda::array<T, 2>>
const &data_view, std::vector<long>
const &sigma_embed_decomp) {
129 auto n_alpha = long(sigma_embed_decomp.size());
130 auto n_sigma = long(data_view.size());
131 auto block2_array = nda::array<nda::array<T, 2>, 2>(n_alpha, n_sigma);
133 for (
auto sigma : range(n_sigma)) { block2_array(alpha, sigma) = data_view[sigma](r_alpha, r_alpha); }
gf_struct2_t get_struct(block2_gf< Mesh, matrix_valued > const &g)
block2_gf< Mesh, matrix_valued > make_block2_gf(Mesh const &mesh, gf_struct2_t const &gf_s)
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
nda::array< long, 2 > dims