mirror of
https://github.com/triqs/dft_tools
synced 2024-12-25 05:43:40 +01:00
gf. Clean Fourier
- lazy_fourier and co --> fourier - ex fourier --> make_gf_from_fourier to make a new gf - = fourier (g) works only iif lhs is a view, like scalar. - updated python (commented fourier method).
This commit is contained in:
parent
1d5ea99d4f
commit
579368f24b
48
doc/reference/c++/gf/clef.rst
Normal file
48
doc/reference/c++/gf/clef.rst
Normal file
@ -0,0 +1,48 @@
|
||||
.. highlight:: c
|
||||
|
||||
.. _gf_clef:
|
||||
|
||||
Interaction with CLEF expressions
|
||||
============================================
|
||||
|
||||
* The gf containers and their view classes can be used with the :doc:`../clef/contents` library :
|
||||
|
||||
* They can be called with CLEF expressions.
|
||||
* :doc:`Automatic assignment<../clef/assign>` has been set up.
|
||||
|
||||
* Using the CLEF library offers a quick and efficient way to fill an array with multiple advantages :
|
||||
|
||||
* It is simpler and more readeable than a series of for loops.
|
||||
* It is usually more optimal since the for loops are automatically written in the TraversalOrder of the array.
|
||||
|
||||
|
||||
* **Example** :
|
||||
|
||||
.. compileblock::
|
||||
|
||||
#include <triqs/gfs.hpp>
|
||||
using namespace triqs::gfs; using triqs::clef::placeholder;
|
||||
int main(){
|
||||
|
||||
// Cf gf<imfreq> specialisation page for the constructor
|
||||
double beta=10; int Nfreq =100;
|
||||
auto g = gf<imfreq> { {beta,Fermion,Nfreq}, {1,1} };
|
||||
|
||||
// Filling the gf with something...
|
||||
placeholder<0> wn_;
|
||||
g(wn_) << 1/ (wn_ + 2);
|
||||
g(wn_) << 1/ (wn_ + 2 + g(wn_) );
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
The syntax uses a <<, not = since the array is not assigned to an expression
|
||||
but filled by the evaluation thereof.
|
||||
|
||||
The LHS uses () and not brackets, even though it is on the mesh, because of the strange C++ limitation
|
||||
that [] can not be overloaded for several variables...
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,151 +3,78 @@
|
||||
Fourier transforms
|
||||
###################
|
||||
|
||||
The Fourier transforms from real and imaginary frequencies to times, and inverse, are currently implemented,
|
||||
along with the analogous transformation from the Legendre expansion to imaginary time and frequencies.
|
||||
|
||||
Synopsis and example
|
||||
======================
|
||||
|
||||
**Synopsis** ::
|
||||
|
||||
lazy_object fourier (gf<imfreq,Target,Opt> const &)
|
||||
lazy_object fourier (gf_const_view<imfreq,Target,Opt> const &)
|
||||
|
||||
lazy_object inverse_fourier (gf<imfreq,Target,Opt> const &)
|
||||
lazy_object inverse_fourier (gf_const_view<imfreq,Target,Opt> const &)
|
||||
|
||||
The fourier/inverse_fourier functions do **not** perform the Fourier transformation,
|
||||
but returns a small lazy object (basically saying "Fourier Transform of XXX"),
|
||||
which is then used in an assignment of a *view* of a gf.
|
||||
|
||||
Example
|
||||
|
||||
.. compileblock::
|
||||
|
||||
#include <triqs/gfs.hpp>
|
||||
using namespace triqs::gfs;
|
||||
int main() {
|
||||
double beta =1, a=1;
|
||||
int N=10000;
|
||||
auto gw = gf<imfreq> {{beta, Fermion, N}, {1,1}};
|
||||
auto gt = gf<imtime> {{beta, Fermion, N}, {1,1}};
|
||||
|
||||
triqs::clef::placeholder<0> om_;
|
||||
gw (om_) << 1/(om_-a);
|
||||
|
||||
gt() = inverse_fourier(gw); // fills the *View* with the contents of the FFT.
|
||||
// NB : the mesh must have the same size.
|
||||
|
||||
// make a new fresh gf, with the same size mesh, from the FFT of gt
|
||||
auto gw2 = make_gf_from_fourier(gt);
|
||||
}
|
||||
|
||||
Note that :
|
||||
|
||||
* the LHS of the = must be a view, since the RHS can not compute the domain of the function
|
||||
(how many points to use ?).
|
||||
|
||||
* In the make_gf_from_fourier function, choice is explicitly made to generate a new gf with the same number of points in the mesh.
|
||||
|
||||
|
||||
Convention
|
||||
==========
|
||||
===========
|
||||
|
||||
For real time/frequency:
|
||||
|
||||
:label: _TF_R
|
||||
.. math:: \tilde G(\omega)=\int_{-\infty}^\infty dt G(t)e^{i\omega t}
|
||||
|
||||
:label: _inv_TF_R
|
||||
.. math:: G(t)=\int_{-\infty}^\infty \frac{d\omega}{2\pi} \tilde G(\omega)e^{-i\omega t}
|
||||
|
||||
For Matsubara (imaginary) time/frequency:
|
||||
|
||||
:label: _TF_I
|
||||
.. math:: \tilde G(i\omega_n)=\int_{0}^\beta d\tau G(t)e^{i\omega_n \tau}
|
||||
|
||||
:label: _inv_TF_I
|
||||
.. math:: G(\tau)=\sum_{n=-\infty}^\infty \frac{1}{\beta} \tilde G(i\omega_n)e^{-i\omega_n \tau}
|
||||
|
||||
The :math:`\omega_n`'s are :math:`\frac{(2n+1)\pi}{\beta}` for fermions, :math:`\frac{2n\pi}{\beta}` for bosons (as :math:`G(\tau+\beta)=-G(\tau)` for fermions, :math:`G(\tau)` for bosons).
|
||||
|
||||
|
||||
*
|
||||
.. toctree::
|
||||
|
||||
The FFTW library
|
||||
================
|
||||
|
||||
Documentation on FFTW is on https://www.fftw.org.
|
||||
FFTW is a C subroutine library for computing the discrete Fourier transform (DFT) in one or more dimensions, of arbitrary input size, and of both real and complex data.
|
||||
It will be used to calculate the (inverse) Fourier transform, in real/imaginary time/frequency, using the fact that the GF values are stored for a finite amount of regularly spaced values.
|
||||
|
||||
The DFT transforms of a sequence of :math:`N` complex numbers :math:`f_0...,f_{N-1}` into a sequence of :math:`N` complex numbers :math:`\tilde f_0...,\tilde f_{N-1}` according to the formula:
|
||||
:label: _DFT
|
||||
.. math:: \tilde f_k = \sum_{n=0}^{N-1} f_n e^{-i 2 \pi k n / N}.
|
||||
The inverse DFT formula is
|
||||
:label: _inv_DFT
|
||||
.. math:: f_n = \frac{1}{N} \sum_{k=0}^{N-1} \tilde f_k e^{i 2 \pi k n / N}.
|
||||
|
||||
|
||||
|
||||
Implementation in real time/frequency using FFTW
|
||||
================================================
|
||||
|
||||
The real time mesh parameters are :math:`t_{min}`, :math:`\delta t` and :math:`N_t`.
|
||||
For the real frequency mesh, they are :math:`\omega_{min}`, :math:`\delta \omega` and :math:`N_\omega`.
|
||||
The Fourier transform requires :math:`N_\omega=N_t` and :math:`\delta t \delta \omega= \frac{2\pi}{N_t}`.
|
||||
The times are :math:`t_k=t_{min}+k\delta t` and the frequencies :math:`\omega_m=\omega_{min}+m\delta \omega`.
|
||||
|
||||
By approximating Eq. :ref:`TF_R` by
|
||||
.. math:: \tilde G(\omega_m) = \delta t \sum_{k=0}^{N_t} G(t_k) e^{i\omega_m t_k},
|
||||
we recognize an inverse DFT (Eq. :ref:`inv_DFT`). To calculate it using FFTW, we first need to prepare the input :math:`\tilde f_k`, then to do the DFT and finally to modify the output to obtain :math:`\tilde G(\omega_m)` using the two formulas:
|
||||
.. math:: \tilde f_k = G(t_k) e^{i \omega_{min}t_k},
|
||||
.. math:: \tilde G(\omega_m) = \delta t f_m e^{i t_{min}(\omega_m-\omega_{min})}.
|
||||
|
||||
Similarly, the inverse transformation is obtained by approximating Eq. :ref:`eq_inv_TF_R` by
|
||||
.. math:: G(t_k)=\frac{\delta\omega}{2\pi}\sum_{m=0}^{N_\omega} \tilde G(\omega_m)e^{-i\omega_m t_k},
|
||||
we recognize a DFT (Eq. :ref:`DFT`). To calculate it using FFTW, we first need to prepare the input :math:`f_m`, then to do the inverse DFT and finally to modify the output to obtain :math:`G(t_k)`:
|
||||
.. math:: f_m = \tilde G(\omega_m) e^{-i t_{min}\omega_m},
|
||||
.. math:: G(t_k) = \frac{1}{N_t \delta t}\tilde f_k e^{-i \omega_{min}(t_k-t_{min})}.
|
||||
|
||||
|
||||
|
||||
Implementation in imaginary time/frequency using FFTW
|
||||
=====================================================
|
||||
|
||||
|
||||
The imaginary time mesh parameters are :math:`\beta` and :math:`N_\tau`, plus a tag ``half_bins``, ``full_bins`` or ``without_last``.
|
||||
In the ``full_bins`` case, one point of the time GF has to be removed for the fourier transform.
|
||||
From these parameters, we deduce :math:`\delta\tau=\beta/N_\tau`.
|
||||
|
||||
For the imaginary frequency mesh, the mesh parameters are :math:`\beta`, :math:`n_{min}` and :math:`N_{\omega_n}`.
|
||||
From them, we deduce :math:`\delta\omega=\frac{2\pi}{\beta}`.
|
||||
|
||||
The Fourier transform requires :math:`N_\omega=N_\tau`.
|
||||
The times are :math:`\tau_k=\tau_{min}+k\delta\tau` and the frequencies :math:`\omega_n=\omega_{min}+n\delta \omega`.
|
||||
:math:`\tau_{min}` is either 0 or :math:`\delta\tau/2` depending on the mesh kind.
|
||||
:math:`\omega_{min}` is either :math:`\frac{2\pi(n_{min}+1)}{\beta}` or :math:`\frac{2\pi n_{min}}{\beta}` depending on the statistics.
|
||||
|
||||
We approximate the TF and its inverse by
|
||||
.. math:: \tilde G(i\omega_n) = \delta\tau \sum_{k=0}^{N_\tau} G(\tau_k)e^{i\omega_n \tau_k}
|
||||
.. math:: G(\tau_k) = \sum_{n=n_{min}}^{N_\tau} \frac{1}{\beta} \tilde G(i\omega_n)e^{-i\omega_n \tau_k}
|
||||
|
||||
We use for the TF:
|
||||
.. math:: \tilde f_k = G(\tau_k) e^{i \omega_{min}\tau_k},
|
||||
.. math:: \tilde G(i\omega_n) = \frac{\beta}{N_\tau} f_n e^{i \tau_{min}(\omega_n-\omega_{min})}.
|
||||
and for the inverse TF:
|
||||
.. math:: f_m = \frac{1}{\beta}\tilde G(i\omega_n) e^{-i t_{min}\omega_n},
|
||||
.. math:: G(t_k) = \tilde f_k e^{-i \omega_{min}(\tau_k-\tau_{min})},
|
||||
|
||||
|
||||
Special case of real functions in time for fermions
|
||||
----------------------------------------------------
|
||||
|
||||
In this case, :math:`G(i\omega_n)=conj(G(i\omega_n))` and we only store the values of :math:`G(i\omega_n)` for :math:`\omega_n > 0`.
|
||||
The Eq. :ref:`inv_DFT_I` becomes:
|
||||
|
||||
:label: _inv_TF_I_real_fermion
|
||||
.. math:: G(\tau)=\sum_{n=0}^\infty \frac{2}{\beta} \tilde G(i\omega_n)\cos(\omega_n \tau)
|
||||
|
||||
The inverse TF formulas are in this case
|
||||
.. math:: f_m = \frac{2}{\beta}\tilde G(i\omega_n) e^{-i t_{min}\omega_n},
|
||||
.. math:: G(t_k) = \tilde f_k e^{-i \omega_{min}(\tau_k-\tau_{min})},
|
||||
|
||||
Special case of real functions in time for bosons
|
||||
--------------------------------------------------
|
||||
|
||||
In this case, :math:`G(i\omega_n)=conj(G(i\omega_n))` and we only store the values of :math:`G(i\omega_n)` for :math:`\omega_n \ge 0`.
|
||||
The Eq. :ref:`inv_DFT_I` becomes:
|
||||
|
||||
:label: _inv_TF_I_real_bosons
|
||||
.. math:: G(\tau)=\frac{1}{\beta} \tilde G(0)+\sum_{n=1}^\infty \frac{2}{\beta} \tilde G(i\omega_n)\cos(\omega_n \tau)
|
||||
|
||||
The inverse TF formulas are in this case
|
||||
.. math:: f_0 = \frac{1}{\beta}\tilde G(0),
|
||||
.. math:: f_m = \frac{2}{\beta}\tilde G(i\omega_n) \cos(t_{min}\omega_n),
|
||||
.. math:: G(t_k) = \tilde f_k e^{-i \omega_{min}(\tau_k-\tau_{min})},
|
||||
|
||||
|
||||
Effect of a TF on the tail
|
||||
===========================
|
||||
|
||||
The tail is unchanged during a TF, but its value is used to limit the errors.
|
||||
|
||||
The components 1 and 2 of the tail (:math:`t_1` and :math:`t_2`) are used to improve the computation of the GF in the following way:
|
||||
in the large :math:`\omega` limit,
|
||||
.. math:: G(\omega)\simeq \frac{t_1}{\omega}+\frac{t_2}{\omega^2}\simeq \frac{a_1}{\omega+i}+\frac{a_2}{\omega-i}
|
||||
with :math:`a_1=\frac{t_1+it_2}{2}` and :math:`a_2=\frac{t_1-it_2}{2}`.
|
||||
|
||||
As these large w terms are badly taken into account if we naively Fourier transform the function described by its values on the mesh in w, we substract them, do the Fourier transform and add their Fourier transform to the result.
|
||||
|
||||
We use the following Fourier tranforms:
|
||||
|
||||
.. math:: \frac{2a}{\omega^2+a^2} \leftrightarrow e^{-a|x|}
|
||||
|
||||
.. math:: \frac{1}{\omega+i} \leftrightarrow -i e^{-x} \theta(x)
|
||||
|
||||
.. math:: \frac{1}{\omega-i} \leftrightarrow i e^{x} \theta(-x)
|
||||
|
||||
For the inverse Fourier transform, the inverse procedure is used.
|
||||
|
||||
In the library, :math:`a` is optimized according to the mesh properties (its size :math:`L=G.mesh().size()` and its precision :math:`\delta = G.mesh().delta()`).
|
||||
The requirements are :math:`a \gg \delta\omega` and :math:`a \ll L\delta\omega`, or equivalently :math:`a \gg \delta t` and :math:`a \ll L\delta t`.
|
||||
Thus, we chose :math:`a=\sqrt{L}\delta\omega`
|
||||
:maxdepth: 1
|
||||
|
||||
fourier_impl_notes
|
||||
|
||||
|
||||
|
||||
|
126
doc/reference/c++/gf/fourier_impl_notes.rst
Normal file
126
doc/reference/c++/gf/fourier_impl_notes.rst
Normal file
@ -0,0 +1,126 @@
|
||||
.. highlight:: c
|
||||
|
||||
Fourier : implementation notes
|
||||
#######################################
|
||||
|
||||
|
||||
The FFTW library
|
||||
---------------------
|
||||
|
||||
Documentation on FFTW is on https://www.fftw.org.
|
||||
FFTW is a C subroutine library for computing the discrete Fourier transform (DFT) in one or more dimensions, of arbitrary input size, and of both real and complex data.
|
||||
It will be used to calculate the (inverse) Fourier transform, in real/imaginary time/frequency, using the fact that the GF values are stored for a finite amount of regularly spaced values.
|
||||
|
||||
The DFT transforms of a sequence of :math:`N` complex numbers :math:`f_0...,f_{N-1}` into a sequence of :math:`N` complex numbers :math:`\tilde f_0...,\tilde f_{N-1}` according to the formula:
|
||||
.. math:: \tilde f_k = \sum_{n=0}^{N-1} f_n e^{-i 2 \pi k n / N}.
|
||||
The inverse DFT formula is
|
||||
.. math:: f_n = \frac{1}{N} \sum_{k=0}^{N-1} \tilde f_k e^{i 2 \pi k n / N}.
|
||||
|
||||
|
||||
|
||||
Implementation in real time/frequency using FFTW
|
||||
---------------------------------------------------------------
|
||||
|
||||
The real time mesh parameters are :math:`t_{min}`, :math:`\delta t` and :math:`N_t`.
|
||||
For the real frequency mesh, they are :math:`\omega_{min}`, :math:`\delta \omega` and :math:`N_\omega`.
|
||||
The Fourier transform requires :math:`N_\omega=N_t` and :math:`\delta t \delta \omega= \frac{2\pi}{N_t}`.
|
||||
The times are :math:`t_k=t_{min}+k\delta t` and the frequencies :math:`\omega_m=\omega_{min}+m\delta \omega`.
|
||||
|
||||
By approximating Eq. :ref:`TF_R` by
|
||||
.. math:: \tilde G(\omega_m) = \delta t \sum_{k=0}^{N_t} G(t_k) e^{i\omega_m t_k},
|
||||
we recognize an inverse DFT (Eq. :ref:`inv_DFT`). To calculate it using FFTW, we first need to prepare the input :math:`\tilde f_k`, then to do the DFT and finally to modify the output to obtain :math:`\tilde G(\omega_m)` using the two formulas:
|
||||
.. math:: \tilde f_k = G(t_k) e^{i \omega_{min}t_k},
|
||||
.. math:: \tilde G(\omega_m) = \delta t f_m e^{i t_{min}(\omega_m-\omega_{min})}.
|
||||
|
||||
Similarly, the inverse transformation is obtained by approximating Eq. :ref:`eq_inv_TF_R` by
|
||||
.. math:: G(t_k)=\frac{\delta\omega}{2\pi}\sum_{m=0}^{N_\omega} \tilde G(\omega_m)e^{-i\omega_m t_k},
|
||||
we recognize a DFT (Eq. :ref:`DFT`). To calculate it using FFTW, we first need to prepare the input :math:`f_m`, then to do the inverse DFT and finally to modify the output to obtain :math:`G(t_k)`:
|
||||
.. math:: f_m = \tilde G(\omega_m) e^{-i t_{min}\omega_m},
|
||||
.. math:: G(t_k) = \frac{1}{N_t \delta t}\tilde f_k e^{-i \omega_{min}(t_k-t_{min})}.
|
||||
|
||||
|
||||
|
||||
Implementation in imaginary time/frequency using FFTW
|
||||
---------------------------------------------------------------
|
||||
|
||||
|
||||
The imaginary time mesh parameters are :math:`\beta` and :math:`N_\tau`, plus a tag ``half_bins``, ``full_bins`` or ``without_last``.
|
||||
In the ``full_bins`` case, one point of the time GF has to be removed for the fourier transform.
|
||||
From these parameters, we deduce :math:`\delta\tau=\beta/N_\tau`.
|
||||
|
||||
For the imaginary frequency mesh, the mesh parameters are :math:`\beta`, :math:`n_{min}` and :math:`N_{\omega_n}`.
|
||||
From them, we deduce :math:`\delta\omega=\frac{2\pi}{\beta}`.
|
||||
|
||||
The Fourier transform requires :math:`N_\omega=N_\tau`.
|
||||
The times are :math:`\tau_k=\tau_{min}+k\delta\tau` and the frequencies :math:`\omega_n=\omega_{min}+n\delta \omega`.
|
||||
:math:`\tau_{min}` is either 0 or :math:`\delta\tau/2` depending on the mesh kind.
|
||||
:math:`\omega_{min}` is either :math:`\frac{2\pi(n_{min}+1)}{\beta}` or :math:`\frac{2\pi n_{min}}{\beta}` depending on the statistics.
|
||||
|
||||
We approximate the TF and its inverse by
|
||||
.. math:: \tilde G(i\omega_n) = \delta\tau \sum_{k=0}^{N_\tau} G(\tau_k)e^{i\omega_n \tau_k}
|
||||
.. math:: G(\tau_k) = \sum_{n=n_{min}}^{N_\tau} \frac{1}{\beta} \tilde G(i\omega_n)e^{-i\omega_n \tau_k}
|
||||
|
||||
We use for the TF:
|
||||
.. math:: \tilde f_k = G(\tau_k) e^{i \omega_{min}\tau_k},
|
||||
.. math:: \tilde G(i\omega_n) = \frac{\beta}{N_\tau} f_n e^{i \tau_{min}(\omega_n-\omega_{min})}.
|
||||
and for the inverse TF:
|
||||
.. math:: f_m = \frac{1}{\beta}\tilde G(i\omega_n) e^{-i t_{min}\omega_n},
|
||||
.. math:: G(t_k) = \tilde f_k e^{-i \omega_{min}(\tau_k-\tau_{min})},
|
||||
|
||||
|
||||
Special case of real functions in time for fermions
|
||||
...........................................................
|
||||
|
||||
In this case, :math:`G(i\omega_n)=conj(G(i\omega_n))` and we only store the values of :math:`G(i\omega_n)` for :math:`\omega_n > 0`.
|
||||
The Eq. :ref:`inv_DFT_I` becomes:
|
||||
|
||||
.. math:: G(\tau)=\sum_{n=0}^\infty \frac{2}{\beta} \tilde G(i\omega_n)\cos(\omega_n \tau)
|
||||
|
||||
The inverse TF formulas are in this case
|
||||
.. math:: f_m = \frac{2}{\beta}\tilde G(i\omega_n) e^{-i t_{min}\omega_n},
|
||||
.. math:: G(t_k) = \tilde f_k e^{-i \omega_{min}(\tau_k-\tau_{min})},
|
||||
|
||||
Special case of real functions in time for bosons
|
||||
...........................................................
|
||||
|
||||
In this case, :math:`G(i\omega_n)=conj(G(i\omega_n))` and we only store the values of :math:`G(i\omega_n)` for :math:`\omega_n \ge 0`.
|
||||
The Eq. :ref:`inv_DFT_I` becomes:
|
||||
|
||||
.. math:: G(\tau)=\frac{1}{\beta} \tilde G(0)+\sum_{n=1}^\infty \frac{2}{\beta} \tilde G(i\omega_n)\cos(\omega_n \tau)
|
||||
|
||||
The inverse TF formulas are in this case
|
||||
.. math:: f_0 = \frac{1}{\beta}\tilde G(0),
|
||||
.. math:: f_m = \frac{2}{\beta}\tilde G(i\omega_n) \cos(t_{min}\omega_n),
|
||||
.. math:: G(t_k) = \tilde f_k e^{-i \omega_{min}(\tau_k-\tau_{min})},
|
||||
|
||||
|
||||
Effect of a TF on the tail
|
||||
------------------------------------------
|
||||
|
||||
The tail is unchanged during a TF, but its value is used to limit the errors.
|
||||
|
||||
The components 1 and 2 of the tail (:math:`t_1` and :math:`t_2`) are used to improve the computation of the GF in the following way:
|
||||
in the large :math:`\omega` limit,
|
||||
.. math:: G(\omega)\simeq \frac{t_1}{\omega}+\frac{t_2}{\omega^2}\simeq \frac{a_1}{\omega+i}+\frac{a_2}{\omega-i}
|
||||
with :math:`a_1=\frac{t_1+it_2}{2}` and :math:`a_2=\frac{t_1-it_2}{2}`.
|
||||
|
||||
As these large w terms are badly taken into account if we naively Fourier transform the function described by its values on the mesh in w, we substract them, do the Fourier transform and add their Fourier transform to the result.
|
||||
|
||||
We use the following Fourier tranforms:
|
||||
|
||||
.. math:: \frac{2a}{\omega^2+a^2} \leftrightarrow e^{-a|x|}
|
||||
|
||||
.. math:: \frac{1}{\omega+i} \leftrightarrow -i e^{-x} \theta(x)
|
||||
|
||||
.. math:: \frac{1}{\omega-i} \leftrightarrow i e^{x} \theta(-x)
|
||||
|
||||
For the inverse Fourier transform, the inverse procedure is used.
|
||||
|
||||
In the library, :math:`a` is optimized according to the mesh properties (its size :math:`L=G.mesh().size()` and its precision :math:`\delta = G.mesh().delta()`).
|
||||
The requirements are :math:`a \gg \delta\omega` and :math:`a \ll L\delta\omega`, or equivalently :math:`a \gg \delta t` and :math:`a \ll L\delta t`.
|
||||
Thus, we chose :math:`a=\sqrt{L}\delta\omega`
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -8,22 +8,22 @@ cdef extern from "triqs/gfs/local/functions.hpp":
|
||||
############### Fourier #########################
|
||||
|
||||
cdef extern from "triqs/gfs/local/fourier_matsubara.hpp" :
|
||||
gf_imfreq lazy_fourier (gf_imtime & )
|
||||
gf_imtime lazy_inverse_fourier (gf_imfreq & )
|
||||
gf_imfreq fourier (gf_imtime & )
|
||||
gf_imtime inverse_fourier (gf_imfreq & )
|
||||
|
||||
cdef extern from "triqs/gfs/local/fourier_real.hpp" :
|
||||
gf_refreq lazy_fourier (gf_retime & )
|
||||
gf_retime lazy_inverse_fourier (gf_refreq & )
|
||||
gf_refreq fourier (gf_retime & ) except +
|
||||
gf_retime inverse_fourier (gf_refreq & ) except +
|
||||
gf_refreq fourier (gf_retime & )
|
||||
gf_retime inverse_fourier (gf_refreq & )
|
||||
#gf_refreq fourier (gf_retime & ) except +
|
||||
#gf_retime inverse_fourier (gf_refreq & ) except +
|
||||
|
||||
############### Legendre #########################
|
||||
|
||||
cdef extern from "triqs/gfs/local/legendre_matsubara.hpp" :
|
||||
gf_imfreq lazy_legendre_imfreq (gf_legendre &)
|
||||
gf_imtime lazy_legendre_imtime (gf_legendre &)
|
||||
gf_legendre lazy_imfreq_legendre (gf_imfreq &)
|
||||
gf_legendre lazy_imtime_legendre (gf_imtime &)
|
||||
gf_imfreq legendre_to_imfreq (gf_legendre &)
|
||||
gf_imtime legendre_to_imtime (gf_legendre &)
|
||||
gf_legendre imfreq_to_legendre (gf_imfreq &)
|
||||
gf_legendre imtime_to_legendre (gf_imtime &)
|
||||
|
||||
############### Pade #########################
|
||||
|
||||
|
@ -12,11 +12,11 @@ cdef class GfImFreq_cython:
|
||||
|
||||
def set_from_fourier(self,GfImTime_cython gt) :
|
||||
"""Fills self with the Fourier transform of gt"""
|
||||
self._c << lazy_fourier( gt._c )
|
||||
self._c << fourier( gt._c )
|
||||
|
||||
def set_from_legendre(self, GfLegendre_cython gl) :
|
||||
"""Fills self with the Legendre transform of gl"""
|
||||
self._c << lazy_legendre_imfreq(gl._c)
|
||||
self._c << legendre_to_imfreq(gl._c)
|
||||
|
||||
def density(self):
|
||||
return density(self._c).to_python()
|
||||
|
@ -12,11 +12,11 @@ cdef class GfImTime_cython:
|
||||
|
||||
def set_from_inverse_fourier(self,GfImFreq_cython gw) :
|
||||
"""Fills self with the Inverse Fourier transform of gw"""
|
||||
self._c << lazy_inverse_fourier( gw._c)
|
||||
self._c << inverse_fourier( gw._c)
|
||||
|
||||
def set_from_legendre(self, GfLegendre_cython gl) :
|
||||
"""Fills self with the Legendre transform of gl"""
|
||||
self._c << lazy_legendre_imtime(gl._c)
|
||||
self._c << legendre_to_imtime(gl._c)
|
||||
|
||||
def __dealloc__ (self):
|
||||
pass
|
||||
|
@ -10,11 +10,11 @@ cdef class GfLegendre_cython:
|
||||
|
||||
def set_from_imtime(self, GfImTime_cython gt) :
|
||||
"""Fills self with the Legendre transform of gt"""
|
||||
self._c << lazy_imtime_legendre(gt._c)
|
||||
self._c << imtime_to_legendre(gt._c)
|
||||
|
||||
def set_from_imfreq(self, GfImFreq_cython gw) :
|
||||
"""Fills self with the Legendre transform of gw"""
|
||||
self._c << lazy_imfreq_legendre(gw._c)
|
||||
self._c << imfreq_to_legendre(gw._c)
|
||||
|
||||
def density(self):
|
||||
return density(self._c).to_python()
|
||||
|
@ -10,10 +10,11 @@ cdef class GfReFreq_cython:
|
||||
|
||||
def set_from_fourier(self, GfReTime_cython gt) :
|
||||
"""Fills self with the Fourier transform of gt"""
|
||||
self._c << lazy_fourier( gt._c )
|
||||
self._c << fourier( gt._c )
|
||||
|
||||
def inverse_fourier(self):
|
||||
return make_GfReTime(inverse_fourier(self._c))
|
||||
# put if back with make_gf_from_fourier when approved
|
||||
#def inverse_fourier(self):
|
||||
# return make_GfReTime(inverse_fourier(self._c))
|
||||
|
||||
def set_from_pade(self, GfImFreq_cython gw, n_points = 100, freq_offset = 0.0) :
|
||||
pade(self._c, gw._c, n_points, freq_offset)
|
||||
|
@ -8,12 +8,13 @@ cdef class GfReTime_cython:
|
||||
def __write_hdf5_cython__ (self, gr , char * key) :
|
||||
h5_write (make_h5_group(gr), key, self._c)
|
||||
|
||||
def fourier(self):
|
||||
return make_GfReFreq(fourier(self._c))
|
||||
# Put it back ?
|
||||
#def fourier(self):
|
||||
# return make_GfReFreq(fourier(self._c))
|
||||
|
||||
def set_from_inverse_fourier(self, GfReFreq_cython gw) :
|
||||
"""Fills self with the Inverse Fourier transform of gw"""
|
||||
self._c << lazy_inverse_fourier( gw._c)
|
||||
self._c << inverse_fourier( gw._c)
|
||||
|
||||
def __dealloc__ (self):
|
||||
pass
|
||||
|
@ -35,11 +35,11 @@ try {
|
||||
auto G_w_wn_curry0 = curry<0>(G_w_wn);
|
||||
auto G_w_tau_curry0 = curry<0>(G_w_tau);
|
||||
|
||||
for (auto const & w : G_w_wn_curry0.mesh()) G_w_wn_curry0[w] = lazy_fourier(G_w_tau_curry0[w]);
|
||||
for (auto const & w : G_w_wn_curry0.mesh()) G_w_wn_curry0[w] = fourier(G_w_tau_curry0[w]);
|
||||
|
||||
G_w_wn_curry0[w_] << lazy_fourier(G_w_tau_curry0[w_]);
|
||||
G_w_wn_curry0[w_] << fourier(G_w_tau_curry0[w_]);
|
||||
|
||||
curry<0>(G_w_wn) [w_] << lazy_fourier(curry<0>(G_w_tau)[w_]);
|
||||
curry<0>(G_w_wn) [w_] << fourier(curry<0>(G_w_tau)[w_]);
|
||||
}
|
||||
// temp fix : THE TEST DOES NOT RUN !!
|
||||
//TRIQS_CATCH_AND_ABORT;
|
||||
|
@ -12,13 +12,13 @@ int main() {
|
||||
auto G = gf<imfreq> {{beta, Fermion}, {2,2}};
|
||||
auto Gc = G;
|
||||
auto G3 = G;
|
||||
auto Gt = gf<imtime> {{beta, Fermion}, {2,2}};
|
||||
auto Gt = gf<imtime> {{beta, Fermion,100}, {2,2}};
|
||||
|
||||
auto gt = inverse_fourier(G);
|
||||
auto gw = fourier(gt);
|
||||
auto gt = make_gf_from_inverse_fourier(G);
|
||||
auto gw = make_gf_from_fourier(gt);
|
||||
|
||||
//gw() = lazy_fourier(gt);
|
||||
G() = lazy_fourier(Gt);
|
||||
//gw() = fourier(gt);
|
||||
G() = fourier(Gt);
|
||||
}
|
||||
|
||||
|
||||
|
38
test/triqs/gfs/gf_notail.cpp
Normal file
38
test/triqs/gfs/gf_notail.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK
|
||||
#include <triqs/gfs.hpp>
|
||||
using namespace triqs::gfs;
|
||||
using namespace triqs::arrays;
|
||||
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> " << (X) << std::endl << std::endl;
|
||||
#include <triqs/gfs/local/functions.hpp>
|
||||
|
||||
int main() {
|
||||
try {
|
||||
double beta = 1, a = 1;
|
||||
|
||||
// construct
|
||||
auto gw_n = gf<imfreq, matrix_valued, no_tail>{{beta, Fermion}, {2, 2}};
|
||||
auto gt_n = gf<imtime, matrix_valued, no_tail>{{beta, Fermion, 100}, {2, 2}};
|
||||
|
||||
// make a view from a g with a tail
|
||||
auto gw = gf<imfreq, matrix_valued>{{beta, Fermion}, {2, 2}};
|
||||
auto gt = gf<imtime, matrix_valued>{gf_mesh<imtime>{beta, Fermion, 100}, {2, 2}};
|
||||
|
||||
auto vw = make_gf_view_without_tail(gw);
|
||||
auto vt = make_gf_view_without_tail(gt);
|
||||
|
||||
triqs::clef::placeholder<0> tau_;
|
||||
// should not and does not compile : improve error message ???
|
||||
// gt(tau_) << exp(-a * tau_) / (1 + exp(-beta * a));
|
||||
vt(tau_) << exp(-a * tau_) / (1 + exp(-beta * a));
|
||||
|
||||
// test hdf5
|
||||
H5::H5File file("ess_g_notail.h5", H5F_ACC_TRUNC);
|
||||
h5_write(file, "g", vt);
|
||||
|
||||
// rebuilding a new gf...
|
||||
auto g3 = make_gf_from_g_and_tail(vw, gw.singularity());
|
||||
// need to test all this....
|
||||
|
||||
}
|
||||
TRIQS_CATCH_AND_ABORT;
|
||||
}
|
@ -20,7 +20,7 @@ int main() {
|
||||
auto G = gf<imfreq>{ {beta, Fermion}, {2,2} };
|
||||
auto Gc = gf<imfreq>{ {beta, Fermion}, {2,2} };
|
||||
auto G3 = gf<imfreq>{ {beta, Fermion}, {2,2} };
|
||||
auto Gt = gf<imtime>{ {beta, Fermion}, {2,2} };
|
||||
auto Gt = gf<imtime>{ {beta, Fermion,100}, {2,2} };
|
||||
|
||||
auto Gv = G();
|
||||
TEST( G( 0) ) ;
|
||||
|
@ -5,6 +5,14 @@ using namespace triqs::arrays;
|
||||
#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) <<std::endl<<std::endl;
|
||||
#include <triqs/gfs/local/fourier_matsubara.hpp>
|
||||
|
||||
namespace triqs { namespace gfs {
|
||||
// defined in the cpp file
|
||||
void fourier_impl (gf_view<imfreq,scalar_valued> gw , gf_const_view<imtime,scalar_valued> gt, scalar_valued);
|
||||
void fourier_impl (gf_view<imfreq,matrix_valued> gw , gf_const_view<imtime,matrix_valued> gt, matrix_valued);
|
||||
void inverse_fourier_impl (gf_view<imtime,scalar_valued> gt, gf_const_view<imfreq,scalar_valued> gw, scalar_valued);
|
||||
void inverse_fourier_impl (gf_view<imtime,matrix_valued> gt, gf_const_view<imfreq,matrix_valued> gw, matrix_valued);
|
||||
}}
|
||||
|
||||
int main() {
|
||||
|
||||
double precision=10e-9;
|
||||
@ -45,9 +53,9 @@ int main() {
|
||||
}
|
||||
h5_write(file,"Gt1b",Gt1); // must be 0
|
||||
|
||||
///to verify that lazy_fourier computes
|
||||
///to verify that fourier computes
|
||||
auto Gw2 = gf<imfreq> {{beta, Fermion}, {1,1}};
|
||||
Gw2() = lazy_fourier(Gt1);
|
||||
Gw2() = fourier(Gt1);
|
||||
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,11 @@ int main() {
|
||||
Gw1.singularity()(2)=triqs::arrays::matrix<double>{{2.0*a}};
|
||||
h5_write(file,"Gw1",Gw1); // the original lorentzian
|
||||
|
||||
auto Gt1 = inverse_fourier(Gw1);
|
||||
auto Gt1 = make_gf_from_inverse_fourier(Gw1);
|
||||
h5_write(file,"Gt1",Gt1); // the lorentzian TF : lorentzian_inverse
|
||||
|
||||
// verification that TF(TF^-1)=Id
|
||||
auto Gw1b = fourier(Gt1);
|
||||
auto Gw1b = make_gf_from_fourier(Gt1);
|
||||
for(auto const & w:Gw1b.mesh()){
|
||||
Gw1b[w]-=Gw1[w];
|
||||
if ( std::abs(Gw1b[w](0,0)) > precision) TRIQS_RUNTIME_ERROR<<" fourier_real_time error : w="<<w<<" ,G1="<<std::abs(Gw1b[w](0,0))<<"\n";
|
||||
@ -65,7 +65,7 @@ int main() {
|
||||
Gt2.singularity()(1)=triqs::arrays::matrix<double>{{1.0}};
|
||||
h5_write(file,"Gt2",Gt2);
|
||||
|
||||
auto Gw2 = fourier(Gt2);
|
||||
auto Gw2 = make_gf_from_fourier(Gt2);
|
||||
h5_write(file,"Gw2",Gw2);
|
||||
|
||||
for(auto const & w:Gw2.mesh()){
|
||||
@ -86,7 +86,7 @@ int main() {
|
||||
//for(auto const & t:Gt3.mesh()) Gt3[t] = 1.0 * std::cos(10*t) + 0.25*std::sin(4*t) + 0.5_j*std::sin(8*t+0.3*acos(-1.)) ;
|
||||
h5_write(file,"Gt3",Gt3);
|
||||
|
||||
auto Gw3 = fourier(Gt3);
|
||||
auto Gw3 = make_gf_from_fourier(Gt3);
|
||||
h5_write(file,"Gw3",Gw3);
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ void test_0(){
|
||||
|
||||
/* ---------- Fourier transform ---------------------*/
|
||||
auto Gt = gf<imtime> {{beta, Fermion, Ntau, full_bins}, {1,1}};
|
||||
Gt() = lazy_inverse_fourier(G);
|
||||
Gt() = inverse_fourier(G);
|
||||
|
||||
TEST(Gt(0.0));
|
||||
|
||||
@ -52,7 +52,7 @@ void test_1(){
|
||||
auto Gw = gf<imfreq> {{beta, Fermion, 100}, {1,1}};
|
||||
Gw.singularity()(1) = 1;
|
||||
|
||||
Gt() = lazy_inverse_fourier(Gw);
|
||||
Gt() = inverse_fourier(Gw);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
@ -30,5 +30,8 @@
|
||||
#include <triqs/gfs/product.hpp>
|
||||
#include <triqs/gfs/curry.hpp>
|
||||
|
||||
#include <triqs/gfs/local/fourier_matsubara.hpp>
|
||||
#include <triqs/gfs/local/fourier_real.hpp>
|
||||
#include <triqs/gfs/local/legendre_matsubara.hpp>
|
||||
#endif
|
||||
|
||||
|
@ -30,7 +30,8 @@ namespace triqs { namespace gfs {
|
||||
typedef typename mpl::if_c<IsComplex, std::complex<double>, double>::type point_t;
|
||||
double beta;
|
||||
statistic_enum statistic;
|
||||
matsubara_domain (double Beta=1, statistic_enum s = Fermion): beta(Beta), statistic(s){
|
||||
matsubara_domain() = default;
|
||||
matsubara_domain (double Beta, statistic_enum s): beta(Beta), statistic(s){
|
||||
if(beta<0)TRIQS_RUNTIME_ERROR<<"Matsubara domain construction : beta <0 : beta ="<< beta <<"\n";
|
||||
}
|
||||
matsubara_domain(matsubara_domain const &) = default;
|
||||
|
@ -94,6 +94,9 @@ namespace triqs { namespace gfs {
|
||||
|
||||
template <typename G> auto get_gf_data_shape(G const &g) DECL_AND_RETURN(g.get_data_shape());
|
||||
|
||||
template <typename Variable, typename Target, typename Opt, bool IsView, bool IsConst>
|
||||
auto get_target_shape(gf_impl<Variable, Target, Opt, IsView, IsConst> const &g) DECL_AND_RETURN(g.data().shape().front_pop());
|
||||
|
||||
// ---------------------- implementation --------------------------------
|
||||
|
||||
// overload get_shape for a vector to simplify code below in gf block case.
|
||||
@ -334,8 +337,10 @@ namespace triqs { namespace gfs {
|
||||
template<typename RHS> friend void triqs_clef_auto_assign_subscript (gf_impl & g, RHS rhs) { triqs_clef_auto_assign(g,rhs);}
|
||||
|
||||
private:
|
||||
template<typename RHS> void triqs_clef_auto_assign_impl (RHS const & rhs, std::integral_constant<bool,false>) {
|
||||
for (auto const & w: this->mesh()) (*this)[w] = rhs(w);
|
||||
template <typename RHS> void triqs_clef_auto_assign_impl(RHS const &rhs, std::integral_constant<bool, false>) {
|
||||
for (auto const &w : this->mesh()) {
|
||||
(*this)[w] = rhs(w);
|
||||
}
|
||||
//for (auto const & w: this->mesh()) (*this)[w] = rhs(typename B::mesh_t::mesh_point_t::cast_t(w));
|
||||
}
|
||||
template <typename RHS> void triqs_clef_auto_assign_impl(RHS const &rhs, std::integral_constant<bool, true>) {
|
||||
@ -582,7 +587,11 @@ namespace triqs { namespace gfs {
|
||||
|
||||
template <typename Var, typename Opt> struct factories<Var, scalar_valued, Opt> {
|
||||
typedef gf<Var, scalar_valued, Opt> gf_t;
|
||||
struct target_shape_t {};
|
||||
struct target_shape_t {
|
||||
target_shape_t front_pop() const { // this make the get_target_shape function works in this case...
|
||||
return {};
|
||||
}
|
||||
};
|
||||
typedef typename gf_t::mesh_t mesh_t;
|
||||
|
||||
static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) {
|
||||
@ -620,6 +629,7 @@ namespace triqs { namespace gfs {
|
||||
};
|
||||
} // gfs_implementation
|
||||
|
||||
|
||||
}}
|
||||
|
||||
// same as for arrays : views can not be swapped by the std::swap. Delete it
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "./tools.hpp"
|
||||
#include "./gf.hpp"
|
||||
#include "./local/tail.hpp"
|
||||
#include "./local/no_tail.hpp"
|
||||
#include "./domains/matsubara.hpp"
|
||||
#include "./meshes/linear.hpp"
|
||||
#include "./evaluators.hpp"
|
||||
@ -34,6 +35,7 @@ namespace triqs { namespace gfs {
|
||||
typedef linear_mesh<matsubara_domain<true>> B;
|
||||
static double m1(double beta) { return std::acos(-1)/beta;}
|
||||
gf_mesh() = default;
|
||||
gf_mesh(B const &x) : B(x) {} // enables also construction from another Opt
|
||||
gf_mesh (typename B::domain_t const & d, int Nmax = 1025) :
|
||||
B(d, d.statistic==Fermion?m1(d.beta):0, d.statistic==Fermion?(2*Nmax+1)*m1(d.beta): 2*Nmax*m1(d.beta), Nmax, without_last){}
|
||||
gf_mesh (double beta, statistic_enum S, int Nmax = 1025) : gf_mesh({beta,S}, Nmax){}
|
||||
@ -42,8 +44,8 @@ namespace triqs { namespace gfs {
|
||||
namespace gfs_implementation {
|
||||
|
||||
//singularity
|
||||
template<typename Opt> struct singularity<imfreq,matrix_valued,Opt> { typedef local::tail type;};
|
||||
template<typename Opt> struct singularity<imfreq,scalar_valued,Opt> { typedef local::tail type;};
|
||||
template<> struct singularity<imfreq,matrix_valued,void> { typedef local::tail type;};
|
||||
template<> struct singularity<imfreq,scalar_valued,void> { typedef local::tail type;};
|
||||
|
||||
//h5 name
|
||||
template<typename Opt> struct h5_name<imfreq,matrix_valued,Opt> { static std::string invoke(){ return "ImFreq";}};
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "./tools.hpp"
|
||||
#include "./gf.hpp"
|
||||
#include "./local/tail.hpp"
|
||||
#include "./local/no_tail.hpp"
|
||||
#include "./domains/matsubara.hpp"
|
||||
#include "./meshes/linear.hpp"
|
||||
#include "./evaluators.hpp"
|
||||
@ -35,15 +36,16 @@ namespace triqs { namespace gfs {
|
||||
template <typename Opt> struct gf_mesh<imtime, Opt> : linear_mesh<matsubara_domain<false>> {
|
||||
typedef linear_mesh<matsubara_domain<false>> B;
|
||||
gf_mesh() = default;
|
||||
gf_mesh(B const &x) : B(x) {} // enables also construction from another Opt
|
||||
gf_mesh(typename B::domain_t d, int n_time_slices, mesh_kind mk = half_bins) : B(d, 0, d.beta, n_time_slices, mk) {}
|
||||
gf_mesh(double beta, statistic_enum S, int n_time_slices, mesh_kind mk = half_bins) : gf_mesh({beta, S}, n_time_slices, mk) {}
|
||||
};
|
||||
|
||||
namespace gfs_implementation {
|
||||
|
||||
// singularity
|
||||
template<typename Opt> struct singularity<imtime,matrix_valued,Opt> { typedef local::tail type;};
|
||||
template<typename Opt> struct singularity<imtime,scalar_valued,Opt> { typedef local::tail type;};
|
||||
// singularity. If no_tail is given, then it is the default (nothing)
|
||||
template<> struct singularity<imtime,matrix_valued,void> { typedef local::tail type;};
|
||||
template<> struct singularity<imtime,scalar_valued,void> { typedef local::tail type;};
|
||||
|
||||
// h5 name
|
||||
template<typename Opt> struct h5_name<imtime,matrix_valued,Opt> { static std::string invoke(){ return "ImTime";}};
|
||||
@ -92,6 +94,7 @@ namespace triqs { namespace gfs {
|
||||
template<typename Opt, typename Target> struct evaluator<imtime,Target,Opt> : evaluator_one_var<imtime>{};
|
||||
|
||||
} // gfs_implementation.
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
@ -18,25 +18,15 @@
|
||||
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "fourier_base.hpp"
|
||||
#include "fourier_matsubara.hpp"
|
||||
#include <fftw3.h>
|
||||
|
||||
namespace triqs { namespace gfs {
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
namespace impl_local_matsubara {
|
||||
|
||||
inline dcomplex oneFermion(dcomplex a,double b,double tau,double beta) {
|
||||
return -a*( b >=0 ? exp(-b*tau)/(1+exp(-beta*b)) : exp(b*(beta-tau))/(1+exp(beta*b)) );
|
||||
}
|
||||
|
||||
inline dcomplex oneBoson(dcomplex a,double b,double tau,double beta) {
|
||||
return a*( b >=0 ? exp(-b*tau)/(exp(-beta*b)-1) : exp(b*(beta-tau))/(1-exp(b*beta)) );
|
||||
}
|
||||
}
|
||||
|
||||
template<typename GfElementType> GfElementType convert_green ( dcomplex const& x) { return x;}
|
||||
template<> double convert_green<double> ( dcomplex const& x) { return real(x);}
|
||||
template <typename GfElementType> GfElementType convert_green(dcomplex const& x) { return x; }
|
||||
template <> double convert_green<double>(dcomplex const& x) { return real(x); }
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -44,142 +34,187 @@ namespace triqs { namespace gfs {
|
||||
|
||||
tqa::vector<dcomplex> g_in, g_out;
|
||||
|
||||
void direct (gf_view<imfreq,scalar_valued> gw, gf_const_view<imtime,scalar_valued> 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
|
||||
dcomplex oneFermion(dcomplex a, double b, double tau, double beta) {
|
||||
return -a * (b >= 0 ? exp(-b * tau) / (1 + exp(-beta * b)) : exp(b * (beta - tau)) / (1 + exp(beta * b)));
|
||||
}
|
||||
|
||||
void inverse(gf_view<imtime,scalar_valued> gt, gf_const_view<imfreq,scalar_valued> gw){
|
||||
using namespace impl_local_matsubara;
|
||||
dcomplex oneBoson(dcomplex a, double b, double tau, double beta) {
|
||||
return a * (b >= 0 ? exp(-b * tau) / (exp(-beta * b) - 1) : exp(b * (beta - tau)) / (1 - exp(b * beta)));
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void direct(gf_view<imfreq, scalar_valued> gw, gf_const_view<imtime, scalar_valued> gt) {
|
||||
auto ta = gt(freq_infty());
|
||||
direct_impl(make_gf_view_without_tail(gw), make_gf_view_without_tail(gt), ta);
|
||||
gw.singularity() = gt.singularity(); // set tail
|
||||
}
|
||||
|
||||
void direct(gf_view<imfreq, scalar_valued,no_tail> gw, gf_const_view<imtime, scalar_valued,no_tail> gt) =delete;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
private:
|
||||
void direct_impl(gf_view<imfreq, scalar_valued, no_tail> gw, gf_const_view<imtime, scalar_valued, no_tail> gt,
|
||||
local::tail const& ta) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
//-------------------------------------
|
||||
|
||||
void inverse(gf_view<imtime, scalar_valued> gt, gf_const_view<imfreq, scalar_valued> gw) {
|
||||
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);
|
||||
// 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());
|
||||
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;
|
||||
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 (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;
|
||||
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) );
|
||||
// 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));
|
||||
}
|
||||
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));
|
||||
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();
|
||||
}
|
||||
|
||||
};
|
||||
}; // class worker
|
||||
|
||||
void fourier_impl (gf_view<imfreq,scalar_valued> gw , gf_const_view<imtime,scalar_valued> gt, scalar_valued){
|
||||
//--------------------------------------------
|
||||
|
||||
void fourier_impl(gf_view<imfreq, scalar_valued> gw, gf_const_view<imtime, scalar_valued> gt, scalar_valued) {
|
||||
impl_worker w;
|
||||
w.direct(gw,gt);
|
||||
w.direct(gw, gt);
|
||||
}
|
||||
|
||||
void fourier_impl (gf_view<imfreq,matrix_valued> gw , gf_const_view<imtime,matrix_valued> gt, matrix_valued){
|
||||
void fourier_impl(gf_view<imfreq, matrix_valued> gw, gf_const_view<imtime, matrix_valued> gt, matrix_valued) {
|
||||
impl_worker w;
|
||||
for (size_t n1=0; n1<gt.data().shape()[1];n1++)
|
||||
for (size_t n2=0; n2<gt.data().shape()[2];n2++){
|
||||
auto gw_sl=slice_target_to_scalar(gw,n1,n2);
|
||||
auto gt_sl=slice_target_to_scalar(gt,n1,n2);
|
||||
for (size_t n1 = 0; n1 < gt.data().shape()[1]; n1++)
|
||||
for (size_t n2 = 0; n2 < gt.data().shape()[2]; n2++) {
|
||||
auto gw_sl = slice_target_to_scalar(gw, n1, n2);
|
||||
auto gt_sl = slice_target_to_scalar(gt, n1, n2);
|
||||
w.direct(gw_sl, gt_sl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void inverse_fourier_impl (gf_view<imtime,scalar_valued> gt , gf_const_view<imfreq,scalar_valued> gw, scalar_valued){
|
||||
void inverse_fourier_impl(gf_view<imtime, scalar_valued> gt, gf_const_view<imfreq, scalar_valued> gw, scalar_valued) {
|
||||
impl_worker w;
|
||||
w.inverse(gt,gw);
|
||||
w.inverse(gt, gw);
|
||||
}
|
||||
|
||||
void inverse_fourier_impl (gf_view<imtime,matrix_valued> gt , gf_const_view<imfreq,matrix_valued> gw, matrix_valued){
|
||||
void inverse_fourier_impl(gf_view<imtime, matrix_valued> gt, gf_const_view<imfreq, matrix_valued> gw, matrix_valued) {
|
||||
impl_worker w;
|
||||
for (size_t n1=0; n1<gw.data().shape()[1];n1++)
|
||||
for (size_t n2=0; n2<gw.data().shape()[2];n2++){
|
||||
auto gt_sl=slice_target_to_scalar(gt, n1, n2);
|
||||
auto gw_sl=slice_target_to_scalar(gw, n1, n2);
|
||||
w.inverse( gt_sl, gw_sl);
|
||||
for (size_t n1 = 0; n1 < gw.data().shape()[1]; n1++)
|
||||
for (size_t n2 = 0; n2 < gw.data().shape()[2]; n2++) {
|
||||
auto gt_sl = slice_target_to_scalar(gt, n1, n2);
|
||||
auto gw_sl = slice_target_to_scalar(gw, n1, n2);
|
||||
w.inverse(gt_sl, gw_sl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void triqs_gf_view_assign_delegation( gf_view<imfreq,scalar_valued> g, gf_keeper<tags::fourier,imtime,scalar_valued> const & L) { fourier_impl ( g ,L.g, scalar_valued() ); }
|
||||
void triqs_gf_view_assign_delegation( gf_view<imfreq,matrix_valued> g, gf_keeper<tags::fourier,imtime,matrix_valued> const & L) { fourier_impl ( g, L.g, matrix_valued() ); }
|
||||
void triqs_gf_view_assign_delegation( gf_view<imtime,scalar_valued> g, gf_keeper<tags::fourier,imfreq,scalar_valued> const & L) { inverse_fourier_impl( g, L.g, scalar_valued() ); }
|
||||
void triqs_gf_view_assign_delegation( gf_view<imtime,matrix_valued> g, gf_keeper<tags::fourier,imfreq,matrix_valued> const & L) { inverse_fourier_impl( g, L.g, matrix_valued() ); }
|
||||
|
||||
}}
|
||||
void triqs_gf_view_assign_delegation(gf_view<imfreq, scalar_valued> g,
|
||||
gf_keeper<tags::fourier, imtime, scalar_valued> const& L) {
|
||||
fourier_impl(g, L.g, scalar_valued());
|
||||
}
|
||||
void triqs_gf_view_assign_delegation(gf_view<imfreq, matrix_valued> g,
|
||||
gf_keeper<tags::fourier, imtime, matrix_valued> const& L) {
|
||||
fourier_impl(g, L.g, matrix_valued());
|
||||
}
|
||||
void triqs_gf_view_assign_delegation(gf_view<imtime, scalar_valued> g,
|
||||
gf_keeper<tags::fourier, imfreq, scalar_valued> const& L) {
|
||||
inverse_fourier_impl(g, L.g, scalar_valued());
|
||||
}
|
||||
void triqs_gf_view_assign_delegation(gf_view<imtime, matrix_valued> g,
|
||||
gf_keeper<tags::fourier, imfreq, matrix_valued> const& L) {
|
||||
inverse_fourier_impl(g, L.g, matrix_valued());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,60 +25,55 @@
|
||||
#include <triqs/gfs/imfreq.hpp>
|
||||
#include <triqs/gfs/imtime.hpp>
|
||||
|
||||
namespace triqs { namespace gfs {
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
// First the implementation of the fourier transform
|
||||
void fourier_impl (gf_view<imfreq,scalar_valued> gw , gf_const_view<imtime,scalar_valued> gt, scalar_valued);
|
||||
void fourier_impl (gf_view<imfreq,matrix_valued> gw , gf_const_view<imtime,matrix_valued> gt, matrix_valued);
|
||||
void inverse_fourier_impl (gf_view<imtime,scalar_valued> gt, gf_const_view<imfreq,scalar_valued> gw, scalar_valued);
|
||||
void inverse_fourier_impl (gf_view<imtime,matrix_valued> gt, gf_const_view<imfreq,matrix_valued> gw, matrix_valued);
|
||||
|
||||
inline gf_view<imfreq,matrix_valued> fourier (gf_const_view<imtime,matrix_valued> gt) {
|
||||
int L = (gt.mesh().kind() == full_bins ? gt.mesh().size()-1 : gt.mesh().size() );
|
||||
auto gw = gf<imfreq,matrix_valued>{ {gt.domain(),L}, gt.data().shape().front_pop() };
|
||||
auto V = gw();
|
||||
fourier_impl(V, gt, matrix_valued());
|
||||
return gw;
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_keeper<tags::fourier, imtime, Target> fourier(gf_impl<imtime, Target, Opt, V, C> const& g) {
|
||||
return {g};
|
||||
}
|
||||
inline gf_view<imfreq,scalar_valued> fourier (gf_const_view<imtime,scalar_valued> gt) {
|
||||
int L = (gt.mesh().kind() == full_bins ? gt.mesh().size()-1 : gt.mesh().size() );
|
||||
auto gw = gf<imfreq,scalar_valued>{ {gt.domain(),L} };
|
||||
auto V = gw();
|
||||
fourier_impl(V, gt, scalar_valued());
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_keeper<tags::fourier, imfreq, Target> inverse_fourier(gf_impl<imfreq, Target, Opt, V, C> const& g) {
|
||||
return {g};
|
||||
}
|
||||
|
||||
void triqs_gf_view_assign_delegation(gf_view<imfreq, scalar_valued> g, gf_keeper<tags::fourier, imtime, scalar_valued> const& L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<imfreq, matrix_valued> g, gf_keeper<tags::fourier, imtime, matrix_valued> const& L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<imtime, scalar_valued> g, gf_keeper<tags::fourier, imfreq, scalar_valued> const& L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<imtime, matrix_valued> g, gf_keeper<tags::fourier, imfreq, matrix_valued> const& L);
|
||||
|
||||
template <typename Opt> gf_mesh<imfreq, Opt> make_mesh_fourier_compatible(gf_mesh<imtime, Opt> const& m) {
|
||||
int L = m.size() - (m.kind() == full_bins ? 1 : 0);
|
||||
return {m.domain(), L};
|
||||
}
|
||||
|
||||
template <typename Opt>
|
||||
gf_mesh<imtime, Opt> make_mesh_fourier_compatible(gf_mesh<imfreq, Opt> const& m, mesh_kind mk = full_bins) {
|
||||
int L = m.size() + (mk == full_bins ? 1 : 0);
|
||||
return {m.domain(), L};
|
||||
}
|
||||
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_view<imfreq, Target> make_gf_from_fourier(gf_impl<imtime, Target, Opt, V, C> const& gt) {
|
||||
auto gw = gf<imfreq, Target>{make_mesh_fourier_compatible(gt.mesh()), get_target_shape(gt)};
|
||||
gw() = fourier(gt);
|
||||
return gw;
|
||||
}
|
||||
|
||||
inline gf_view<imtime, matrix_valued> inverse_fourier (gf_const_view<imfreq, matrix_valued> gw, mesh_kind mk = half_bins) {
|
||||
double pi = std::acos(-1);
|
||||
int L = (mk == full_bins ? gw.mesh().size()+1 : gw.mesh().size() );
|
||||
auto gt = gf<imtime,matrix_valued>{ {gw.domain(),L}, gw.data().shape().front_pop()};
|
||||
auto V = gt();
|
||||
inverse_fourier_impl(V, gw, matrix_valued());
|
||||
return gt;
|
||||
}
|
||||
inline gf_view<imtime,scalar_valued> inverse_fourier (gf_const_view<imfreq,scalar_valued> gw, mesh_kind mk = half_bins) {
|
||||
double pi = std::acos(-1);
|
||||
int L = (mk == full_bins ? gw.mesh().size()+1 : gw.mesh().size() );
|
||||
auto gt = gf<imtime,scalar_valued>{ {gw.domain(),L} };
|
||||
auto V = gt();
|
||||
inverse_fourier_impl(V, gw,scalar_valued());
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_view<imtime, Target> make_gf_from_inverse_fourier(gf_impl<imfreq, Target, Opt, V, C> const& gw, mesh_kind mk = full_bins) {
|
||||
auto gt = gf<imtime, Target>{make_mesh_fourier_compatible(gw.mesh(), mk), get_target_shape(gw)};
|
||||
gt() = inverse_fourier(gw);
|
||||
return gt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline gf_keeper<tags::fourier,imtime,scalar_valued> lazy_fourier (gf_const_view<imtime,scalar_valued> g) { return {g};}
|
||||
inline gf_keeper<tags::fourier,imfreq,scalar_valued> lazy_inverse_fourier (gf_const_view<imfreq,scalar_valued> g) { return {g};}
|
||||
inline gf_keeper<tags::fourier,imtime,matrix_valued> lazy_fourier (gf_const_view<imtime,matrix_valued> g) { return {g};}
|
||||
inline gf_keeper<tags::fourier,imfreq,matrix_valued> lazy_inverse_fourier (gf_const_view<imfreq,matrix_valued> g) { return {g};}
|
||||
|
||||
void triqs_gf_view_assign_delegation( gf_view<imfreq,scalar_valued> g, gf_keeper<tags::fourier,imtime,scalar_valued> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<imfreq,matrix_valued> g, gf_keeper<tags::fourier,imtime,matrix_valued> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<imtime,scalar_valued> g, gf_keeper<tags::fourier,imfreq,scalar_valued> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<imtime,matrix_valued> g, gf_keeper<tags::fourier,imfreq,matrix_valued> const & L);
|
||||
}}
|
||||
|
||||
namespace triqs { namespace clef {
|
||||
TRIQS_CLEF_MAKE_FNT_LAZY (lazy_fourier);
|
||||
TRIQS_CLEF_MAKE_FNT_LAZY (lazy_inverse_fourier);
|
||||
}}
|
||||
namespace triqs {
|
||||
namespace clef {
|
||||
TRIQS_CLEF_MAKE_FNT_LAZY(fourier);
|
||||
TRIQS_CLEF_MAKE_FNT_LAZY(inverse_fourier);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
*
|
||||
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||
*
|
||||
* Copyright (C) 2011 by M. Ferrero, O. Parcollet
|
||||
* Copyright (C) 2011-2014 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
|
||||
@ -27,63 +27,50 @@
|
||||
|
||||
namespace triqs { namespace gfs {
|
||||
|
||||
// First the implementation of the fourier transform
|
||||
void fourier_impl (gf_view<refreq,scalar_valued> gw , gf_const_view<retime,scalar_valued> gt, scalar_valued);
|
||||
void fourier_impl (gf_view<refreq,matrix_valued> gw , gf_const_view<retime,matrix_valued> gt, matrix_valued);
|
||||
void inverse_fourier_impl (gf_view<retime,scalar_valued> gt, gf_const_view<refreq,scalar_valued> gw, scalar_valued);
|
||||
void inverse_fourier_impl (gf_view<retime,matrix_valued> gt, gf_const_view<refreq,matrix_valued> gw, matrix_valued);
|
||||
|
||||
inline gf_view<refreq,matrix_valued> fourier (gf_const_view<retime, matrix_valued> gt) {
|
||||
double pi = std::acos(-1);
|
||||
int L = gt.mesh().size();
|
||||
double wmin = -pi * (L-1) / (L*gt.mesh().delta());
|
||||
double wmax = pi * (L-1) / (L*gt.mesh().delta());
|
||||
auto gw = gf<refreq,matrix_valued>{ {wmin, wmax, L}, gt.data().shape().front_pop()};
|
||||
auto V = gw();
|
||||
fourier_impl(V, gt, matrix_valued());
|
||||
return gw;
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_keeper<tags::fourier, retime, Target> fourier(gf_impl<retime, Target, Opt, V, C> const& g) {
|
||||
return {g};
|
||||
}
|
||||
inline gf_view<refreq,scalar_valued> fourier (gf_const_view<retime, scalar_valued> gt) {
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_keeper<tags::fourier, refreq, Target> inverse_fourier(gf_impl<refreq, Target, Opt, V, C> const& g) {
|
||||
return {g};
|
||||
}
|
||||
|
||||
void triqs_gf_view_assign_delegation(gf_view<refreq, scalar_valued> g, gf_keeper<tags::fourier, retime, scalar_valued> const& L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<refreq, matrix_valued> g, gf_keeper<tags::fourier, retime, matrix_valued> const& L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<retime, scalar_valued> g, gf_keeper<tags::fourier, refreq, scalar_valued> const& L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<retime, matrix_valued> g, gf_keeper<tags::fourier, refreq, matrix_valued> const& L);
|
||||
|
||||
template <typename Opt> gf_mesh<refreq, Opt> make_mesh_fourier_compatible(gf_mesh<retime, Opt> const& m) {
|
||||
int L = m.size();
|
||||
double pi = std::acos(-1);
|
||||
int L = gt.mesh().size();
|
||||
double wmin = -pi * (L-1) / (L*gt.mesh().delta());
|
||||
double wmax = pi * (L-1) / (L*gt.mesh().delta());
|
||||
auto gw = gf<refreq,scalar_valued>{ {wmin, wmax, L} };
|
||||
auto V = gw();
|
||||
fourier_impl(V, gt, scalar_valued());
|
||||
double wmin = -pi * (L - 1) / (L * m.delta());
|
||||
double wmax = pi * (L - 1) / (L * m.delta());
|
||||
return {wmin, wmax, L};
|
||||
}
|
||||
|
||||
template <typename Opt>
|
||||
gf_mesh<retime, Opt> make_mesh_fourier_compatible(gf_mesh<refreq, Opt> const& m, mesh_kind mk = full_bins) {
|
||||
double pi = std::acos(-1);
|
||||
int L = m.size();
|
||||
double tmin = -pi * (L-1) / (L*m.delta());
|
||||
double tmax = pi * (L-1) / (L*m.delta());
|
||||
return {tmin, tmax, L};
|
||||
}
|
||||
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_view<refreq, Target> make_gf_from_fourier(gf_impl<retime, Target, Opt, V, C> const& gt) {
|
||||
auto gw = gf<refreq, Target>{make_mesh_fourier_compatible(gt.mesh()), get_target_shape(gt)};
|
||||
gw() = fourier(gt);
|
||||
return gw;
|
||||
}
|
||||
|
||||
inline gf_view<retime,matrix_valued> inverse_fourier (gf_const_view<refreq,matrix_valued> gw) {
|
||||
double pi = std::acos(-1);
|
||||
int L = gw.mesh().size();
|
||||
double tmin = -pi * (L-1) / (L*gw.mesh().delta());
|
||||
double tmax = pi * (L-1) / (L*gw.mesh().delta());
|
||||
auto gt = gf<retime,matrix_valued>{{ tmin, tmax, L} , gw.data().shape().front_pop()};
|
||||
auto V = gt();
|
||||
inverse_fourier_impl(V, gw, matrix_valued());
|
||||
template <typename Target, typename Opt, bool V, bool C>
|
||||
gf_view<retime, Target> make_gf_from_inverse_fourier(gf_impl<refreq, Target, Opt, V, C> const& gw) {
|
||||
auto gt = gf<retime, Target>{make_mesh_fourier_compatible(gw.mesh()), get_target_shape(gw)};
|
||||
gt() = inverse_fourier(gw);
|
||||
return gt;
|
||||
}
|
||||
inline gf_view<retime,scalar_valued> inverse_fourier (gf_const_view<refreq,scalar_valued> gw) {
|
||||
double pi = std::acos(-1);
|
||||
int L = gw.mesh().size();
|
||||
double tmin = -pi * (L-1) / (L*gw.mesh().delta());
|
||||
double tmax = pi * (L-1) / (L*gw.mesh().delta());
|
||||
auto gt = gf<retime,scalar_valued>{ {tmin, tmax, L} };
|
||||
auto V = gt();
|
||||
inverse_fourier_impl(V, gw, scalar_valued());
|
||||
return gt;
|
||||
}
|
||||
|
||||
inline gf_keeper<tags::fourier, retime, scalar_valued> lazy_fourier(gf_const_view<retime, scalar_valued> g) { return {g}; }
|
||||
inline gf_keeper<tags::fourier, refreq, scalar_valued> lazy_inverse_fourier(gf_const_view<refreq, scalar_valued> g) { return {g}; }
|
||||
inline gf_keeper<tags::fourier, retime, matrix_valued> lazy_fourier(gf_const_view<retime, matrix_valued> g) { return {g}; }
|
||||
inline gf_keeper<tags::fourier, refreq, matrix_valued> lazy_inverse_fourier(gf_const_view<refreq, matrix_valued> g) { return {g}; }
|
||||
|
||||
void triqs_gf_view_assign_delegation( gf_view<refreq,scalar_valued> g, gf_keeper<tags::fourier,retime,scalar_valued> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<refreq,matrix_valued> g, gf_keeper<tags::fourier,retime,matrix_valued> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<retime,scalar_valued> g, gf_keeper<tags::fourier,refreq,scalar_valued> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<retime,matrix_valued> g, gf_keeper<tags::fourier,refreq,matrix_valued> const & L);
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
@ -1,9 +1,8 @@
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||
*
|
||||
* Copyright (C) 2011 by L. Boehnke, M. Ferrero, O. Parcollet
|
||||
* Copyright (C) 2011-2014 by L. Boehnke, 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
|
||||
@ -27,25 +26,63 @@
|
||||
|
||||
using namespace triqs::utility;
|
||||
|
||||
namespace triqs { namespace gfs {
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
void legendre_matsubara_direct(gf_view<imfreq> & gw, gf_const_view<legendre> gl) {
|
||||
// ----------------------------
|
||||
|
||||
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];
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
// ----------------------------
|
||||
|
||||
void legendre_matsubara_inverse (gf_view<legendre> & gl, gf_const_view<imfreq> gw) {
|
||||
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());
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
|
||||
void legendre_matsubara_inverse(gf_view<legendre> gl, gf_const_view<imtime> gt) {
|
||||
|
||||
gl() = 0.0;
|
||||
legendre_generator L;
|
||||
|
||||
// Do the integral over imaginary time
|
||||
for (auto t : gt.mesh()) {
|
||||
L.reset(2 * t / gt.domain().beta - 1);
|
||||
for (auto l : gl.mesh()) {
|
||||
gl[l] += sqrt(2 * l.index() + 1) * L.next() * gt[t];
|
||||
}
|
||||
}
|
||||
gl.data() *= gt.mesh().delta();
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
|
||||
void legendre_matsubara_inverse(gf_view<legendre> gl, gf_const_view<imfreq> gw) {
|
||||
|
||||
gl() = 0.0;
|
||||
|
||||
@ -53,64 +90,25 @@ void legendre_matsubara_inverse (gf_view<legendre> & gl, gf_const_view<imfreq>
|
||||
// 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, half_bins}, gw.data().shape().front_pop() };
|
||||
auto gt = gf<imtime>{{gw.domain(), Nt, half_bins}, gw.data().shape().front_pop()};
|
||||
|
||||
// We first transform to imaginary time because it's been coded with the knowledge of the tails
|
||||
gt() = lazy_inverse_fourier(gw);
|
||||
gt() = inverse_fourier(gw);
|
||||
legendre_matsubara_inverse(gl, gt());
|
||||
|
||||
}
|
||||
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
void legendre_matsubara_inverse (gf_view<legendre> & gl, gf_const_view<imtime> gt) {
|
||||
|
||||
gl() = 0.0;
|
||||
legendre_generator L;
|
||||
|
||||
// Do the integral over imaginary time
|
||||
for (auto t : gt.mesh()) {
|
||||
L.reset( 2*t/gt.domain().beta-1 );
|
||||
for (auto l : gl.mesh()) {
|
||||
gl[l] += sqrt(2*l.index()+1) * L.next() * gt[t];
|
||||
}
|
||||
}
|
||||
gl.data() *= gt.mesh().delta();
|
||||
|
||||
}
|
||||
|
||||
|
||||
gf_keeper<tags::legendre,legendre> lazy_legendre_imfreq (gf_const_view<legendre> gl) { return {gl}; }
|
||||
gf_keeper<tags::legendre,legendre> lazy_legendre_imtime (gf_const_view<legendre> gl) { return {gl}; }
|
||||
gf_keeper<tags::legendre,imfreq> lazy_imfreq_legendre (gf_const_view<imfreq> gw) { return {gw}; }
|
||||
gf_keeper<tags::legendre,imtime> lazy_imtime_legendre (gf_const_view<imtime> gt) { return {gt}; }
|
||||
|
||||
void triqs_gf_view_assign_delegation( gf_view<imfreq> &gw, gf_keeper<tags::legendre,legendre> const & L) {
|
||||
void triqs_gf_view_assign_delegation(gf_view<imfreq> gw, gf_keeper<tags::legendre, legendre> const& L) {
|
||||
legendre_matsubara_direct(gw, L.g);
|
||||
}
|
||||
void triqs_gf_view_assign_delegation( gf_view<imtime> >, gf_keeper<tags::legendre,legendre> const & L) {
|
||||
}
|
||||
void triqs_gf_view_assign_delegation(gf_view<imtime> gt, gf_keeper<tags::legendre, legendre> const& L) {
|
||||
legendre_matsubara_direct(gt, L.g);
|
||||
}
|
||||
void triqs_gf_view_assign_delegation( gf_view<legendre> &gl, gf_keeper<tags::legendre,imfreq> const & L) {
|
||||
}
|
||||
void triqs_gf_view_assign_delegation(gf_view<legendre> gl, gf_keeper<tags::legendre, imfreq> const& L) {
|
||||
legendre_matsubara_inverse(gl, L.g);
|
||||
}
|
||||
void triqs_gf_view_assign_delegation( gf_view<legendre> &gl, gf_keeper<tags::legendre,imtime> const & L) {
|
||||
}
|
||||
void triqs_gf_view_assign_delegation(gf_view<legendre> gl, gf_keeper<tags::legendre, imtime> const& L) {
|
||||
legendre_matsubara_inverse(gl, L.g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -1,9 +1,8 @@
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||
*
|
||||
* Copyright (C) 2011 by L. Boehnke, M. Ferrero, O. Parcollet
|
||||
* Copyright (C) 2011-2014 by L. Boehnke, 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
|
||||
@ -26,26 +25,30 @@
|
||||
#include <triqs/gfs/imtime.hpp>
|
||||
#include <triqs/gfs/legendre.hpp>
|
||||
|
||||
namespace triqs { namespace gfs {
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
void legendre_matsubara_direct (gf_view<imfreq> &gw, gf_const_view<legendre> gl);
|
||||
void legendre_matsubara_inverse (gf_view<legendre> &gl, gf_const_view<imfreq> gw);
|
||||
namespace tags {
|
||||
struct legendre {};
|
||||
}
|
||||
|
||||
void legendre_matsubara_direct (gf_view<imtime> >, gf_const_view<legendre> gl);
|
||||
void legendre_matsubara_inverse (gf_view<legendre> &gl, gf_const_view<imtime> gt);
|
||||
inline gf_keeper<tags::legendre, legendre> legendre_to_imfreq(gf_const_view<legendre> gl) {
|
||||
return {gl};
|
||||
}
|
||||
inline gf_keeper<tags::legendre, legendre> legendre_to_imtime(gf_const_view<legendre> gl) {
|
||||
return {gl};
|
||||
}
|
||||
inline gf_keeper<tags::legendre, imfreq> imfreq_to_legendre(gf_const_view<imfreq> gw) {
|
||||
return {gw};
|
||||
}
|
||||
inline gf_keeper<tags::legendre, imtime> imtime_to_legendre(gf_const_view<imtime> gt) {
|
||||
return {gt};
|
||||
}
|
||||
|
||||
namespace tags { struct legendre{}; }
|
||||
|
||||
gf_keeper<tags::legendre,legendre> lazy_legendre_imfreq (gf_const_view<legendre> gl);
|
||||
gf_keeper<tags::legendre,legendre> lazy_legendre_imtime (gf_const_view<legendre> gl);
|
||||
gf_keeper<tags::legendre,imfreq> lazy_imfreq_legendre (gf_const_view<imfreq> gw);
|
||||
gf_keeper<tags::legendre,imtime> lazy_imtime_legendre (gf_const_view<imtime> gt);
|
||||
|
||||
void triqs_gf_view_assign_delegation( gf_view<imfreq> &gw, gf_keeper<tags::legendre,legendre> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<imtime> >, gf_keeper<tags::legendre,legendre> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<legendre> &gl, gf_keeper<tags::legendre,imfreq> const & L);
|
||||
void triqs_gf_view_assign_delegation( gf_view<legendre> &gl, gf_keeper<tags::legendre,imtime> const & L);
|
||||
|
||||
|
||||
}}
|
||||
void triqs_gf_view_assign_delegation(gf_view<imfreq> gw, gf_keeper<tags::legendre, legendre> const &L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<imtime> gt, gf_keeper<tags::legendre, legendre> const &L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<legendre> gl, gf_keeper<tags::legendre, imfreq> const &L);
|
||||
void triqs_gf_view_assign_delegation(gf_view<legendre> gl, gf_keeper<tags::legendre, imtime> const &L);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
48
triqs/gfs/local/no_tail.hpp
Normal file
48
triqs/gfs/local/no_tail.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||
*
|
||||
* Copyright (C) 2013-2014 by 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
#include "../tools.hpp"
|
||||
#include "../gf.hpp"
|
||||
#include "./tail.hpp"
|
||||
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
struct no_tail {};
|
||||
|
||||
template <typename Variable, typename Target, bool V, bool C>
|
||||
gf_view<Variable, Target, no_tail, C> make_gf_view_without_tail(gf_impl<Variable, Target, void, V, C> const &g) {
|
||||
return {g.mesh(), g.data(), {}, g.symmetry()};
|
||||
}
|
||||
|
||||
template <typename Variable, typename Target, bool V, bool C>
|
||||
gf_view<Variable, Target> make_gf_from_g_and_tail(gf_impl<Variable, Target, no_tail, V, C> const &g, local::tail t) {
|
||||
auto g2 = gf<Variable, Target, no_tail>{g}; // copy the function without tail
|
||||
return {std::move(g2.mesh()), std::move(g2.data()), std::move(t), g2.symmetry()};
|
||||
}
|
||||
|
||||
template <typename Variable, typename Target, bool V, bool C>
|
||||
gf_view<Variable, Target, void, C> make_gf_view_from_g_and_tail(gf_impl<Variable, Target, no_tail, V, C> const &g,
|
||||
local::tail_view t) {
|
||||
return {g.mesh(), g.data(), t, g.symmetry()};
|
||||
}
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ namespace gfs {
|
||||
|
||||
linear_mesh() : _dom(), L(0), a_pt(0), b_pt(0), xmin(0), xmax(0), del(0), meshk(half_bins) {}
|
||||
|
||||
linear_mesh(domain_t dom, double a, double b, size_t n_pts, mesh_kind mk)
|
||||
explicit linear_mesh(domain_t dom, double a, double b, size_t n_pts, mesh_kind mk)
|
||||
: _dom(std::move(dom)), L(n_pts), a_pt(a), b_pt(b), meshk(mk) {
|
||||
switch (mk) {
|
||||
case half_bins:
|
||||
|
@ -50,6 +50,8 @@ namespace triqs { namespace gfs {
|
||||
|
||||
struct freq_infty{}; // the point at infinity
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
inline std::vector<std::string> split(const std::string &s, char delim){
|
||||
std::vector<std::string> elems;
|
||||
std::stringstream ss(s);
|
||||
|
Loading…
Reference in New Issue
Block a user