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();
 }
 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());
 }
Exemple #3
0
 // compute a tail from the Legendre GF
 // this is Eq. 8 of our paper
 local::tail_view get_tail(gf_view<legendre> const & gl, int size = 10, int omin = -1) {

   auto sh = gl.data().shape().front_pop();
   local::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;

 }
Exemple #4
0
 tqa::matrix<double> density( gf_view<legendre> const & gl) { 

   auto sh = gl.data().shape().front_pop();
   tqa::matrix<double> res(sh);
   res() = 0.0;

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

   return res;

 }
 void direct (gf_view<imfreq,scalar_valued> gw, gf_view<imtime,scalar_valued> const gt) {
  using namespace impl_local_matsubara;
  auto ta = gt(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=0, b2=0, b3=0;
  dcomplex a1, a2, a3;
  double beta=gt.mesh().domain().beta;
  auto L = ( gt.mesh().kind() == full_bins ? gt.mesh().size()-1 : gt.mesh().size());
  double fact= beta/ gt.mesh().size();
  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);
  g_in.resize(gt.mesh().size());
  g_out.resize(gw.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; 
  }
  if (gw.domain().statistic == Fermion){
   for (auto & t : gt.mesh())  
    g_in[t.index()] = fact * exp(iomega*t) * ( gt[t] - ( oneFermion(a1,b1,t,beta) + oneFermion(a2,b2,t,beta)+ oneFermion(a3,b3,t,beta) ) );
  }
  else {
   for (auto & t : gt.mesh()) 
    g_in[t.index()] =  fact * ( gt[t] -  ( oneBoson(a1,b1,t,beta) + oneBoson(a2,b2,t,beta) + oneBoson(a3,b3,t,beta) ) );  
  }
  details::fourier_base(g_in, g_out, L, true);
  for (auto & w : gw.mesh()) {
   gw[w] = g_out( w.index() ) * exp(iomega2*w.index() ) + a1/(w-b1) + a2/(w-b2) + a3/(w-b3); 
  }
  gw.singularity() = gt.singularity();// set tail
 }
Exemple #6
0
 // Impose a discontinuity G(\tau=0)-G(\tau=\beta)
 void enforce_discontinuity(gf_view<legendre> & gl, arrays::array_view<double,2> disc) {

   double norm = 0.0;
   arrays::vector<double> t(gl.data().shape()[0]);
   for (int i=0; i<t.size(); ++i) {
     t(i) = triqs::utility::legendre_t(i,1) / gl.domain().beta;
     norm += t(i)*t(i);
   }

   arrays::array<dcomplex, 2> corr(disc.shape());
   corr() = 0;
   for (auto const &l : gl.mesh()) corr += t(l.index()) * gl[l];

   auto _ = arrays::range{};
   for (auto const& l : gl.mesh()) gl.data()(l.index(), _, _) += (disc - corr) * t(l.index()) / norm;
 }
Exemple #7
0
 // Impose a discontinuity G(\tau=0)-G(\tau=\beta)
 void enforce_discontinuity(gf_view<legendre> & gl, tqa::array_view<double,2> disc) {

   double norm = 0.0;
   tqa::vector<double> t(gl.data().shape()[0]);
   for (int i=0; i<t.size(); ++i) {
     t(i) = triqs::utility::legendre_t(i,1) / gl.domain().beta;
     norm += t(i)*t(i);
   }

   tqa::array<double,2> corr(disc.shape()); corr() = 0;
   for (auto l : gl.mesh()) {
     corr += t(l.index()) * gl[l];
   }

   tqa::range R;
   for (auto l : gl.mesh()) {
     gl.data()(l.index(),R,R) += (disc - corr) * t(l.index()) / norm;
   }

 }
Exemple #8
0
 //-------------------------------------------------------
 // For Imaginary Matsubara Frequency functions
 // ------------------------------------------------------
 tqa::matrix<double> density( gf_view<imfreq> const & G) { 
  dcomplex I(0,1);
  auto sh = G.data().shape().front_pop();
  auto Beta = G.domain().beta;
  local::tail_view t = G(freq_infty());
  if (!t.is_decreasing_at_infinity())  TRIQS_RUNTIME_ERROR<<" density computation : Green Function is not as 1/omega or less !!!";
  const size_t N1=sh[0], N2 = sh[1];
  tqa::array<dcomplex,2> dens_part(sh), dens_tail(sh), dens(sh);
  tqa::matrix<double> res(sh);
  dens_part()=0;dens()=0;dens_tail()=0;
  for (size_t n1=0; n1<N1;n1++) 
   for (size_t n2=0; n2<N2;n2++) {
    dcomplex d= t(1)(n1,n2) , A=t(2)(n1,n2),B = t(3)(n1,n2) ;
    double b1 = 0,b2 =1, b3 =-1;
    dcomplex a1 = d-B, a2 = (A+B)/2, a3 = (B-A)/2;
    for (auto & w : G.mesh())  dens_part(n1,n2)+= G[w](n1,n2)  -  (a1/(w - b1) + a2 / (w-b2) + a3/(w-b3)); 
    dens_part(n1,n2) = dens_part(n1,n2)/Beta;
    dens_tail(n1,n2) = d + F(a1,b1,Beta) + F(a2,b2,Beta)+ F(a3,b3,Beta);
    // If  the Green function are NOT complex, then one use the symmetry property
    // fold the sum and get a factor 2
    //double fact = (Green_Function_Are_Complex_in_time ? 1 : 2);
    //dens_part(n1,n2) = dens_part(n1,n2)*(fact/Beta)  + (d + F(a1,b1,Beta) + F(a2,b2,Beta)+ F(a3,b3,Beta));
    //if (!Green_Function_Are_Complex_in_time) dens_part  = 0+real(dens_part);
   }

  for (size_t n1=0; n1<N1;n1++) 
   for (size_t n2=0; n2<N2;n2++) {
    dens_part(n1,n2) = dens_part(n1,n2) + real(dens_part(n2,n1)) - I * imag(dens_part(n2,n1)) + dens_tail(n1,n2);
    // ?? STRANGE ??
    dens_part(n2,n1) = real(dens_part(n1,n2)) - I * imag(dens_part(n1,n2));
   }

  for (size_t n1=0; n1<N1;n1++) 
   for (size_t n2=0; n2<N2;n2++) {
    res(n1,n2) = real(dens_part(n1,n2));
   }

  return res;
 }