void inverse(gf_view<imtime,scalar_valued> gt, gf_view<imfreq,scalar_valued> const gw){
  using namespace impl_local_matsubara;
  static bool Green_Function_Are_Complex_in_time = false;
  // If the Green function are NOT complex, then one use the symmetry property
  // fold the sum and get a factor 2
  auto ta = gw(freq_infty());
  //TO BE MODIFIED AFTER SCALAR IMPLEMENTATION TODO
  dcomplex d= ta(1)(0,0), A= ta.get_or_zero(2)(0,0), B = ta.get_or_zero(3)(0,0);
  double b1, b2, b3;
  dcomplex a1, a2, a3;
  
  double beta=gw.domain().beta;
  size_t L= gt.mesh().size() - ( gt.mesh().kind() == full_bins ? 1 : 0); //L can be different from gt.mesh().size() (depending on the mesh kind) and is given to the FFT algorithm 
  dcomplex iomega = dcomplex(0.0,1.0) * std::acos(-1) / beta;
  dcomplex iomega2 = -iomega * 2 * gt.mesh().delta() * (gt.mesh().kind() == half_bins ? 0.5 : 0.0) ; 
  double fact = (Green_Function_Are_Complex_in_time ? 1 : 2)/beta;
  g_in.resize( gw.mesh().size());
  g_out.resize(gt.mesh().size());
  
  if (gw.domain().statistic == Fermion){
   b1 = 0; b2 =1; b3 =-1; 
   a1 = d-B; a2 = (A+B)/2; a3 = (B-A)/2; 
  }
  else { 
   b1 = -0.5; b2 =-1; b3 =1; 
   a1=4*(d-B)/3; a2=B-(d+A)/2; a3=d/6+A/2+B/3;
  }
  g_in() = 0;
  for (auto & w: gw.mesh()) {
   g_in[ w.index() ] =  fact * exp(w.index()*iomega2) * ( gw[w] - (a1/(w-b1) + a2/(w-b2) + a3/(w-b3)) );
  }
  // for bosons GF(w=0) is divided by 2 to avoid counting it twice
  if (gw.domain().statistic == Boson && !Green_Function_Are_Complex_in_time ) g_in(0) *= 0.5;
  
  details::fourier_base(g_in, g_out, L, false);
  
  // CORRECT FOR COMPLEX G(tau) !!!
  typedef double gt_result_type;
  //typedef typename gf<imtime>::mesh_type::gf_result_type gt_result_type;
  if (gw.domain().statistic == Fermion){
   for (auto & t : gt.mesh()){
    gt[t] = convert_green<gt_result_type> ( g_out( t.index() == L ? 0 : t.index() ) * exp(-iomega*t)
    + oneFermion(a1,b1,t,beta) + oneFermion(a2,b2,t,beta)+ oneFermion(a3,b3,t,beta) );
   }
  }
  else {
   for (auto & t : gt.mesh()) 
    gt[t] = convert_green<gt_result_type> ( g_out( t.index() == L ? 0 : t.index() )
    + oneBoson(a1,b1,t,beta) + oneBoson(a2,b2,t,beta) + oneBoson(a3,b3,t,beta) );
  }
  if (gt.mesh().kind() == full_bins)
   gt.on_mesh(L) = -gt.on_mesh(0)-convert_green<gt_result_type>(ta(1)(0,0));
  // set tail
   gt.singularity() = gw.singularity();
 }
Exemple #2
0
 void pade (gf_view<refreq> &gr, gf_view<imfreq> const &gw, int n_points, double freq_offset) {

  // make sure the GFs have the same structure
  //assert(gw.shape() == gr.shape());

  // copy the tail. it doesn't need to conform to the pade approximant
  gr.singularity() = gw.singularity();

  auto sh = gw.data().shape().front_pop();
  int N1 = sh[0], N2 = sh[1];
  for (int n1=0; n1<N1; n1++) {
    for (int n2=0; n2<N2; n2++) {

      arrays::vector<dcomplex> z_in(n_points); // complex points
      arrays::vector<dcomplex> u_in(n_points); // values at these points
      arrays::vector<dcomplex> a(n_points);    // corresponding Pade coefficients

      for (int i=0; i < n_points; ++i) z_in(i) = gw.mesh()[i];
      for (int i=0; i < n_points; ++i) u_in(i) = gw.on_mesh(i)(n1,n2);

      triqs::utility::pade_approximant PA(z_in,u_in);

      gr() = 0.0;
      for (auto om : gr.mesh()) {
        dcomplex e = om + dcomplex(0.0,1.0)*freq_offset;
        gr[om](n1,n2) = PA(e);
      }

    }
  }

 }