/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2012 by M. Ferrero, O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see .
*
******************************************************************************/
#pragma once
#include
#include "triqs/utility/complex_ops.hpp"
#include
#include
#include
#include
namespace triqs {
namespace gfs {
namespace mpl = boost::mpl;
namespace tag {
struct composite {};
struct mesh_point {};
}
// scalar_valued, matrix_valued, tensor_valued
struct scalar_valued {};
template struct tensor_valued {
static_assert(R > 0, "tensor_valued only for rank >0");
};
struct matrix_valued {};
//------------------------------------------------------
using dcomplex = std::complex;
/** The statistics : Boson or Fermion
*/
enum statistic_enum {
Boson,
Fermion
};
struct freq_infty {}; // the point at infinity
//------------------------------------------------------
template struct closest_pt_wrap;
template struct closest_pt_wrap : tag::mesh_point {
T value;
template explicit closest_pt_wrap(U &&x) : value(std::forward(x)) {}
};
template struct closest_pt_wrap : tag::mesh_point {
std::tuple value_tuple;
template explicit closest_pt_wrap(U &&... x) : value_tuple(std::forward(x)...) {}
};
template closest_pt_wrap closest_mesh_pt(T &&... x) {
return closest_pt_wrap{std::forward(x)...};
}
//------------------------------------------------------
// A simple indice struct
// Replace empty state by optional ?
struct indices_2 {
std::vector> ind;
indices_2() = default;
indices_2(std::vector> _ind) : ind(std::move(_ind)) {}
// from a size
indices_2(int L) : indices_2(arrays::mini_vector{L, L}) {};
// from a shape
indices_2(arrays::mini_vector const & shape) : ind(2) {
for (int i = 0; i < shape[0]; ++i) ind[0].push_back(std::to_string(i));
for (int i = 0; i < shape[1]; ++i) ind[1].push_back(std::to_string(i));
}
// indices from a vector : L and R are the same.
template indices_2(std::vector const & _ind) : ind(2) {
for (auto const &i : _ind) ind[0].push_back(std::to_string(i));
ind[1] = ind[0];
}
bool is_empty() const { return ind.size() == 0; }
void resize(int s) { ind.resize(s);}
template 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 operator[](int i) const {
if (is_empty())
return std::vector {};
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 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 = fg; // no default construction
try {
gr = fg.open_group(subgroup_name);
}
catch (...) {
g = indices_2{}; // empty, no file
return;
}
g.resize(2);
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";
}
inline indices_2 transpose(indices_2 const &x) {
auto ind2 = x.ind;
if (x.ind.size() > 0) {
int im = x.ind.size(), jm = x.ind[0].size();
for (int i = 0; i < im; ++i)
for (int j = 0; j < jm; ++j) ind2[i][j] = x.ind[j][i];
}
return indices_2(std::move(ind2));
}
//------------------------------------------------------
// A simple replacement of tail when there is none to maintain generic code simple...
struct nothing {
template explicit nothing(Args &&...) {} // takes anything, do nothing..
nothing() {}
using view_type = nothing;
using regular_type = nothing;
void rebind(nothing) {}
template 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 friend nothing slice(nothing, A...) { return nothing(); }
friend class boost::serialization::access;
template void serialize(Archive &ar, const unsigned int version) {}
friend nothing operator+(nothing, nothing) { return nothing(); }
template friend void assign_from_expression(nothing &, RHS) {}
template bool check_size(A) {return true;}
bool is_empty() const { return false;}
};
inline nothing transpose(nothing) { return {};}
inline nothing inverse(nothing) { return {};}
inline nothing conj(nothing) { return {};}
template nothing slice_target(nothing, T...) { return nothing(); }
template nothing operator+(nothing, T const &) { return nothing(); }
template nothing operator-(nothing, T const &) { return nothing(); }
template nothing operator*(nothing, T const &) { return nothing(); }
template nothing operator/(nothing, T const &) { return nothing(); }
template TYPE_DISABLE_IF(nothing, std::is_same) operator+(T const &, nothing) { return nothing(); }
template TYPE_DISABLE_IF(nothing, std::is_same) operator-(T const &, nothing) { return nothing(); }
template TYPE_DISABLE_IF(nothing, std::is_same) operator*(T const &, nothing) { return nothing(); }
template TYPE_DISABLE_IF(nothing, std::is_same) operator/(T const &, nothing) { return nothing(); }
}
}