@@ -70,29 +70,37 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
7070 return r.value ();
7171
7272 float xf = x;
73- // High precision for inputs very close to 1.0
74- // For inputs close to 1 (1 <= x < 1.25), use polynomial approximation:
73+ // High precision polynomial approximation for inputs very close to 1.0
74+ // Specifically, for inputs within the range [1, 1.25), we employ the
75+ // following step-by-step Taylor expansion derivation to maintain numerical
76+ // accuracy:
7577 //
7678 // Step-by-step derivation:
77- // 1. Let y = acosh(x), thus x = cosh(y).
79+ // 1. Define y = acosh(x), thus by definition x = cosh(y).
7880 //
79- // 2. Rewrite cosh identity using exponential form :
81+ // 2. Expand cosh(y) using exponential identities :
8082 // cosh(y) = (e^y + e^{-y}) / 2
81- // For y close to 0 , let y = sqrt(2 * delta), thus:
82- // x = cosh(y) ≈ 1 + delta (since cosh(0) = 1, and delta is small)
83- // thus delta = x - 1.
83+ // For small y , let us set y ≈ sqrt(2 * delta), thus:
84+ // x ≈ cosh(y) ≈ 1 + delta, for small delta
85+ // hence delta = x - 1.
8486 //
85- // 3: Express y in terms of delta (for small delta):
86- // y ≈ sqrt(2 * delta)
87+ // 3. Express y explicitly in terms of delta (for small delta):
88+ // y = acosh(1 + delta) ≈ sqrt(2 * delta) for very small delta.
8789 //
88- // 4: Expand acosh(1 + delta) using a Taylor expansion around delta = 0:
89- // acosh(1 + delta) ≈ sqrt(2 * delta) * P(delta), where P(delta)
90- // is a polynomial approximation obtained by fitting the function
91- // precisely in the interval [0, 0.25].
90+ // 4. Use Taylor expansion around delta = 0 to obtain a more accurate
91+ // polynomial:
92+ // acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160 -
93+ // 5*delta^3/896 + 35*delta^4/18432 + ...] For practical computation and
94+ // precision, truncate and fit the polynomial precisely in the range [0,
95+ // 0.25].
9296 //
93- // Because delta = x - 1 and 0 <= delta < 0.25, the polynomial approximation
94- // remains numerically stable and accurate in this domain, ensuring high
95- // precision.
97+ // 5. The implemented polynomial approximation (coefficients obtained from
98+ // careful numerical fitting) is:
99+ // P(delta) ≈ 1 - 0x1.55551ap-4 * delta + 0x1.33160cp-6 * delta^2 -
100+ // 0x1.6890f4p-8 * delta^3 + 0x1.8f3a62p-10 * delta^4
101+ //
102+ // Since delta = x - 1, and 0 <= delta < 0.25, this approximation achieves
103+ // high precision and numerical stability.
96104 if (LIBC_UNLIKELY (xf < 1 .25f )) {
97105 float delta = xf - 1 .0f ;
98106 float sqrt_2_delta = fputil::sqrt<float >(2.0 * delta);
0 commit comments