
(FPCore (x) :precision binary64 (atanh x))
double code(double x) {
return atanh(x);
}
def code(x): return math.atanh(x)
function code(x) return atanh(x) end
function tmp = code(x) tmp = atanh(x); end
code[x_] := N[ArcTanh[x], $MachinePrecision]
\tanh^{-1} x
Herbie found 5 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x) :precision binary64 (* 0.5 (log1p (/ (* 2.0 x) (- 1.0 x)))))
double code(double x) {
return 0.5 * log1p(((2.0 * x) / (1.0 - x)));
}
public static double code(double x) {
return 0.5 * Math.log1p(((2.0 * x) / (1.0 - x)));
}
def code(x): return 0.5 * math.log1p(((2.0 * x) / (1.0 - x)))
function code(x) return Float64(0.5 * log1p(Float64(Float64(2.0 * x) / Float64(1.0 - x)))) end
code[x_] := N[(0.5 * N[Log[1 + N[(N[(2.0 * x), $MachinePrecision] / N[(1.0 - x), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]
0.5 \cdot \mathsf{log1p}\left(\frac{2 \cdot x}{1 - x}\right)
(FPCore (x) :precision binary64 (* (copysign 1.0 x) (if (<= (fabs x) 0.023) (* 0.5 (log1p (/ (+ (fabs x) (fabs x)) (- 1.0 (fabs x))))) (log 1.0))))
double code(double x) {
double tmp;
if (fabs(x) <= 0.023) {
tmp = 0.5 * log1p(((fabs(x) + fabs(x)) / (1.0 - fabs(x))));
} else {
tmp = log(1.0);
}
return copysign(1.0, x) * tmp;
}
public static double code(double x) {
double tmp;
if (Math.abs(x) <= 0.023) {
tmp = 0.5 * Math.log1p(((Math.abs(x) + Math.abs(x)) / (1.0 - Math.abs(x))));
} else {
tmp = Math.log(1.0);
}
return Math.copySign(1.0, x) * tmp;
}
def code(x): tmp = 0 if math.fabs(x) <= 0.023: tmp = 0.5 * math.log1p(((math.fabs(x) + math.fabs(x)) / (1.0 - math.fabs(x)))) else: tmp = math.log(1.0) return math.copysign(1.0, x) * tmp
function code(x) tmp = 0.0 if (abs(x) <= 0.023) tmp = Float64(0.5 * log1p(Float64(Float64(abs(x) + abs(x)) / Float64(1.0 - abs(x))))); else tmp = log(1.0); end return Float64(copysign(1.0, x) * tmp) end
code[x_] := N[(N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision] * If[LessEqual[N[Abs[x], $MachinePrecision], 0.023], N[(0.5 * N[Log[1 + N[(N[(N[Abs[x], $MachinePrecision] + N[Abs[x], $MachinePrecision]), $MachinePrecision] / N[(1.0 - N[Abs[x], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision], N[Log[1.0], $MachinePrecision]]), $MachinePrecision]
\mathsf{copysign}\left(1, x\right) \cdot \begin{array}{l}
\mathbf{if}\;\left|x\right| \leq 0.023:\\
\;\;\;\;0.5 \cdot \mathsf{log1p}\left(\frac{\left|x\right| + \left|x\right|}{1 - \left|x\right|}\right)\\
\mathbf{else}:\\
\;\;\;\;\log 1\\
\end{array}
if x < 0.023Initial program 50.4%
lift-*.f64N/A
count-2-revN/A
lower-+.f6450.4%
Applied rewrites50.4%
if 0.023 < x Initial program 50.4%
lift-*.f64N/A
lift-log1p.f64N/A
log-pow-revN/A
lower-log.f64N/A
unpow1/2N/A
lower-sqrt.f64N/A
+-commutativeN/A
lift-/.f64N/A
lift-*.f64N/A
associate-/l*N/A
*-commutativeN/A
lower-fma.f64N/A
lower-/.f644.1%
Applied rewrites4.1%
Taylor expanded in x around 0
lower-+.f644.4%
Applied rewrites4.4%
Taylor expanded in x around 0
Applied rewrites52.3%
(FPCore (x) :precision binary64 (* (copysign 1.0 x) (if (<= (fabs x) 0.023) (* (log1p (* (fma (fabs x) (fabs x) (fabs x)) 2.0)) 0.5) (log 1.0))))
double code(double x) {
double tmp;
if (fabs(x) <= 0.023) {
tmp = log1p((fma(fabs(x), fabs(x), fabs(x)) * 2.0)) * 0.5;
} else {
tmp = log(1.0);
}
return copysign(1.0, x) * tmp;
}
function code(x) tmp = 0.0 if (abs(x) <= 0.023) tmp = Float64(log1p(Float64(fma(abs(x), abs(x), abs(x)) * 2.0)) * 0.5); else tmp = log(1.0); end return Float64(copysign(1.0, x) * tmp) end
code[x_] := N[(N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision] * If[LessEqual[N[Abs[x], $MachinePrecision], 0.023], N[(N[Log[1 + N[(N[(N[Abs[x], $MachinePrecision] * N[Abs[x], $MachinePrecision] + N[Abs[x], $MachinePrecision]), $MachinePrecision] * 2.0), $MachinePrecision]], $MachinePrecision] * 0.5), $MachinePrecision], N[Log[1.0], $MachinePrecision]]), $MachinePrecision]
\mathsf{copysign}\left(1, x\right) \cdot \begin{array}{l}
\mathbf{if}\;\left|x\right| \leq 0.023:\\
\;\;\;\;\mathsf{log1p}\left(\mathsf{fma}\left(\left|x\right|, \left|x\right|, \left|x\right|\right) \cdot 2\right) \cdot 0.5\\
\mathbf{else}:\\
\;\;\;\;\log 1\\
\end{array}
if x < 0.023Initial program 50.4%
lift-*.f64N/A
*-commutativeN/A
lower-*.f6450.4%
lift-log1p.f64N/A
lower-log.f64N/A
+-commutativeN/A
lift-/.f64N/A
lift-*.f64N/A
associate-/l*N/A
*-commutativeN/A
lower-fma.f64N/A
lower-/.f644.1%
Applied rewrites4.1%
Taylor expanded in x around 0
lower-*.f64N/A
lower-+.f645.0%
Applied rewrites5.0%
lift-log.f64N/A
lift-fma.f64N/A
+-commutativeN/A
lower-log1p.f64N/A
lower-*.f6451.1%
lift-*.f64N/A
lift-+.f64N/A
distribute-rgt-inN/A
*-lft-identityN/A
+-commutativeN/A
lower-fma.f6451.1%
Applied rewrites51.1%
if 0.023 < x Initial program 50.4%
lift-*.f64N/A
lift-log1p.f64N/A
log-pow-revN/A
lower-log.f64N/A
unpow1/2N/A
lower-sqrt.f64N/A
+-commutativeN/A
lift-/.f64N/A
lift-*.f64N/A
associate-/l*N/A
*-commutativeN/A
lower-fma.f64N/A
lower-/.f644.1%
Applied rewrites4.1%
Taylor expanded in x around 0
lower-+.f644.4%
Applied rewrites4.4%
Taylor expanded in x around 0
Applied rewrites52.3%
(FPCore (x) :precision binary64 (* (copysign 1.0 x) (if (<= (fabs x) 0.023) (* 0.5 (log1p (* (fabs x) 2.0))) (log 1.0))))
double code(double x) {
double tmp;
if (fabs(x) <= 0.023) {
tmp = 0.5 * log1p((fabs(x) * 2.0));
} else {
tmp = log(1.0);
}
return copysign(1.0, x) * tmp;
}
public static double code(double x) {
double tmp;
if (Math.abs(x) <= 0.023) {
tmp = 0.5 * Math.log1p((Math.abs(x) * 2.0));
} else {
tmp = Math.log(1.0);
}
return Math.copySign(1.0, x) * tmp;
}
def code(x): tmp = 0 if math.fabs(x) <= 0.023: tmp = 0.5 * math.log1p((math.fabs(x) * 2.0)) else: tmp = math.log(1.0) return math.copysign(1.0, x) * tmp
function code(x) tmp = 0.0 if (abs(x) <= 0.023) tmp = Float64(0.5 * log1p(Float64(abs(x) * 2.0))); else tmp = log(1.0); end return Float64(copysign(1.0, x) * tmp) end
code[x_] := N[(N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision] * If[LessEqual[N[Abs[x], $MachinePrecision], 0.023], N[(0.5 * N[Log[1 + N[(N[Abs[x], $MachinePrecision] * 2.0), $MachinePrecision]], $MachinePrecision]), $MachinePrecision], N[Log[1.0], $MachinePrecision]]), $MachinePrecision]
\mathsf{copysign}\left(1, x\right) \cdot \begin{array}{l}
\mathbf{if}\;\left|x\right| \leq 0.023:\\
\;\;\;\;0.5 \cdot \mathsf{log1p}\left(\left|x\right| \cdot 2\right)\\
\mathbf{else}:\\
\;\;\;\;\log 1\\
\end{array}
if x < 0.023Initial program 50.4%
lift-*.f64N/A
count-2-revN/A
lower-+.f6450.4%
Applied rewrites50.4%
Taylor expanded in x around 0
lower-*.f64N/A
lower-+.f64N/A
lower-*.f6451.1%
Applied rewrites51.1%
Taylor expanded in x around 0
Applied rewrites50.2%
if 0.023 < x Initial program 50.4%
lift-*.f64N/A
lift-log1p.f64N/A
log-pow-revN/A
lower-log.f64N/A
unpow1/2N/A
lower-sqrt.f64N/A
+-commutativeN/A
lift-/.f64N/A
lift-*.f64N/A
associate-/l*N/A
*-commutativeN/A
lower-fma.f64N/A
lower-/.f644.1%
Applied rewrites4.1%
Taylor expanded in x around 0
lower-+.f644.4%
Applied rewrites4.4%
Taylor expanded in x around 0
Applied rewrites52.3%
(FPCore (x) :precision binary64 (log 1.0))
double code(double x) {
return log(1.0);
}
real(8) function code(x)
use fmin_fmax_functions
real(8), intent (in) :: x
code = log(1.0d0)
end function
public static double code(double x) {
return Math.log(1.0);
}
def code(x): return math.log(1.0)
function code(x) return log(1.0) end
function tmp = code(x) tmp = log(1.0); end
code[x_] := N[Log[1.0], $MachinePrecision]
\log 1
Initial program 50.4%
lift-*.f64N/A
lift-log1p.f64N/A
log-pow-revN/A
lower-log.f64N/A
unpow1/2N/A
lower-sqrt.f64N/A
+-commutativeN/A
lift-/.f64N/A
lift-*.f64N/A
associate-/l*N/A
*-commutativeN/A
lower-fma.f64N/A
lower-/.f644.1%
Applied rewrites4.1%
Taylor expanded in x around 0
lower-+.f644.4%
Applied rewrites4.4%
Taylor expanded in x around 0
Applied rewrites52.3%
(FPCore (x) :precision binary64 (/ 1.0 x))
double code(double x) {
return 1.0 / x;
}
real(8) function code(x)
use fmin_fmax_functions
real(8), intent (in) :: x
code = 1.0d0 / x
end function
public static double code(double x) {
return 1.0 / x;
}
def code(x): return 1.0 / x
function code(x) return Float64(1.0 / x) end
function tmp = code(x) tmp = 1.0 / x; end
code[x_] := N[(1.0 / x), $MachinePrecision]
\frac{1}{x}
Initial program 50.4%
lift-log1p.f64N/A
lift-/.f64N/A
add-to-fractionN/A
log-divN/A
diff-logN/A
fabs-divN/A
add-to-fractionN/A
lift-/.f64N/A
lower-log.f64N/A
add-flipN/A
fabs-subN/A
lower-fabs.f64N/A
sub-flipN/A
metadata-evalN/A
Applied rewrites51.7%
Taylor expanded in x around inf
lower-/.f644.6%
Applied rewrites4.6%
herbie shell --seed 2025313 -o setup:search
(FPCore (x)
:name "Rust f64::atanh"
:precision binary64
(* 0.5 (log1p (/ (* 2.0 x) (- 1.0 x)))))