TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
map.hpp
Go to the documentation of this file.
1// Copyright (c) 2016-2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2016-2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2023 Simons Foundation
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You may obtain a copy of the License at
16// https://www.gnu.org/licenses/gpl-3.0.txt
17//
18// Authors: Michel Ferrero, Olivier Parcollet, Nils Wentzell
19
24
25#pragma once
26
27#include "./factories.hpp"
28
29#include <type_traits>
30#include <utility>
31#include <vector>
32
33namespace triqs::gfs {
34
35 // ------------------------------- Map --------------------------------------------------
36 // map takes a function f, a block_gf or its view g
37 // then it computes f(g[i]) for all i
38 // If the result of f is :
39 // * a gf : then map returns a block_gf
40 // * a gf_view : then map returns a block_gf_view
41 // * a gf_const_view : then map returns a block_gf_const_view
42 // * otherwise : then map returns a std::vector<>
43 namespace impl {
44
45 // NOLINTBEGIN(cppcoreguidelines-missing-std-forward,cppcoreguidelines-rvalue-reference-param-not-moved): f is applied
46 // once per element (so it cannot be forwarded); in `invoke`, F/G are class-template parameters that collapse to
47 // lvalue refs for lvalue operands, so std::forward (not std::move) is the correct cast.
48
49 // Apply f to each element of a (const) vector, collecting the results in a new vector.
50 template <typename F, typename T> auto _map(F &&f, std::vector<T> const &V) {
51 std::vector<std::invoke_result_t<F, T>> res;
52 res.reserve(V.size());
53 for (auto &x : V) res.emplace_back(f(x));
54 return res;
55 }
56
57 template <typename F, typename T> auto _map(F &&f, std::vector<T> &V) {
58 std::vector<std::invoke_result_t<F, T>> res;
59 res.reserve(V.size());
60 for (auto &x : V) res.emplace_back(f(x));
61 return res;
62 }
63
64 // Apply f to each element of a (const) vector of vectors, collecting the results in a new vector of vectors.
65 template <typename F, typename T> auto _map(F &&f, std::vector<std::vector<T>> const &V) {
66 std::vector<std::vector<std::invoke_result_t<F, T>>> res;
67 res.reserve(V.size());
68 for (auto &x : V) res.push_back(_map(f, x));
69 return res;
70 }
71
72 template <typename F, typename T> auto _map(F &&f, std::vector<std::vector<T>> &V) {
73 std::vector<std::vector<std::invoke_result_t<F, T>>> res;
74 res.reserve(V.size());
75 for (auto &x : V) res.push_back(_map(f, x));
76 return res;
77 }
78
79 // Dispatch the result type R of f: build a block_gf(_view) when R is a gf(_view), else a std::vector.
80 template <typename F, typename G, typename R = std::decay_t<std::invoke_result_t<F, typename std::decay_t<G>::g_t>>> struct map;
81
82 // general case
83 template <typename F, typename G, typename R> struct map {
84 static auto invoke(F &&f, G &&g) { return _map(std::forward<F>(f), std::forward<G>(g).data()); }
85 };
86
87 // now , when R is a gf, gf_view, a gf_const_view
88 template <typename F, typename G, typename... T> struct map<F, G, gf<T...>> {
89 static auto invoke(F &&f, G &&g) {
90 if constexpr (std::remove_reference_t<G>::arity == 1)
91 return make_block_gf(g.block_names(), _map(std::forward<F>(f), std::forward<G>(g).data()));
92 else
93 return make_block2_gf(g.block_names()[0], g.block_names()[1], _map(std::forward<F>(f), std::forward<G>(g).data()));
94 }
95 };
96
97 template <typename F, typename G, typename... T> struct map<F, G, gf_view<T...>> {
98 static auto invoke(F &&f, G &&g) {
99 if constexpr (std::remove_reference_t<G>::arity == 1)
100 return make_block_gf_view(g.block_names(), _map(std::forward<F>(f), std::forward<G>(g).data()));
101 else
102 return make_block2_gf_view(g.block_names()[0], g.block_names()[1], _map(std::forward<F>(f), std::forward<G>(g).data()));
103 }
104 };
105
106 template <typename F, typename G, typename... T> struct map<F, G, gf_const_view<T...>> {
107 static auto invoke(F &&f, G &&g) {
108 if constexpr (std::remove_reference_t<G>::arity == 1)
109 return make_block_gf_const_view(g.block_names(), _map(std::forward<F>(f), std::forward<G>(g).data()));
110 else
111 return make_block2_gf_const_view(g.block_names()[0], g.block_names()[1], _map(std::forward<F>(f), std::forward<G>(g).data()));
112 }
113 };
114 // NOLINTEND(cppcoreguidelines-missing-std-forward,cppcoreguidelines-rvalue-reference-param-not-moved)
115 } // namespace impl
116
131 template <typename F, typename G> auto map_block_gf(F &&f, G &&g) {
132 static_assert(is_block_gf_v<G>, "map_block_gf requires a block gf");
133 return impl::map<F, G>::invoke(std::forward<F>(f), std::forward<G>(g));
134 }
135
146 template <typename F, typename G>
147 auto map(F &&f, G &&g)
148 requires(is_block_gf_v<G>)
149 {
150 return impl::map<F, G>::invoke(std::forward<F>(f), std::forward<G>(g));
151 }
152
153} // namespace triqs::gfs
data_t & data()
Direct access to the blocks.
Provides the free factory functions for block Green's functions.
gf(M, DataArray) -> gf< M, target_from_array< DataArray, n_variables< M > > >
Deduce a triqs::gfs::gf type from a mesh and a data array.
block_gf_const_view_of< G0 > make_block_gf_const_view(G0 &&g0, G &&...g)
Make a triqs::gfs::block_gf_const_view from a list of Green's function views (block names default to ...
block2_gf_const_view_of< Gf > make_block2_gf_const_view(std::vector< std::vector< Gf > > &v)
Make a triqs::gfs::block2_gf_const_view from a matrix of views (block names default to "0",...
block2_gf_view_of< Gf > make_block2_gf_view(std::vector< std::vector< Gf > > &v)
Make a triqs::gfs::block2_gf_view from a matrix of views (block names default to "0",...
block_gf_view_of< G0 > make_block_gf_view(G0 &&g0, G &&...g)
Make a triqs::gfs::block_gf_view from a list of Green's function views (block names default to "0",...
block2_gf< V, T, L > make_block2_gf(int n, int p, gf< V, T, L > const &g)
Make a triqs::gfs::block2_gf of n x p copies of a Green's function.
block_gf< V, T, L > make_block_gf(int n, gf< V, T, L > const &g)
Make a triqs::gfs::block_gf of n copies of a Green's function (block names default to "0",...
Definition factories.hpp:50
auto map(F &&f, G &&g)
Apply a callable to each block of a block Green's function (alias of triqs::gfs::map_block_gf).
Definition map.hpp:147
auto map_block_gf(F &&f, G &&g)
Apply a callable to each block of a block Green's function.
Definition map.hpp:131
constexpr bool is_block_gf_v
Trait to check whether a type is a block Green's function.
Definition block_gf.hpp:119