ALPSCore reference
fourier.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 #pragma once
7 #include <alps/gf/gf.hpp>
8 
9 namespace alps {
10 namespace gf {
11 
12 inline std::complex<double> f_omega(double wn, double c1, double c2, double c3) {
13  std::complex<double> iwn(0., wn);
14  std::complex<double> iwnsq=iwn*iwn;
15  return c1/iwn + c2/(iwnsq) + c3/(iwn*iwnsq);
16 }
17 
18 inline double f_tau(double tau, double beta, double c1, double c2, double c3) {
19  return -0.5*c1 + (c2*0.25)*(-beta+2.*tau) + (c3*0.25)*(beta*tau-tau*tau);
20 }
21 
23 inline void transform_vector_no_tail(const std::vector<std::complex<double> >&input_data, const std::vector<double> &omega, std::vector<double> &output_data, const std::vector<double> &tau, double beta){
24  for (unsigned int i=0; i<output_data.size(); ++i) {
25  output_data[i] = 0.;
26  for (unsigned int k=0; k<input_data.size(); ++k) {
27  double wt=omega[k]*tau[i];
28  output_data[i]+= 2/beta*(cos(wt)*input_data[k].real()+sin(wt)*input_data[k].imag());
29  }
30  }
31 }
33 template<class MESH1> void fourier_frequency_to_time(const two_index_gf_with_tail<
34  two_index_gf<std::complex<double>, matsubara_positive_mesh, MESH1>, one_index_gf<double, MESH1> > &g_omega,
36 
37  std::vector<std::complex<double> > input_data(g_omega.mesh1().extent(), 0.);
38  std::vector<double > output_data(g_tau.mesh1().extent(), 0.);
39 
40  for(int i=0;i<g_omega.mesh2().extent();++i){
41  double c0=(g_omega.min_tail_order()==0 && g_omega.max_tail_order()>=0 )? g_omega.tail(0)(typename MESH1::index_type(i)):0;
42  double c1=(g_omega.min_tail_order()<=1 && g_omega.max_tail_order()>=1 )? g_omega.tail(1)(typename MESH1::index_type(i)):0;
43  double c2=(g_omega.min_tail_order()<=2 && g_omega.max_tail_order()>=2 )? g_omega.tail(2)(typename MESH1::index_type(i)):0;
44  double c3=(g_omega.min_tail_order()<=3 && g_omega.max_tail_order()>=3 )? g_omega.tail(3)(typename MESH1::index_type(i)):0;
45  if(c0 != 0) throw std::runtime_error("attempt to Fourier transform an object which goes to a constant. FT is ill defined");
46  for(int n=0;n<g_omega.mesh1().extent();++n){
47  input_data[n]=g_omega(matsubara_index(n),typename MESH1::index_type(i))-f_omega(g_omega.mesh1().points()[n],c1,c2,c3);
48  }
49  transform_vector_no_tail(input_data,g_omega.mesh1().points(), output_data, g_tau.mesh1().points(), g_tau.mesh1().beta());
50  for(int t=0;t<g_tau.mesh1().extent();++t){
51  g_tau(itime_index(t),typename MESH1::index_type(i))=output_data[t]+f_tau(g_tau.mesh1().points()[t],g_tau.mesh1().beta(),c1,c2,c3);
52  }
53  }
54 }
56 template<class MESH1, class MESH2> void fourier_frequency_to_time(const three_index_gf_with_tail<
57  three_index_gf<std::complex<double>, matsubara_positive_mesh, MESH1,MESH2>, two_index_gf<double, MESH1,MESH2> > &g_omega,
59 
60  std::vector<std::complex<double> > input_data(g_omega.mesh1().extent(), 0.);
61  std::vector<double > output_data(g_tau.mesh1().extent(), 0.);
62 
63  for(int i=0;i<g_omega.mesh2().extent();++i){
64  for(int j=0;j<g_omega.mesh3().extent();++j){
65  double c0=(g_omega.min_tail_order()==0 && g_omega.max_tail_order()>=0 )? g_omega.tail(0)(typename MESH1::index_type(i),typename MESH2::index_type(j)):0;
66  double c1=(g_omega.min_tail_order()<=1 && g_omega.max_tail_order()>=1 )? g_omega.tail(1)(typename MESH1::index_type(i),typename MESH2::index_type(j)):0;
67  double c2=(g_omega.min_tail_order()<=2 && g_omega.max_tail_order()>=2 )? g_omega.tail(2)(typename MESH1::index_type(i),typename MESH2::index_type(j)):0;
68  double c3=(g_omega.min_tail_order()<=3 && g_omega.max_tail_order()>=3 )? g_omega.tail(3)(typename MESH1::index_type(i),typename MESH2::index_type(j)):0;
69  if(c0 != 0) throw std::runtime_error("attempt to Fourier transform an object which goes to a constant. FT is ill defined");
70  for(int n=0;n<g_omega.mesh1().extent();++n){
71  input_data[n]=g_omega(matsubara_index(n),typename MESH1::index_type(i),typename MESH2::index_type(j))-f_omega(g_omega.mesh1().points()[n],c1,c2,c3);
72  }
73  transform_vector_no_tail(input_data,g_omega.mesh1().points(), output_data, g_tau.mesh1().points(), g_tau.mesh1().beta());
74  for(int t=0;t<g_tau.mesh1().extent();++t){
75  g_tau(itime_index(t),typename MESH1::index_type(i),typename MESH2::index_type(j))=output_data[t]+f_tau(g_tau.mesh1().points()[t],g_tau.mesh1().beta(),c1,c2,c3);
76  }
77  }
78  }
79 }
81 template<class MESH1, class MESH2, class MESH3> void fourier_frequency_to_time(const four_index_gf_with_tail<
82  four_index_gf<std::complex<double>, matsubara_positive_mesh, MESH1,MESH2,MESH3>, three_index_gf<double, MESH1,MESH2,MESH3> > &g_omega,
84 
85  std::vector<std::complex<double> > input_data(g_omega.mesh1().extent(), 0.);
86  std::vector<double > output_data(g_tau.mesh1().extent(), 0.);
87 
88  for(int i=0;i<g_omega.mesh2().extent();++i){
89  for(int j=0;j<g_omega.mesh3().extent();++j){
90  for(int k=0;k<g_omega.mesh4().extent();++k){
91  double c0=(g_omega.min_tail_order()==0 && g_omega.max_tail_order()>=0 )? g_omega.tail(0)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k)):0;
92  double c1=(g_omega.min_tail_order()<=1 && g_omega.max_tail_order()>=1 )? g_omega.tail(1)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k)):0;
93  double c2=(g_omega.min_tail_order()<=2 && g_omega.max_tail_order()>=2 )? g_omega.tail(2)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k)):0;
94  double c3=(g_omega.min_tail_order()<=3 && g_omega.max_tail_order()>=3 )? g_omega.tail(3)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k)):0;
95  if(c0 != 0) throw std::runtime_error("attempt to Fourier transform an object which goes to a constant. FT is ill defined");
96  for(int n=0;n<g_omega.mesh1().extent();++n){
97  input_data[n]=g_omega(matsubara_index(n),typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k))-f_omega(g_omega.mesh1().points()[n],c1,c2,c3);
98  }
99  transform_vector_no_tail(input_data,g_omega.mesh1().points(), output_data, g_tau.mesh1().points(), g_tau.mesh1().beta());
100  for(int t=0;t<g_tau.mesh1().extent();++t){
101  g_tau(itime_index(t),typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k))=output_data[t]+f_tau(g_tau.mesh1().points()[t],g_tau.mesh1().beta(),c1,c2,c3);
102  }
103  }
104  }
105  }
106 }
108 template<class MESH1, class MESH2, class MESH3,class MESH4> void fourier_frequency_to_time(const five_index_gf_with_tail<
109  five_index_gf<std::complex<double>, matsubara_positive_mesh, MESH1,MESH2,MESH3,MESH4>, four_index_gf<double, MESH1,MESH2,MESH3,MESH4> > &g_omega,
111 
112  std::vector<std::complex<double> > input_data(g_omega.mesh1().extent(), 0.);
113  std::vector<double > output_data(g_tau.mesh1().extent(), 0.);
114 
115  for(int i=0;i<g_omega.mesh2().extent();++i){
116  for(int j=0;j<g_omega.mesh3().extent();++j){
117  for(int k=0;k<g_omega.mesh4().extent();++k){
118  for(int l=0;l<g_omega.mesh5().extent();++l){
119  double c0=(g_omega.min_tail_order()==0 && g_omega.max_tail_order()>=0 )? g_omega.tail(0)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k),typename MESH4::index_type(l)):0;
120  double c1=(g_omega.min_tail_order()<=1 && g_omega.max_tail_order()>=1 )? g_omega.tail(1)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k),typename MESH4::index_type(l)):0;
121  double c2=(g_omega.min_tail_order()<=2 && g_omega.max_tail_order()>=2 )? g_omega.tail(2)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k),typename MESH4::index_type(l)):0;
122  double c3=(g_omega.min_tail_order()<=3 && g_omega.max_tail_order()>=3 )? g_omega.tail(3)(typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k),typename MESH4::index_type(l)):0;
123  if(c0 != 0) throw std::runtime_error("attempt to Fourier transform an object which goes to a constant. FT is ill defined");
124  for(int n=0;n<g_omega.mesh1().extent();++n){
125  input_data[n]=g_omega(matsubara_index(n),typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k),typename MESH4::index_type(l))-f_omega(g_omega.mesh1().points()[n],c1,c2,c3);
126  }
127  transform_vector_no_tail(input_data,g_omega.mesh1().points(), output_data, g_tau.mesh1().points(), g_tau.mesh1().beta());
128  for(int t=0;t<g_tau.mesh1().extent();++t){
129  g_tau(itime_index(t),typename MESH1::index_type(i),typename MESH2::index_type(j),typename MESH3::index_type(k),typename MESH4::index_type(l))=output_data[t]+f_tau(g_tau.mesh1().points()[t],g_tau.mesh1().beta(),c1,c2,c3);
130  }
131  }
132  }
133  }
134  }
135 }
136 
137 }
138 } // end alps::
greenf< VTYPE, MESH1, MESH2, MESH3, MESH4, MESH5 > five_index_gf
Definition: gf.hpp:25
greenf< VTYPE, MESH1 > one_index_gf
Definition: gf.hpp:17
boost::array< T, N > cos(boost::array< T, N > arg)
std::complex< double > f_omega(double wn, double c1, double c2, double c3)
Definition: fourier.hpp:12
gf_tail< GFT, TAILT > three_index_gf_with_tail
Definition: gf.hpp:61
greenf< VTYPE, MESH1, MESH2, MESH3 > three_index_gf
Definition: gf.hpp:21
void fourier_frequency_to_time(const two_index_gf_with_tail< two_index_gf< std::complex< double >, matsubara_positive_mesh, MESH1 >, one_index_gf< double, MESH1 > > &g_omega, two_index_gf_with_tail< two_index_gf< double, itime_mesh, MESH1 >, one_index_gf< double, MESH1 > > &g_tau)
Fourier transform a two-index matsubara gf to an imag time gf.
Definition: fourier.hpp:33
itime_mesh::index_type itime_index
Definition: mesh.hpp:1244
gf_tail< GFT, TAILT > four_index_gf_with_tail
Definition: gf.hpp:63
void transform_vector_no_tail(const std::vector< std::complex< double > > &input_data, const std::vector< double > &omega, std::vector< double > &output_data, const std::vector< double > &tau, double beta)
Fourier transform kernel of the omega -> tau transform.
Definition: fourier.hpp:23
gf_tail< GFT, TAILT > five_index_gf_with_tail
Definition: gf.hpp:65
matsubara_mesh< mesh::POSITIVE_ONLY >::index_type matsubara_index
Definition: mesh.hpp:1242
greenf< VTYPE, MESH1, MESH2 > two_index_gf
Definition: gf.hpp:19
boost::array< T, N > sin(boost::array< T, N > arg)
greenf< VTYPE, MESH1, MESH2, MESH3, MESH4 > four_index_gf
Definition: gf.hpp:23
double f_tau(double tau, double beta, double c1, double c2, double c3)
Definition: fourier.hpp:18
gf_tail< GFT, TAILT > two_index_gf_with_tail
Definition: gf.hpp:59