예제 #1
0
파일: som_core.cpp 프로젝트: krivenko/som
void check_input_gf(gf_const_view<GfOpts...> g, gf_const_view<GfOpts...> S) {
 if(g.mesh() != S.mesh() || get_target_shape(g) != get_target_shape(S))
  fatal_error("input quantity and the error-bar function S must have equivalent structure");

 auto shape = get_target_shape(g);
 if(shape[0] != shape[1]) fatal_error("matrix-valued input quantities must be square");
}
예제 #2
0
 gf<imfreq, T, S> make_gf_from_fourier(gf_const_view<imtime, T, S, E> const& gt, int n_iw = -1) {
  if (n_iw == -1) n_iw = (gt.mesh().size() - 1) / 2;
  auto m = gf_mesh<imfreq>{gt.mesh().domain(), n_iw};
  auto gw = gf<imfreq, T, S>{m, get_target_shape(gt)};
  gw() = fourier(gt);
  return gw;
 }
예제 #3
0
파일: imfreq.hpp 프로젝트: MHarland/triqs
 bool is_gf_real_in_tau(gf_const_view<imfreq, T, S, E> g, double tolerance = 1.e-13) {
  if (g.mesh().positive_only()) return true;
  using triqs::arrays::max_element; // the case real, complex is not found by ADL
  for (auto const &w : g.mesh().get_positive_freq())
   if (max_element(abs(conj(g(-w)) - g(w))) > tolerance) return false;
  return true;
 }
예제 #4
0
 //-------------------------------------------------------
 // For Imaginary Matsubara Frequency functions
 // ------------------------------------------------------
 arrays::matrix<dcomplex> density(gf_const_view<imfreq> g) {

  if (g.mesh().positive_only())
   TRIQS_RUNTIME_ERROR << "density is only implemented for g(i omega_n) with full mesh (positive and negative frequencies)";

  tail_const_view t = g.singularity();
  if (!t.is_decreasing_at_infinity())
   TRIQS_RUNTIME_ERROR << " density computation : green Function is not as 1/omega or less !!!";

  if (g.mesh().positive_only()) TRIQS_RUNTIME_ERROR << " imfreq gF : full mesh required in density computation";
  auto sh = get_target_shape(g);
  int N1 = sh[0], N2 = sh[1];
  arrays::matrix<dcomplex> res(sh);
  auto beta = g.domain().beta;
  double b1 = 0, b2 = 1, b3 = -1;
  auto F = [&beta](dcomplex a, double b) { return -a / (1 + exp(-beta * b)); };

  for (int n1 = 0; n1 < N1; n1++)
   for (int n2 = n1; n2 < N2; n2++) {
    dcomplex d = t(1)(n1, n2), A = t(2)(n1, n2), B = t(3)(n1, n2);
    dcomplex a1 = d - B, a2 = (A + B) / 2, a3 = (B - A) / 2;
    dcomplex r = 0;
    for (auto const& w : g.mesh()) r += g[w](n1, n2) - (a1 / (w - b1) + a2 / (w - b2) + a3 / (w - b3));
    res(n1, n2) = r / beta + d + F(a1, b1) + F(a2, b2) + F(a3, b3);
    if (n2 > n1) res(n2, n1) = conj(res(n1, n2));
   }

  return res;
 }
예제 #5
0
 gf<imtime, T, S> make_gf_from_inverse_fourier(gf_const_view<imfreq, T, S, E> const& gw, int n_tau = -1) {
  if (n_tau == -1) n_tau = 2*(gw.mesh().last_index() + 1) +1;
  auto m = gf_mesh<imtime>{gw.mesh().domain(), n_tau};
  auto gt = gf<imtime, T, S, E>{m, get_target_shape(gw)};
  gt() = inverse_fourier(gw);
  return gt;
 }
예제 #6
0
 //-------------------------------------------------------
 arrays::matrix<dcomplex> density(gf_const_view<legendre> gl) {
  arrays::matrix<dcomplex> res(get_target_shape(gl));
  res() = 0.0;
  for (auto const& l : gl.mesh()) res -= sqrt(2 * l.index() + 1) * gl[l];
  res /= gl.domain().beta;
  return res;
 }
예제 #7
0
파일: legendre.cpp 프로젝트: TRIQS/triqs
    // compute a tail from the Legendre GF
    // this is Eq. 8 of our paper
    array<dcomplex, 3> get_tail(gf_const_view<legendre> gl, int order) {

      auto _  = ellipsis{};
      auto sh = gl.data().shape();
      sh[0]   = order;
      array<dcomplex, 3> t{sh};
      t() = 0.0;

      for (int p = 0; p < order; p++)
        for (auto l : gl.mesh()) t(p, _) += (triqs::utility::legendre_t(l.index(), p) / std::pow(gl.domain().beta, p)) * gl[l];

      return t;
    }
예제 #8
0
 // compute a tail from the Legendre GF
 // this is Eq. 8 of our paper
 tail_view get_tail(gf_const_view<legendre> gl, int size = 10, int omin = -1) {

   auto sh = gl.data().shape().front_pop();
   tail t(sh, size, omin);
   t.data()() = 0.0;

   for (int p=1; p<=t.order_max(); p++)
     for (auto l : gl.mesh())
       t(p) += (triqs::utility::legendre_t(l.index(),p)/pow(gl.domain().beta,p)) * gl[l];

   return t;

 }
예제 #9
0
 void legendre_matsubara_inverse(gf_view<legendre> gl, gf_const_view<imfreq> gw) {

  gl() = 0.0;

  // Construct a temporary imaginary-time Green's function gt
  // I set Nt time bins. This is ugly, one day we must code the direct
  // transformation without going through imaginary time
  int Nt = 50000;
  auto gt = gf<imtime>{{gw.domain(), Nt}, gw.data().shape().front_pop()};

  // We first transform to imaginary time because it's been coded with the knowledge of the tails
  gt() = inverse_fourier(gw);
  legendre_matsubara_inverse(gl, gt());
 }
예제 #10
0
gf<imtime> change_mesh(gf_const_view<imtime> old_gf, int new_n_tau) {
    auto const& old_m = old_gf.mesh();
    gf<imtime> new_gf{{old_m.domain().beta, old_m.domain().statistic, new_n_tau, old_m.kind()}, get_target_shape(old_gf)};
    auto const& new_m = new_gf.mesh();

    new_gf.data()() = 0;
    double f = old_m.delta()/new_m.delta();
    for(auto tau : old_m) new_gf[closest_mesh_pt(double(tau))] += f*old_gf[tau];
    new_gf[0] *= 2.0; new_gf[new_n_tau-1] *= 2.0;

    new_gf.singularity() = old_gf.singularity();

    return new_gf;
}
예제 #11
0
파일: som_core.cpp 프로젝트: krivenko/som
void som_core::set_input_data(gf_const_view<GfOpts...> g, gf_const_view<GfOpts...> S) {
 using mesh_t = typename gf_const_view<GfOpts...>::mesh_t;

 auto & rhs_ = (input_data_t<mesh_t>&)rhs;
 auto & error_bars_ = (input_data_t<mesh_t>&)error_bars;
 auto gf_dim = get_target_shape(g)[0];

 results.reserve(gf_dim);
 for(int i = 0; i < gf_dim; ++i) {
  rhs_.emplace_back(g.data()(range(),i,i));
  error_bars_.emplace_back(S.data()(range(),i,i));
  results.emplace_back(ci);
 }
 histograms.resize(gf_dim);
}
예제 #12
0
 static void write(h5::group gr, gf_const_view<block_index2, Target> g) {
  auto const &m0 = std::get<0>(g.mesh());
  auto const &m1 = std::get<1>(g.mesh());
  for (int i = 0; i < m0.size(); ++i)
   for (int j = 0; j < m1.size(); ++j) h5_write(gr, m0.domain().names()[i] + "_" + m1.domain().names()[j], g._data[i][j]);
  h5_write(gr, "block_names", m0.domain().names());
 }
예제 #13
0
파일: som_core.cpp 프로젝트: krivenko/som
template<typename MeshType> void check_gf_stat(gf_const_view<MeshType> g,
                                               triqs::gfs::statistic_enum expected_stat) {
 if(g.domain().statistic != expected_stat)
  fatal_error("expected a " + mesh_traits<MeshType>::name()
              + " Green's function with "
              + (expected_stat == Fermion ? "fermionic" : "bosonic")
              + " statistics");
}
예제 #14
0
파일: imfreq.hpp 프로젝트: MHarland/triqs
 // This function takes a g(i omega_n) on half mesh (positive omega_n) and returns a gf on the whole mesh
 // using G(-i omega_n) = G(i omega_n)^* for real G(tau) functions.
 template <typename T, typename S, typename E> gf<imfreq, T, S, E> make_gf_from_real_gf(gf_const_view<imfreq, T, S, E> g) {
  if (!g.mesh().positive_only()) TRIQS_RUNTIME_ERROR << "gf imfreq is not for omega_n >0, real_to_complex does not apply";
  auto const &dat = g.data();
  auto sh = dat.shape();
  int is_boson = (g.mesh().domain().statistic == Boson);
  long L = sh[0];
  sh[0] = 2 * sh[0] - is_boson;
  array<dcomplex, std14::decay_t<decltype(dat)>::rank> new_data(sh);
  auto _ = arrays::ellipsis{};
  if (is_boson) new_data(L - 1, _) = dat(0, _);
  int L1 = (is_boson ? L - 1 : L);
  for (int u = is_boson; u < L; ++u) {
   new_data(L1 + u, _) = dat(u, _);
   new_data(L - 1 - u, _) = conj(dat(u, _));
  }
  return {gf_mesh<imfreq>{g.mesh().domain(), L}, std::move(new_data), g.singularity(), g.symmetry(), g.indices(), g.name};
 }
예제 #15
0
 void legendre_matsubara_inverse(gf_view<legendre> gl, gf_const_view<imtime> gt) {

  gl() = 0.0;
  legendre_generator L;
  auto N = gt.mesh().size() - 1;
  double coef;

  // Do the integral over imaginary time
  for (auto t : gt.mesh()) {
   if (t.index()==0 || t.index()==N) coef = 0.5;
   else coef = 1.0;
   L.reset(2 * t / gt.domain().beta - 1);
   for (auto l : gl.mesh()) {
    gl[l] += coef * sqrt(2 * l.index() + 1) * L.next() * gt[t];
   }
  }
  gl.data() *= gt.mesh().delta();
 }
예제 #16
0
 //-------------------------------------------------------
 // For Imaginary Time functions
 // ------------------------------------------------------
 gf<imtime> rebinning_tau(gf_const_view<imtime> const& g, int new_n_tau) {

  auto const& old_m = g.mesh();
  gf<imtime> new_gf{{old_m.domain().beta, old_m.domain().statistic, new_n_tau}, get_target_shape(g)};
  auto const& new_m = new_gf.mesh();
  new_gf.data()() = 0;
  long prev_index = 0;
  long norm = 0;
  for (auto const & tau : old_m) {
   long index = std::round((double(tau) - new_m.x_min()) / new_m.delta());
   if (index == prev_index) { norm++; } else {
    new_gf[index - 1] /= double(norm);
    prev_index = index;
    norm = 1;
   }
   new_gf[index] += g[tau];
  }
  if (norm != 1) new_gf[new_m.size() - 1] /= norm;
  new_gf.singularity() = g.singularity();
  return new_gf;
 }
예제 #17
0
파일: som_core.cpp 프로젝트: krivenko/som
// Legendre coefficients
som_core::som_core(gf_const_view<legendre> g_l, gf_const_view<legendre> S_l,
                   observable_kind kind, vector<double> const& norms) :
 mesh(g_l.mesh()), kind(kind), norms(make_default_norms(norms,get_target_shape(g_l)[0])),
 rhs(input_data_r_t()), error_bars(input_data_r_t()) {

 if(is_stat_relevant(kind)) check_gf_stat(g_l, observable_statistics(kind));

 check_input_gf(g_l,S_l);
 if(!is_gf_real(g_l) || !is_gf_real(S_l))
  fatal_error("Legendre " + observable_name(kind) + " must be real");
 gf<legendre, matrix_real_valued> g_l_real = real(g_l), S_l_real = real(S_l);
 set_input_data(make_const_view(g_l_real), make_const_view(S_l_real));
}
예제 #18
0
 void legendre_matsubara_direct(gf_view<imtime> gt, gf_const_view<legendre> gl) {

  gt() = 0.0;
  legendre_generator L;

  for (auto t : gt.mesh()) {
   L.reset(2 * t / gt.domain().beta - 1);
   for (auto l : gl.mesh()) {
    gt[t] += sqrt(2 * l.index() + 1) / gt.domain().beta * gl[l] * L.next();
   }
  }

  gt.singularity() = get_tail(gl, gt.singularity().size(), gt.singularity().order_min());
 }
예제 #19
0
 void legendre_matsubara_direct(gf_view<imfreq> gw, gf_const_view<legendre> gl) {

  gw() = 0.0;
  triqs::arrays::range R;

  // Use the transformation matrix
  for (auto om : gw.mesh()) {
   for (auto l : gl.mesh()) {
    gw[om] += legendre_T(om.index(), l.index()) * gl[l];
   }
  }

  gw.singularity() = get_tail(gl, gw.singularity().size(), gw.singularity().order_min());
 }
예제 #20
0
파일: som_core.cpp 프로젝트: krivenko/som
// Imaginary frequency
som_core::som_core(gf_const_view<imfreq> g_iw, gf_const_view<imfreq> S_iw,
                   observable_kind kind, vector<double> const& norms) :
 mesh(g_iw.mesh()), kind(kind), norms(make_default_norms(norms,get_target_shape(g_iw)[0])),
 rhs(input_data_c_t()), error_bars(input_data_c_t()) {

 if(is_stat_relevant(kind)) check_gf_stat(g_iw, observable_statistics(kind));

 check_input_gf(g_iw,S_iw);
 if(!is_gf_real_in_tau(g_iw) || !is_gf_real_in_tau(S_iw))
  fatal_error("imaginary frequency " + observable_name(kind) + " must be real in \\tau-domain");
 auto g_iw_pos = positive_freq_view(g_iw);
 auto S_iw_pos = positive_freq_view(S_iw);
 check_input_gf(g_iw_pos,S_iw_pos);
 set_input_data(g_iw_pos,S_iw_pos);
}
예제 #21
0
 template <typename F, typename G> gf<block_index, std14::result_of_t<F(G)>> map(F &&f, gf_const_view<block_index, G> g) {
  return make_block_gf(get_block_names(g), _map(f, g.data()));
 }
예제 #22
0
파일: block.hpp 프로젝트: EBRUDU1/triqs
 static void write(h5::group gr, gf_const_view<block_index, Target, Opt> g) {
  for (size_t i = 0; i < g.mesh().size(); ++i) h5_write(gr, g.mesh().domain().names()[i], g._data[i]);
  // h5_write(gr,"symmetry",g._symmetry);
 }
예제 #23
0
 static void write(h5::group gr, gf_const_view<block_index, Target> g) {
  for (size_t i = 0; i < g.mesh().size(); ++i) h5_write(gr, g.mesh().domain().names()[i], g._data[i]);
  h5_write(gr, "block_names", g.mesh().domain().names());
 }
예제 #24
0
 gf<retime, Target, Singularity> make_gf_from_inverse_fourier(gf_const_view<refreq, Target, Singularity, Evaluator> const& gw) {
  auto gt = gf<retime, Target>{make_mesh_fourier_compatible(gw.mesh()), get_target_shape(gw)};
  gt() = inverse_fourier(gw);
  return gt;
 }
예제 #25
0
 gf<refreq, Target, Singularity> make_gf_from_fourier(gf_const_view<retime, Target, Singularity, Evaluator> const& gt) {
  auto gw = gf<refreq, Target>{make_mesh_fourier_compatible(gt.mesh()), get_target_shape(gt)};
  gw() = fourier(gt);
  return gw;
 }
예제 #26
0
 /// Takes the real part of g without check, and returns a new gf with a real target
 template <typename M, typename T, typename S, typename E> gf<M, real_target_t<T>, S> real(gf_const_view<M, T, S, E> g) {
  return {g.mesh(), real(g.data()), g.singularity(), g.symmetry(), {}, {}}; // no indices for real_valued, internal C++ use only
 }