diff options
Diffstat (limited to 'fourier.cpp')
-rw-r--r-- | fourier.cpp | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/fourier.cpp b/fourier.cpp index cf45ad1..bb1c92f 100644 --- a/fourier.cpp +++ b/fourier.cpp @@ -1,5 +1,5 @@ #include "fourier.hpp" -#include <boost/multiprecision/fwd.hpp> +#include <fftw3.h> inline Real fP(unsigned p, Real q) { return 0.5 * pow(q, p); @@ -100,15 +100,15 @@ void FourierTransform::writeToA(unsigned i, Real ai) { a[i] = ai; } -LogarithmicFourierTransform::LogarithmicFourierTransform(unsigned N, Real k, Real Δω, Real Δτ, Real Δs) : N(N), k(k), Δτ(Δτ), Δω(Δω), Δs(Δs) { +LogarithmicFourierTransform::LogarithmicFourierTransform(unsigned N, Real k, Real Δτ, unsigned pad) : N(N), pad(pad), k(k), Δτ(Δτ) { τₛ = -0.5 * N; ωₛ = -0.5 * N; - sₛ = -0.5 * N; - a = reinterpret_cast<Complex*>(fftw_alloc_complex(N)); - â = reinterpret_cast<Complex*>(fftw_alloc_complex(N)); + sₛ = -0.5 * pad * N; + a = reinterpret_cast<Complex*>(fftw_alloc_complex(pad*N)); + â = reinterpret_cast<Complex*>(fftw_alloc_complex(pad*N)); fftw_import_wisdom_from_filename("fftw.wisdom"); - a_to_â = fftw_plan_dft_1d(N, reinterpret_cast<fftw_complex*>(a), reinterpret_cast<fftw_complex*>(â), 1, 0); - â_to_a = fftw_plan_dft_1d(N, reinterpret_cast<fftw_complex*>(â), reinterpret_cast<fftw_complex*>(a), 1, 0); + a_to_â = fftw_plan_dft_1d(pad*N, reinterpret_cast<fftw_complex*>(a), reinterpret_cast<fftw_complex*>(â), FFTW_BACKWARD, 0); + â_to_a = fftw_plan_dft_1d(pad*N, reinterpret_cast<fftw_complex*>(â), reinterpret_cast<fftw_complex*>(a), FFTW_BACKWARD, 0); fftw_export_wisdom_to_filename("fftw.wisdom"); } @@ -125,11 +125,11 @@ Real LogarithmicFourierTransform::τ(unsigned n) const { } Real LogarithmicFourierTransform::ω(unsigned n) const { - return Δω * (n + ωₛ); + return Δτ * (n + ωₛ); } Real LogarithmicFourierTransform::s(unsigned n) const { - return Δs * (n + sₛ); + return (n + sₛ) * 2*M_PI / (pad * N * Δτ); } Real LogarithmicFourierTransform::t(unsigned n) const { @@ -149,29 +149,57 @@ Complex gamma(Complex z) { return exp(logΓ.val + 1i * argΓ.val); } -std::vector<Complex> LogarithmicFourierTransform::fourier(const std::vector<Real>& c, bool symmetric){ +std::vector<Complex> LogarithmicFourierTransform::fourier(const std::vector<Real>& c, bool symmetric) { std::vector<Complex> ĉ(N); std::vector<Real> σs = {1}; if (symmetric){ σs.push_back(-1); } for (Real σ : σs) { - for (unsigned n = 0; n < N; n++) { - a[n] = c[n] * exp((1 - k) * τ(n)); + for (unsigned n = 0; n < pad*N; n++) { + if (n < N) { + a[n] = c[n] * exp((1 - k) * τ(n)); + } else { + a[n] = 0; + } } fftw_execute(a_to_â); - for (unsigned n = 0; n < N; n++) { - â[(n + N / 2) % N] *= pow(-1i * σ, 1i * (s(n)) - k) * gamma(k - 1i * (s(n))); + for (unsigned n = 0; n < pad*N; n++) { + â[(pad*N / 2 + n) % (pad*N)] *= pow(1i * σ, 1i * s(n) - k) * gamma(k - 1i * s(n)); } fftw_execute(â_to_a); for (unsigned n = 0; n < N; n++) { - ĉ[n] += exp(-k * ω(n) * 4 * M_PI) * a[n] / pow(2 * M_PI, 1); + ĉ[n] += exp(-k * ω(n)) * a[(pad - 1)*N+n].real() / (Real)(pad*N); } } return ĉ; } +std::vector<Real> LogarithmicFourierTransform::inverse(const std::vector<Complex>& ĉ) { + std::vector<Real> c(N); + std::vector<Real> σs = {1, -1}; + for (Real σ : σs) { + for (unsigned n = 0; n < pad * N; n++) { + if (n < N) { + a[n] = ĉ[n] * exp((1 - k) * ω(n)); + } else { + a[n] = 0; + } + } + fftw_execute(a_to_â); + for (unsigned n = 0; n < pad*N; n++) { + â[(pad*N / 2 + n) % (pad*N)] *= pow(-1i * σ, 1i * s(n) - k) * gamma(k - 1i * s(n)); + } + fftw_execute(â_to_a); + for (unsigned n = 0; n < N; n++) { + c[n] += exp(-k * τ(n)) * a[(pad - 1)*N+n].real() / (Real)(pad*N) / (2 * M_PI); + } + } + + return c; +} + std::string fourierFile(std::string prefix, unsigned p, unsigned s, Real λ, Real τ₀, Real y, unsigned log2n, Real τₘₐₓ) { return prefix + "_" + std::to_string(p) + "_" + std::to_string(s) + "_" + std::to_string(λ) + "_" + std::to_string(τ₀) + "_" + std::to_string(y) + "_" + std::to_string(log2n) + "_" + std::to_string(τₘₐₓ) + ".dat"; } |