diff options
-rw-r--r-- | log-fourier.cpp | 24 | ||||
-rw-r--r-- | log-fourier.hpp | 4 | ||||
-rw-r--r-- | log-fourier_integrator.cpp | 27 |
3 files changed, 49 insertions, 6 deletions
diff --git a/log-fourier.cpp b/log-fourier.cpp index d5ac17d..345e490 100644 --- a/log-fourier.cpp +++ b/log-fourier.cpp @@ -190,7 +190,7 @@ Real estimateZ(LogarithmicFourierTransform& fft, const std::vector<Real>& C, con return ((2 * Γ₀ * std::conj(Rt[0]) + std::pow(β, 2) * (RddfCt[0] * Ct[0] + dfCt[0] * std::conj(Rt[0]))) / Ct[0]).real(); } -Real energy(const LogarithmicFourierTransform& fft, std::vector<Real>& C, const std::vector<Real>& R, unsigned p, unsigned s, Real λ, Real β) { +Real energy(const LogarithmicFourierTransform& fft, const std::vector<Real>& C, const std::vector<Real>& R, unsigned p, unsigned s, Real λ, Real β) { unsigned n₀ = 0; for (unsigned n = 0; n < C.size(); n++) { if (C[n] > 1 || R[n] > 1) n₀ = n % 2 == 0 ? n / 2 : (n + 1) / 2; @@ -221,3 +221,25 @@ Real energy(const LogarithmicFourierTransform& fft, std::vector<Real>& C, const return β * E; } +Real C0(const LogarithmicFourierTransform& fft, const std::vector<Complex>& Ĉ) { + Real C = 0; + for (unsigned n = 0; n < Ĉ.size()/2-1; n++) { + Real Ĉ₂ₙ = Ĉ[2*n].real(); + Real Ĉ₂ₙ₊₁ = Ĉ[2*n+1].real(); + Real Ĉ₂ₙ₊₂ = Ĉ[2*n+2].real(); + + Real h₂ₙ = fft.t(2*n+1) - fft.t(2*n); + Real h₂ₙ₊₁ = fft.t(2*n+2) - fft.t(2*n+1); + Real f₂ₙ = Ĉ₂ₙ; + Real f₂ₙ₊₁ = Ĉ₂ₙ₊₁; + Real f₂ₙ₊₂ = Ĉ₂ₙ₊₂; + + C += (h₂ₙ + h₂ₙ₊₁) / 6 * ( + (2 - h₂ₙ₊₁ / h₂ₙ) * f₂ₙ + + std::pow(h₂ₙ + h₂ₙ₊₁, 2) / (h₂ₙ * h₂ₙ₊₁) * f₂ₙ₊₁ + + (2 - h₂ₙ / h₂ₙ₊₁) * f₂ₙ₊₂ + ); + } + return C / M_PI; +} + diff --git a/log-fourier.hpp b/log-fourier.hpp index b5bb4c0..9c7c237 100644 --- a/log-fourier.hpp +++ b/log-fourier.hpp @@ -43,4 +43,6 @@ std::tuple<std::vector<Complex>, std::vector<Complex>> RddfCtdfCt(LogarithmicFou Real estimateZ(LogarithmicFourierTransform& fft, const std::vector<Real>& C, const std::vector<Complex>& Ct, const std::vector<Real>& R, const std::vector<Complex>& Rt, unsigned p, unsigned s, Real λ, Real τ₀, Real β); -Real energy(const LogarithmicFourierTransform& fft, std::vector<Real>& C, const std::vector<Real>& R, unsigned p, unsigned s, Real λ, Real β); +Real energy(const LogarithmicFourierTransform& fft, const std::vector<Real>& C, const std::vector<Real>& R, unsigned p, unsigned s, Real λ, Real β); + +Real C0(const LogarithmicFourierTransform& fft, const std::vector<Complex>& Ĉ); diff --git a/log-fourier_integrator.cpp b/log-fourier_integrator.cpp index 0e05366..5ff27a4 100644 --- a/log-fourier_integrator.cpp +++ b/log-fourier_integrator.cpp @@ -138,14 +138,33 @@ int main(int argc, char* argv[]) { std::vector<Complex> Ĉₜ₊₁(N); std::vector<Complex> Ȓₜ₊₁(N); + + Real C₀ = 0; + Real μ₊ = 0; + Real μ₋ = 0; + + while (std::abs(C₀ - 1) > ε) { + for (unsigned n = 0; n < N; n++) { + Ĉₜ₊₁[n] = ((2 * Γ₀ * std::conj(Ȓₜ[n]) / (1 + std::pow(τ₀ * fft.ν(n), 2)) + std::pow(β, 2) * (RddfCt[n] * Ĉₜ[n] + dfCt[n] * std::conj(Ȓₜ[n]))) / (μₜ + II * fft.ν(n))).real(); + } + C₀ = C0(fft, Ĉₜ₊₁); + if (C₀ > 1) { + μ₋ = μₜ; + } else { + μ₊ = μₜ; + } + if (μ₋ > 0 && μ₊ > 0) { + μₜ = (μ₊ + μ₋) / 2; + } else { + μₜ *= C₀; + } + } + for (unsigned n = 0; n < N; n++) { Ȓₜ₊₁[n] = ((Real)1.0 + std::pow(β, 2) * RddfCt[n] * Ȓₜ[n]) / (μₜ + II * fft.ν(n)); - Ĉₜ₊₁[n] = ((2 * Γ₀ * std::conj(Ȓₜ[n]) / (1 + std::pow(τ₀ * fft.ν(n), 2)) + std::pow(β, 2) * (RddfCt[n] * Ĉₜ[n] + dfCt[n] * std::conj(Ȓₜ[n]))) / (μₜ + II * fft.ν(n))).real(); } - std::vector<Real> Rₜ₊₁ = fft.inverse(Ȓₜ₊₁); std::vector<Real> Cₜ₊₁ = fft.inverse(Ĉₜ₊₁); - - Real C₀ = Cₜ₊₁[0]; + std::vector<Real> Rₜ₊₁ = fft.inverse(Ȓₜ₊₁); if (!std::isnan(Cₜ₊₁[0])) { |