DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
Loading...
Searching...
No Matches
LogCosh.h
1// DSPark - Professional Audio DSP Framework
2// Copyright (c) 2026 Cristian Moresi - MIT License
3#pragma once
4
5#include <cmath>
6
7namespace dspark::detail {
8
10template <typename T>
11inline T logCosh(T x) noexcept
12{
13 const T a = std::abs(x);
14 // The usual large-argument identity subtracts nearly equal numbers
15 // around zero. This series also preserves small-signal ADAA accuracy.
16 if (a < T(0.01))
17 {
18 const T z = x * x;
19 return z * (T(0.5) + z * (T(-1.0 / 12.0)
20 + z * (T(1.0 / 45.0) + z * T(-17.0 / 2520.0))));
21 }
22 return a + std::log1p(std::exp(T(-2) * a)) - T(0.6931471805599453);
23}
24
30inline double integralLogCosh(double x) noexcept
31{
32 const double a = std::abs(x);
33 if (a < 1.0)
34 {
35 const double z = a * a;
36 constexpr double coefficients[] = {
37 -7.98389023185534e-11, 8.6684720203723614e-10,
38 -4.7997095383377807e-9, 1.8850617466346369e-8,
39 -6.1974137503985441e-8, 1.8914247025489175e-7,
40 -5.6812797392185565e-7, 1.7247571922095787e-6,
41 -5.3522004257752879e-6, 1.7105344959469917e-5,
42 -5.6815608632124677e-5, 0.00019881353180096906,
43 -0.00074955908287299841, 0.0031746031746026004,
44 -0.016666666666666659, 0.16666666666666666
45 };
46 double p = 0.0;
47 for (double c : coefficients) p = p * z + c;
48 return x * z * p;
49 }
50 const double z = std::exp(-2.0 * a);
51 double li = 1.0 / 256.0;
52 for (int k = 15; k >= 1; --k)
53 li = li * z + (k % 2 == 0 ? 1.0 : -1.0) / (k * k);
54 li *= z;
55 return std::copysign(0.5 * a * a - a * 0.6931471805599453
56 + 0.5 * (li + 0.8224670334241132), x);
57}
58
59} // namespace dspark::detail
double integralLogCosh(double x) noexcept
Definition LogCosh.h:30
T logCosh(T x) noexcept
Definition LogCosh.h:11