
(FPCore (x) :precision binary64 (asinh x))
double code(double x) {
return asinh(x);
}
def code(x): return math.asinh(x)
function code(x) return asinh(x) end
function tmp = code(x) tmp = asinh(x); end
code[x_] := N[ArcSinh[x], $MachinePrecision]
\begin{array}{l}
\\
\sinh^{-1} x
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 2 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x) :precision binary64 (copysign (log (+ (fabs x) (sqrt (+ (* x x) 1.0)))) x))
double code(double x) {
return copysign(log((fabs(x) + sqrt(((x * x) + 1.0)))), x);
}
public static double code(double x) {
return Math.copySign(Math.log((Math.abs(x) + Math.sqrt(((x * x) + 1.0)))), x);
}
def code(x): return math.copysign(math.log((math.fabs(x) + math.sqrt(((x * x) + 1.0)))), x)
function code(x) return copysign(log(Float64(abs(x) + sqrt(Float64(Float64(x * x) + 1.0)))), x) end
function tmp = code(x) tmp = sign(x) * abs(log((abs(x) + sqrt(((x * x) + 1.0))))); end
code[x_] := N[With[{TMP1 = Abs[N[Log[N[(N[Abs[x], $MachinePrecision] + N[Sqrt[N[(N[(x * x), $MachinePrecision] + 1.0), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]], $MachinePrecision]], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
\begin{array}{l}
\\
\mathsf{copysign}\left(\log \left(\left|x\right| + \sqrt{x \cdot x + 1}\right), x\right)
\end{array}
(FPCore (x) :precision binary64 (copysign (asinh x) x))
double code(double x) {
return copysign(asinh(x), x);
}
def code(x): return math.copysign(math.asinh(x), x)
function code(x) return copysign(asinh(x), x) end
function tmp = code(x) tmp = sign(x) * abs(asinh(x)); end
code[x_] := N[With[{TMP1 = Abs[N[ArcSinh[x], $MachinePrecision]], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
\begin{array}{l}
\\
\mathsf{copysign}\left(\sinh^{-1} x, x\right)
\end{array}
Initial program 32.6%
lift-log.f64N/A
lift-+.f64N/A
lift-fabs.f64N/A
lift-sqrt.f64N/A
lift-+.f64N/A
lift-*.f64N/A
pow2N/A
+-commutativeN/A
+-commutativeN/A
pow2N/A
sqr-abs-revN/A
asinh-def-revN/A
rem-sqrt-square-revN/A
pow2N/A
sqrt-pow1N/A
metadata-evalN/A
unpow1N/A
lower-asinh.f6499.9
Applied rewrites99.9%
(FPCore (x)
:precision binary64
(let* ((t_0 (pow (+ 1.0 x) -2.0)))
(copysign
(fma
(fma
(fma
(* 0.001388888888888889 (* x x))
(+ (fma 45.0 t_0 (/ 30.0 (pow (+ 1.0 x) 3.0))) (/ 45.0 (+ 1.0 x)))
(* (fma t_0 3.0 (/ 3.0 (+ 1.0 x))) -0.041666666666666664))
(* x x)
(/ 0.5 (+ 1.0 x)))
(* x x)
(log1p x))
x)))
double code(double x) {
double t_0 = pow((1.0 + x), -2.0);
return copysign(fma(fma(fma((0.001388888888888889 * (x * x)), (fma(45.0, t_0, (30.0 / pow((1.0 + x), 3.0))) + (45.0 / (1.0 + x))), (fma(t_0, 3.0, (3.0 / (1.0 + x))) * -0.041666666666666664)), (x * x), (0.5 / (1.0 + x))), (x * x), log1p(x)), x);
}
function code(x) t_0 = Float64(1.0 + x) ^ -2.0 return copysign(fma(fma(fma(Float64(0.001388888888888889 * Float64(x * x)), Float64(fma(45.0, t_0, Float64(30.0 / (Float64(1.0 + x) ^ 3.0))) + Float64(45.0 / Float64(1.0 + x))), Float64(fma(t_0, 3.0, Float64(3.0 / Float64(1.0 + x))) * -0.041666666666666664)), Float64(x * x), Float64(0.5 / Float64(1.0 + x))), Float64(x * x), log1p(x)), x) end
code[x_] := Block[{t$95$0 = N[Power[N[(1.0 + x), $MachinePrecision], -2.0], $MachinePrecision]}, N[With[{TMP1 = Abs[N[(N[(N[(N[(0.001388888888888889 * N[(x * x), $MachinePrecision]), $MachinePrecision] * N[(N[(45.0 * t$95$0 + N[(30.0 / N[Power[N[(1.0 + x), $MachinePrecision], 3.0], $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(45.0 / N[(1.0 + x), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(N[(t$95$0 * 3.0 + N[(3.0 / N[(1.0 + x), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] * -0.041666666666666664), $MachinePrecision]), $MachinePrecision] * N[(x * x), $MachinePrecision] + N[(0.5 / N[(1.0 + x), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] * N[(x * x), $MachinePrecision] + N[Log[1 + x], $MachinePrecision]), $MachinePrecision]], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := {\left(1 + x\right)}^{-2}\\
\mathsf{copysign}\left(\mathsf{fma}\left(\mathsf{fma}\left(\mathsf{fma}\left(0.001388888888888889 \cdot \left(x \cdot x\right), \mathsf{fma}\left(45, t\_0, \frac{30}{{\left(1 + x\right)}^{3}}\right) + \frac{45}{1 + x}, \mathsf{fma}\left(t\_0, 3, \frac{3}{1 + x}\right) \cdot -0.041666666666666664\right), x \cdot x, \frac{0.5}{1 + x}\right), x \cdot x, \mathsf{log1p}\left(x\right)\right), x\right)
\end{array}
\end{array}
Initial program 32.6%
Taylor expanded in x around 0
Applied rewrites47.7%
herbie shell --seed 2025057
(FPCore (x)
:name "Rust f64::asinh"
:precision binary64
:alt
(! :herbie-platform herbie20 (let* ((ax (fabs x)) (ix (/ 1 ax))) (copysign (log1p (+ ax (/ ax (+ (hypot 1 ix) ix)))) x)))
(copysign (log (+ (fabs x) (sqrt (+ (* x x) 1.0)))) x))