From 717558730554dbb470fbda0700f14fc43595063d Mon Sep 17 00:00:00 2001
From: Jaron Kent-Dobias <jaron@kent-dobias.com>
Date: Fri, 18 Apr 2025 20:04:58 -0300
Subject: Got the log-fourier method working, but integrator is not working
 correctly

---
 fourier.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 43 insertions(+), 15 deletions(-)

(limited to 'fourier.cpp')

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";
 }
-- 
cgit v1.2.3-70-g09d2