3
0
mirror of https://github.com/triqs/dft_tools synced 2024-10-31 11:13:46 +01:00

gf : add indices, name in C++

This commit is contained in:
Olivier Parcollet 2014-05-09 22:22:32 +02:00
parent 5105e04ac7
commit 376056f7bd
5 changed files with 148 additions and 28 deletions

View File

@ -40,6 +40,8 @@ namespace arrays {
range(std::ptrdiff_t first__, std::ptrdiff_t last__, std::ptrdiff_t step__ = 1)
: first_(first__), last_(last__), step_(step__) {}
range(std::ptrdiff_t i) : range (i,i+1,1){}
std::ptrdiff_t first() const { return first_; }
std::ptrdiff_t last() const { return last_; }
std::ptrdiff_t step() const { return step_; }

View File

@ -97,13 +97,13 @@ namespace gfs {
block_gf<Variable, Target, Opt> make_block_gf(int n, gf<Variable, Target, Opt> const &g) {
auto V = std::vector<gf<Variable, Target, Opt>>{};
for (int i = 0; i < n; ++i) V.push_back(g);
return {{n}, std::move(V), nothing{}, nothing{}};
return {{n}, std::move(V), nothing{}, nothing{}, nothing{}};
}
// from a vector of gf (moving directly)
template <typename Variable, typename Target, typename Opt>
block_gf<Variable, Target, Opt> make_block_gf(std::vector<gf<Variable, Target, Opt>> V) {
return {{int(V.size())}, std::move(V), nothing{}, nothing{}};
return {{int(V.size())}, std::move(V), nothing{}, nothing{}, nothing{}};
}
// from a vector of gf : generalized to have a different type of gf in the vector (e.g. views...)
@ -111,13 +111,13 @@ namespace gfs {
block_gf<Variable, Target, Opt> make_block_gf(std::vector<GF2> const &V) {
auto V2 = std::vector<gf<Variable, Target, Opt>>{};
for (auto const &g : V) V2.push_back(g);
return {{int(V.size())}, std::move(V2), nothing{}, nothing{}};
return {{int(V.size())}, std::move(V2), nothing{}, nothing{}, nothing{}};
}
// from a init list of GF with the correct type
template <typename Variable, typename Target, typename Opt>
block_gf<Variable, Target, Opt> make_block_gf(std::initializer_list<gf<Variable, Target, Opt>> const &V) {
return {{int(V.size())}, V, nothing{}, nothing{}};
return {{int(V.size())}, V, nothing{}, nothing{}, nothing{}};
}
// from vector<string> and a gf to be copied
@ -125,7 +125,7 @@ namespace gfs {
block_gf<Variable, Target, Opt> make_block_gf(std::vector<std::string> block_names, gf<Variable, Target, Opt> const &g) {
auto V = std::vector<gf<Variable, Target, Opt>>{};
for (int i = 0; i < block_names.size(); ++i) V.push_back(g);
return {{block_names}, std::move(V), nothing{}, nothing{}};
return {{block_names}, std::move(V), nothing{}, nothing{}, nothing{}};
}
// from vector<string>, vector<gf>
@ -133,7 +133,7 @@ namespace gfs {
block_gf<Variable, Target, Opt> make_block_gf(std::vector<std::string> block_names, std::vector<gf<Variable, Target, Opt>> V) {
if (block_names.size() != V.size())
TRIQS_RUNTIME_ERROR << "make_block_gf(vector<string>, vector<gf>) : the two vectors do not have the same size !";
return {{block_names}, std::move(V), nothing{}, nothing{}};
return {{block_names}, std::move(V), nothing{}, nothing{}, nothing{}};
}
// from vector<string>, init_list<GF>
@ -141,7 +141,7 @@ namespace gfs {
block_gf<Variable, Target, Opt> make_block_gf(std::vector<std::string> block_names,
std::initializer_list<gf<Variable, Target, Opt>> const &V) {
if (block_names.size() != V.size()) TRIQS_RUNTIME_ERROR << "make_block_gf(vector<string>, init_list) : size mismatch !";
return {{block_names}, V, nothing{}, nothing{}};
return {{block_names}, V, nothing{}, nothing{}, nothing{}};
}
// ------------------------------- Free Factories for view type --------------------------------------------------
@ -149,17 +149,17 @@ namespace gfs {
template <typename G0, typename... G>
gf_view<block_index, typename std::remove_reference<G0>::type::view_type> make_block_gf_view(G0 &&g0, G &&... g) {
auto V = std::vector<typename std::remove_reference<G0>::type::view_type>{std::forward<G0>(g0), std::forward<G>(g)...};
return {{int(V.size())}, std::move(V), nothing{}, nothing{}};
return {{int(V.size())}, std::move(V), nothing{}, nothing{}, nothing{}};
// return { gf_mesh<block_index, Opt> {int(V.size())}, std::move(V), nothing{}, nothing{} } ;
}
template <typename GF> gf_view<block_index, typename GF::regular_type> make_block_gf_view_from_vector(std::vector<GF> V) {
return {{int(V.size())}, std::move(V), nothing{}, nothing{}};
return {{int(V.size())}, std::move(V), nothing{}, nothing{}, nothing{}};
}
// for cython proxy only. do not document.
template <typename GF, typename GF2> gf_view<block_index, GF> make_block_gf_view_from_vector_of_cython_proxy(std::vector<GF2> V) {
return {{int(V.size())}, std::move(V), nothing{}, nothing{}};
return {{int(V.size())}, std::move(V), nothing{}, nothing{}, nothing{}};
}
// ------------------------------- Extend reinterpret_scalar_valued_gf_as_matrix_valued for block gf ------

View File

@ -72,6 +72,15 @@ namespace gfs {
using type = nothing;
};
// indices
template <typename Target, typename Opt> struct indices {
using type = nothing;
};
template <typename Opt> struct indices<matrix_valued, Opt> {
using type = indices_2;
};
// data_proxy contains function to manipulate the data array, but no data itself.
// this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf,
// ...)
@ -119,6 +128,7 @@ namespace gfs {
using mesh_point_t = typename mesh_t::mesh_point_t;
using mesh_index_t = typename mesh_t::index_t;
using symmetry_t = typename gfs_implementation::symmetry<Variable, Target, Opt>::type;
using indices_t = typename gfs_implementation::indices<Target, Opt>::type;
using evaluator_t = gfs_implementation::evaluator<Variable, Target, Opt>;
using data_proxy_t = gfs_implementation::data_proxy<Variable, Target, Opt>;
@ -138,6 +148,7 @@ namespace gfs {
singularity_t &singularity() { return _singularity; }
singularity_t const &singularity() const { return _singularity; }
symmetry_t const &symmetry() const { return _symmetry; }
indices_t const &indices() const { return _indices; }
evaluator_t const &get_evaluator() const { return _evaluator; }
auto get_data_shape() const DECL_AND_RETURN(get_shape(this -> data()));
@ -147,6 +158,10 @@ namespace gfs {
data_t _data;
singularity_t _singularity;
symmetry_t _symmetry;
indices_t _indices;
public :
std::string name;
protected :
evaluator_t _evaluator;
data_proxy_t _data_proxy;
@ -160,6 +175,8 @@ namespace gfs {
_data(factory<data_t>(x.data())),
_singularity(factory<singularity_t>(x.singularity())),
_symmetry(x.symmetry()),
_indices(x.indices()),
name(x.name),
_evaluator(x._evaluator) {}
gf_impl(gf_impl &&) = default;
@ -171,15 +188,21 @@ namespace gfs {
_data(factory<data_t>(x.data())),
_singularity(factory<singularity_t>(x.singularity())),
_symmetry(x.symmetry()),
_indices(x.indices()),
name(x.name),
_evaluator(x.get_evaluator()) {}
template <typename M, typename D, typename S, typename SY, typename EV>
gf_impl(M &&m, D &&dat, S &&sing, SY &&sy, EV &&ev)
: _mesh(std::forward<M>(m)),
_data(std::forward<D>(dat)),
_singularity(std::forward<S>(sing)),
_symmetry(std::forward<SY>(sy)),
_evaluator(std::forward<EV>(ev)) {}
gf_impl(M &&m, D &&dat, S &&sing, SY &&sy, indices_t ind, std::string name, EV &&ev)
: _mesh(std::forward<M>(m))
, _data(std::forward<D>(dat))
, _singularity(std::forward<S>(sing))
, _symmetry(std::forward<SY>(sy))
, _indices(std::move(ind))
, name(name)
, _evaluator(std::forward<EV>(ev)) {
if (!_indices.check_size(this)) TRIQS_RUNTIME_ERROR << "Size of indices mismatch with data size";
}
void operator=(gf_impl const &rhs) = delete; // done in derived class.
@ -189,6 +212,8 @@ namespace gfs {
swap(this->_data, b._data);
swap(this->_singularity, b._singularity);
swap(this->_symmetry, b._symmetry);
swap(this->_indices, b._indices);
swap(this->name, b.name);
swap(this->_evaluator, b._evaluator);
}
@ -320,6 +345,8 @@ namespace gfs {
ar &TRIQS_MAKE_NVP("singularity", _singularity);
ar &TRIQS_MAKE_NVP("mesh", _mesh);
ar &TRIQS_MAKE_NVP("symmetry", _symmetry);
ar &TRIQS_MAKE_NVP("indices", _indices);
ar &TRIQS_MAKE_NVP("name", name);
}
/// print
@ -391,17 +418,19 @@ namespace gfs {
*this = x;
}
gf(typename B::mesh_t m, typename B::data_t dat, typename B::singularity_view_t const &si, typename B::symmetry_t const &s)
: B(std::move(m), std::move(dat), si, s, typename B::evaluator_t{}) {}
gf(typename B::mesh_t m, typename B::data_t dat, typename B::singularity_view_t const &si, typename B::symmetry_t const &s,
typename B::indices_t const &ind, std::string name = "")
: B(std::move(m), std::move(dat), si, s, ind, name, typename B::evaluator_t{}) {}
using target_shape_t = typename factory::target_shape_t;
gf(typename B::mesh_t m, target_shape_t shape = target_shape_t{})
: B(std::move(m), factory::make_data(m, shape), factory::make_singularity(m, shape), typename B::symmetry_t{},
gf(typename B::mesh_t m, target_shape_t shape = target_shape_t{}, typename B::indices_t const &ind = typename B::indices_t{})
: B(std::move(m), factory::make_data(m, shape), factory::make_singularity(m, shape), typename B::symmetry_t{}, ind, {}, // clean unncessary types
typename B::evaluator_t{}) {}
friend void swap(gf &a, gf &b) noexcept { a.swap_impl(b); }
// CLEAN THIS : one op only gf rhs, + move
gf &operator=(gf const &rhs) {
*this = gf(rhs);
return *this;
@ -424,6 +453,7 @@ namespace gfs {
this->_singularity = rhs.singularity();
// to be implemented : there is none in the gf_expr in particular....
// this->_symmetry = rhs.symmetry();
// indices and name are not affected by it ???
}
};
@ -454,14 +484,17 @@ namespace gfs {
gf_view(gf_impl<Variable, Target, Opt, false, false> &&g) noexcept : B(std::move(g), bool {}) {} // from a gf &&
template <typename D>
gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s)
: B(m, factory<typename B::data_t>(dat), t, s, typename B::evaluator_t{}) {}
gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s,
typename B::indices_t const &ind, std::string name = "")
: B(m, factory<typename B::data_t>(dat), t, s, ind, name, typename B::evaluator_t{}) {}
void rebind(gf_view const &X) noexcept {
this->_mesh = X._mesh;
this->_symmetry = X._symmetry;
this->_data_proxy.rebind(this->_data, X);
this->_singularity.rebind(X._singularity);
this->_indices = X._indices;
this->name = X.name;
}
void rebind(gf_view<Variable, Target, Opt, false> const &X) noexcept {
@ -489,8 +522,9 @@ namespace gfs {
gf_view(gf_impl<Variable, Target, Opt, false, false> &&g) noexcept : B(std::move(g), bool {}) {} // from a gf &&
template <typename D>
gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s)
: B(m, factory<typename B::data_t>(dat), t, s, typename B::evaluator_t{}) {}
gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s,
typename B::indices_t const &ind = typename B::indices_t{}, std::string name = "")
: B(m, factory<typename B::data_t>(dat), t, s, ind, name, typename B::evaluator_t{}) {}
friend void swap(gf_view &a, gf_view &b) noexcept { a.swap_impl(b); }
@ -499,6 +533,8 @@ namespace gfs {
this->_symmetry = X._symmetry;
this->_data_proxy.rebind(this->_data, X);
this->_singularity.rebind(X._singularity);
this->_indices = X._indices;
this->name = X.name;
}
gf_view &operator=(gf_view const &rhs) {
@ -540,7 +576,7 @@ namespace gfs {
static_assert(std::is_same<Target, matrix_valued>::value, "slice_target only for matrix_valued GF's");
using arrays::range;
return {g.mesh(), g.data()(range(), std::forward<Args>(args)...),
slice_target(g.singularity(), std::forward<Args>(args)...), g.symmetry()};
slice_target(g.singularity(), std::forward<Args>(args)...), g.symmetry(), slice(g.indices(),std::forward<Args>(args)...), g.name };
}
template <typename Variable, typename Target, typename Opt, typename... Args>
@ -560,7 +596,7 @@ namespace gfs {
static_assert(std::is_same<Target, matrix_valued>::value, "slice_target only for matrix_valued GF's");
using arrays::range;
return {g.mesh(), g.data()(range(), std::forward<Args>(args)...),
slice_target(g.singularity(), range(args, args + 1)...), g.symmetry()};
slice_target(g.singularity(), range(args, args + 1)...), g.symmetry(), {}, g.name};
}
template <typename Variable, typename Target, typename Opt, typename... Args>
@ -573,6 +609,15 @@ namespace gfs {
return slice_target_to_scalar(g(), std::forward<Args>(args)...);
}
/*// slice with string arguments, for python mainly.
template <typename Variable, typename Target, typename Opt>
gf_view<Variable, matrix_valued, Opt> slice_target_string_indices(gf_view<Variable, Target, Opt> g, std::string const & a1, std::string const & a2) {
int n1 = g.indices().convert_index(a1,0);
int n2 = g.indices().convert_index(a2,1);
return slice_target (g, n1, n2); // the slice will have no indices. Ok ?
}
*/
// ---------------------------------- target reinterpretation ------------------------------------
// a scalar_valued gf can be viewed as a 1x1 matrix
@ -581,7 +626,7 @@ namespace gfs {
reinterpret_scalar_valued_gf_as_matrix_valued(gf_view<Variable, scalar_valued, Opt, IsConst> g) {
using a_t = typename gf_view<Variable, matrix_valued, Opt, IsConst>::data_view_t;
auto a = a_t{typename a_t::indexmap_type(join(g.data().shape(), make_shape(1, 1))), g.data().storage()};
return {g.mesh(), a, g.singularity(), g.symmetry()};
return {g.mesh(), a, g.singularity(), g.symmetry(), {} , g.name};
}
template <typename Variable, typename Opt>
@ -677,6 +722,8 @@ namespace gfs {
h5_write(gr, "singularity", g._singularity);
h5_write(gr, "mesh", g._mesh);
h5_write(gr, "symmetry", g._symmetry);
h5_write(gr, "indices", g._indices);
//h5_write(gr, "name", g.name);
}
template <bool B> static void read(h5::group gr, gf_impl<Variable, Target, Opt, B, false> &g) {
@ -684,6 +731,8 @@ namespace gfs {
h5_read(gr, "singularity", g._singularity);
h5_read(gr, "mesh", g._mesh);
h5_read(gr, "symmetry", g._symmetry);
h5_read(gr, "indices", g._indices);
//h5_read(gr, "name", g.name);
}
};
} // gfs_implementation

View File

@ -30,7 +30,7 @@ namespace gfs {
template <typename Variable, typename Target, bool V, bool C>
gf_view<Variable, Target, no_tail, C> make_gf_view_without_tail(gf_impl<Variable, Target, void, V, C> const &g) {
return {g.mesh(), g.data(), {}, g.symmetry()};
return {g.mesh(), g.data(), {}, g.symmetry(), g.indices(), g.name};
}
namespace details { // dispatch the test for scalar_valued and matrix_valued

View File

@ -74,6 +74,73 @@ namespace gfs {
template <typename... T> closest_pt_wrap<T...> closest_mesh_pt(T &&... x) {
return closest_pt_wrap<T...>{std::forward<T>(x)...};
}
//------------------------------------------------------
// A simple indice struct
// Replace empty state by optional ?
struct indices_2 {
std::vector<std::vector<std::string>> ind;
indices_2() = default;
indices_2(std::vector<std::vector<std::string>> _ind) : ind(std::move(_ind)) {}
bool is_empty() const { return ind.size() == 0; }
template <typename G> bool check_size(G *g) const {
return (is_empty() ||
((ind.size() == 2) && (ind[0].size() == get_target_shape(*g)[0]) && (ind[1].size() == get_target_shape(*g)[1])));
}
std::vector<std::string> operator[](int i) const {
if (is_empty())
return {};
else
return ind[i];
}
arrays::range convert_index(std::string const &s, int l_r) const {
if (!is_empty()) {
auto b = ind[l_r].begin(), e = ind[l_r].end();
auto it = std::find(b, e, s);
if (it != e) return it - b;
}
TRIQS_RUNTIME_ERROR << "There are no string indices for this Green function";
}
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int version) { ar &TRIQS_MAKE_NVP("ind", ind); }
friend void h5_write(h5::group fg, std::string subgroup_name, indices_2 const &g) {
if (g.is_empty()) return;
auto gr = fg.create_group(subgroup_name);
h5_write(gr, "left", g.ind[0]);
h5_write(gr, "right", g.ind[1]);
}
friend void h5_read(h5::group fg, std::string subgroup_name, indices_2 &g) {
h5::group gr;
try {
gr = fg.open_group(subgroup_name);
}
catch (...) {
g = indices_2{}; // empty, no file
return;
}
h5_read(gr, "left", g.ind[0]);
h5_read(gr, "right", g.ind[1]);
}
};
// inline indices_2 slice(indices_2 const & ind, arrays::range rl, arrays::range rr) {
// return {};
// }
inline indices_2 slice(indices_2 const &ind, arrays::range rl, arrays::range rr) {
if (ind.is_empty()) return {};
return {}; // MODIFY : slice the indices !!!
TRIQS_RUNTIME_ERROR << "Not implemented : slice of string indices";
}
//------------------------------------------------------
@ -87,10 +154,12 @@ namespace gfs {
template <typename RHS> void operator=(RHS &&) {}
friend void h5_write(h5::group, std::string subgroup_name, nothing) {}
friend void h5_read(h5::group, std::string subgroup_name, nothing) {}
template <typename... A> friend nothing slice(nothing, A...) { return nothing(); }
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int version) {}
friend nothing operator+(nothing, nothing) { return nothing(); }
template <typename RHS> friend void assign_from_expression(nothing &, RHS) {}
template<typename A> bool check_size(A) {return true;}
};
template <typename... T> nothing slice_target(nothing, T...) { return nothing(); }