
(FPCore (x) :precision binary64 (* (/ 1.0 2.0) (log (/ (+ 1.0 x) (- 1.0 x)))))
double code(double x) {
return (1.0 / 2.0) * log(((1.0 + x) / (1.0 - x)));
}
real(8) function code(x)
real(8), intent (in) :: x
code = (1.0d0 / 2.0d0) * log(((1.0d0 + x) / (1.0d0 - x)))
end function
public static double code(double x) {
return (1.0 / 2.0) * Math.log(((1.0 + x) / (1.0 - x)));
}
def code(x): return (1.0 / 2.0) * math.log(((1.0 + x) / (1.0 - x)))
function code(x) return Float64(Float64(1.0 / 2.0) * log(Float64(Float64(1.0 + x) / Float64(1.0 - x)))) end
function tmp = code(x) tmp = (1.0 / 2.0) * log(((1.0 + x) / (1.0 - x))); end
code[x_] := N[(N[(1.0 / 2.0), $MachinePrecision] * N[Log[N[(N[(1.0 + x), $MachinePrecision] / N[(1.0 - x), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{1}{2} \cdot \log \left(\frac{1 + x}{1 - x}\right)
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 5 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x) :precision binary64 (* (/ 1.0 2.0) (log (/ (+ 1.0 x) (- 1.0 x)))))
double code(double x) {
return (1.0 / 2.0) * log(((1.0 + x) / (1.0 - x)));
}
real(8) function code(x)
real(8), intent (in) :: x
code = (1.0d0 / 2.0d0) * log(((1.0d0 + x) / (1.0d0 - x)))
end function
public static double code(double x) {
return (1.0 / 2.0) * Math.log(((1.0 + x) / (1.0 - x)));
}
def code(x): return (1.0 / 2.0) * math.log(((1.0 + x) / (1.0 - x)))
function code(x) return Float64(Float64(1.0 / 2.0) * log(Float64(Float64(1.0 + x) / Float64(1.0 - x)))) end
function tmp = code(x) tmp = (1.0 / 2.0) * log(((1.0 + x) / (1.0 - x))); end
code[x_] := N[(N[(1.0 / 2.0), $MachinePrecision] * N[Log[N[(N[(1.0 + x), $MachinePrecision] / N[(1.0 - x), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{1}{2} \cdot \log \left(\frac{1 + x}{1 - x}\right)
\end{array}
x_m = (fabs.f64 x)
x_s = (copysign.f64 1 x)
(FPCore (x_s x_m)
:precision binary64
(*
x_s
(if (<= x_m 7.5e-68)
0.0
(+
x_m
(+
(* 0.14285714285714285 (pow x_m 7.0))
(+ (* 0.2 (pow x_m 5.0)) (* 0.3333333333333333 (pow x_m 3.0))))))))x_m = fabs(x);
x_s = copysign(1.0, x);
double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = x_m + ((0.14285714285714285 * pow(x_m, 7.0)) + ((0.2 * pow(x_m, 5.0)) + (0.3333333333333333 * pow(x_m, 3.0))));
}
return x_s * tmp;
}
x_m = abs(x)
x_s = copysign(1.0d0, x)
real(8) function code(x_s, x_m)
real(8), intent (in) :: x_s
real(8), intent (in) :: x_m
real(8) :: tmp
if (x_m <= 7.5d-68) then
tmp = 0.0d0
else
tmp = x_m + ((0.14285714285714285d0 * (x_m ** 7.0d0)) + ((0.2d0 * (x_m ** 5.0d0)) + (0.3333333333333333d0 * (x_m ** 3.0d0))))
end if
code = x_s * tmp
end function
x_m = Math.abs(x);
x_s = Math.copySign(1.0, x);
public static double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = x_m + ((0.14285714285714285 * Math.pow(x_m, 7.0)) + ((0.2 * Math.pow(x_m, 5.0)) + (0.3333333333333333 * Math.pow(x_m, 3.0))));
}
return x_s * tmp;
}
x_m = math.fabs(x) x_s = math.copysign(1.0, x) def code(x_s, x_m): tmp = 0 if x_m <= 7.5e-68: tmp = 0.0 else: tmp = x_m + ((0.14285714285714285 * math.pow(x_m, 7.0)) + ((0.2 * math.pow(x_m, 5.0)) + (0.3333333333333333 * math.pow(x_m, 3.0)))) return x_s * tmp
x_m = abs(x) x_s = copysign(1.0, x) function code(x_s, x_m) tmp = 0.0 if (x_m <= 7.5e-68) tmp = 0.0; else tmp = Float64(x_m + Float64(Float64(0.14285714285714285 * (x_m ^ 7.0)) + Float64(Float64(0.2 * (x_m ^ 5.0)) + Float64(0.3333333333333333 * (x_m ^ 3.0))))); end return Float64(x_s * tmp) end
x_m = abs(x); x_s = sign(x) * abs(1.0); function tmp_2 = code(x_s, x_m) tmp = 0.0; if (x_m <= 7.5e-68) tmp = 0.0; else tmp = x_m + ((0.14285714285714285 * (x_m ^ 7.0)) + ((0.2 * (x_m ^ 5.0)) + (0.3333333333333333 * (x_m ^ 3.0)))); end tmp_2 = x_s * tmp; end
x_m = N[Abs[x], $MachinePrecision]
x_s = N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
code[x$95$s_, x$95$m_] := N[(x$95$s * If[LessEqual[x$95$m, 7.5e-68], 0.0, N[(x$95$m + N[(N[(0.14285714285714285 * N[Power[x$95$m, 7.0], $MachinePrecision]), $MachinePrecision] + N[(N[(0.2 * N[Power[x$95$m, 5.0], $MachinePrecision]), $MachinePrecision] + N[(0.3333333333333333 * N[Power[x$95$m, 3.0], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]]), $MachinePrecision]
\begin{array}{l}
x_m = \left|x\right|
\\
x_s = \mathsf{copysign}\left(1, x\right)
\\
x\_s \cdot \begin{array}{l}
\mathbf{if}\;x\_m \leq 7.5 \cdot 10^{-68}:\\
\;\;\;\;0\\
\mathbf{else}:\\
\;\;\;\;x\_m + \left(0.14285714285714285 \cdot {x\_m}^{7} + \left(0.2 \cdot {x\_m}^{5} + 0.3333333333333333 \cdot {x\_m}^{3}\right)\right)\\
\end{array}
\end{array}
if x < 7.50000000000000081e-68Initial program 91.6%
metadata-eval91.6%
Simplified91.6%
Applied egg-rr89.7%
count-289.7%
+-inverses89.7%
metadata-eval89.7%
Simplified89.7%
if 7.50000000000000081e-68 < x Initial program 13.5%
metadata-eval13.5%
Simplified13.5%
Taylor expanded in x around 0 100.0%
Final simplification90.9%
x_m = (fabs.f64 x) x_s = (copysign.f64 1 x) (FPCore (x_s x_m) :precision binary64 (* x_s (if (<= x_m 7.5e-68) 0.0 (* 0.5 (- (log1p x_m) (log1p (- x_m)))))))
x_m = fabs(x);
x_s = copysign(1.0, x);
double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = 0.5 * (log1p(x_m) - log1p(-x_m));
}
return x_s * tmp;
}
x_m = Math.abs(x);
x_s = Math.copySign(1.0, x);
public static double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = 0.5 * (Math.log1p(x_m) - Math.log1p(-x_m));
}
return x_s * tmp;
}
x_m = math.fabs(x) x_s = math.copysign(1.0, x) def code(x_s, x_m): tmp = 0 if x_m <= 7.5e-68: tmp = 0.0 else: tmp = 0.5 * (math.log1p(x_m) - math.log1p(-x_m)) return x_s * tmp
x_m = abs(x) x_s = copysign(1.0, x) function code(x_s, x_m) tmp = 0.0 if (x_m <= 7.5e-68) tmp = 0.0; else tmp = Float64(0.5 * Float64(log1p(x_m) - log1p(Float64(-x_m)))); end return Float64(x_s * tmp) end
x_m = N[Abs[x], $MachinePrecision]
x_s = N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
code[x$95$s_, x$95$m_] := N[(x$95$s * If[LessEqual[x$95$m, 7.5e-68], 0.0, N[(0.5 * N[(N[Log[1 + x$95$m], $MachinePrecision] - N[Log[1 + (-x$95$m)], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]]), $MachinePrecision]
\begin{array}{l}
x_m = \left|x\right|
\\
x_s = \mathsf{copysign}\left(1, x\right)
\\
x\_s \cdot \begin{array}{l}
\mathbf{if}\;x\_m \leq 7.5 \cdot 10^{-68}:\\
\;\;\;\;0\\
\mathbf{else}:\\
\;\;\;\;0.5 \cdot \left(\mathsf{log1p}\left(x\_m\right) - \mathsf{log1p}\left(-x\_m\right)\right)\\
\end{array}
\end{array}
if x < 7.50000000000000081e-68Initial program 91.6%
metadata-eval91.6%
Simplified91.6%
Applied egg-rr89.7%
count-289.7%
+-inverses89.7%
metadata-eval89.7%
Simplified89.7%
if 7.50000000000000081e-68 < x Initial program 13.5%
metadata-eval13.5%
log-div13.6%
log1p-def25.3%
sub-neg25.3%
log1p-def99.9%
Simplified99.9%
Final simplification90.9%
x_m = (fabs.f64 x) x_s = (copysign.f64 1 x) (FPCore (x_s x_m) :precision binary64 (* x_s (if (<= x_m 7.5e-68) 0.0 (+ x_m (* 0.3333333333333333 (pow x_m 3.0))))))
x_m = fabs(x);
x_s = copysign(1.0, x);
double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = x_m + (0.3333333333333333 * pow(x_m, 3.0));
}
return x_s * tmp;
}
x_m = abs(x)
x_s = copysign(1.0d0, x)
real(8) function code(x_s, x_m)
real(8), intent (in) :: x_s
real(8), intent (in) :: x_m
real(8) :: tmp
if (x_m <= 7.5d-68) then
tmp = 0.0d0
else
tmp = x_m + (0.3333333333333333d0 * (x_m ** 3.0d0))
end if
code = x_s * tmp
end function
x_m = Math.abs(x);
x_s = Math.copySign(1.0, x);
public static double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = x_m + (0.3333333333333333 * Math.pow(x_m, 3.0));
}
return x_s * tmp;
}
x_m = math.fabs(x) x_s = math.copysign(1.0, x) def code(x_s, x_m): tmp = 0 if x_m <= 7.5e-68: tmp = 0.0 else: tmp = x_m + (0.3333333333333333 * math.pow(x_m, 3.0)) return x_s * tmp
x_m = abs(x) x_s = copysign(1.0, x) function code(x_s, x_m) tmp = 0.0 if (x_m <= 7.5e-68) tmp = 0.0; else tmp = Float64(x_m + Float64(0.3333333333333333 * (x_m ^ 3.0))); end return Float64(x_s * tmp) end
x_m = abs(x); x_s = sign(x) * abs(1.0); function tmp_2 = code(x_s, x_m) tmp = 0.0; if (x_m <= 7.5e-68) tmp = 0.0; else tmp = x_m + (0.3333333333333333 * (x_m ^ 3.0)); end tmp_2 = x_s * tmp; end
x_m = N[Abs[x], $MachinePrecision]
x_s = N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
code[x$95$s_, x$95$m_] := N[(x$95$s * If[LessEqual[x$95$m, 7.5e-68], 0.0, N[(x$95$m + N[(0.3333333333333333 * N[Power[x$95$m, 3.0], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]]), $MachinePrecision]
\begin{array}{l}
x_m = \left|x\right|
\\
x_s = \mathsf{copysign}\left(1, x\right)
\\
x\_s \cdot \begin{array}{l}
\mathbf{if}\;x\_m \leq 7.5 \cdot 10^{-68}:\\
\;\;\;\;0\\
\mathbf{else}:\\
\;\;\;\;x\_m + 0.3333333333333333 \cdot {x\_m}^{3}\\
\end{array}
\end{array}
if x < 7.50000000000000081e-68Initial program 91.6%
metadata-eval91.6%
Simplified91.6%
Applied egg-rr89.7%
count-289.7%
+-inverses89.7%
metadata-eval89.7%
Simplified89.7%
if 7.50000000000000081e-68 < x Initial program 13.5%
metadata-eval13.5%
Simplified13.5%
Taylor expanded in x around 0 100.0%
*-commutative100.0%
Simplified100.0%
Final simplification90.9%
x_m = (fabs.f64 x) x_s = (copysign.f64 1 x) (FPCore (x_s x_m) :precision binary64 (* x_s (if (<= x_m 7.5e-68) 0.0 x_m)))
x_m = fabs(x);
x_s = copysign(1.0, x);
double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = x_m;
}
return x_s * tmp;
}
x_m = abs(x)
x_s = copysign(1.0d0, x)
real(8) function code(x_s, x_m)
real(8), intent (in) :: x_s
real(8), intent (in) :: x_m
real(8) :: tmp
if (x_m <= 7.5d-68) then
tmp = 0.0d0
else
tmp = x_m
end if
code = x_s * tmp
end function
x_m = Math.abs(x);
x_s = Math.copySign(1.0, x);
public static double code(double x_s, double x_m) {
double tmp;
if (x_m <= 7.5e-68) {
tmp = 0.0;
} else {
tmp = x_m;
}
return x_s * tmp;
}
x_m = math.fabs(x) x_s = math.copysign(1.0, x) def code(x_s, x_m): tmp = 0 if x_m <= 7.5e-68: tmp = 0.0 else: tmp = x_m return x_s * tmp
x_m = abs(x) x_s = copysign(1.0, x) function code(x_s, x_m) tmp = 0.0 if (x_m <= 7.5e-68) tmp = 0.0; else tmp = x_m; end return Float64(x_s * tmp) end
x_m = abs(x); x_s = sign(x) * abs(1.0); function tmp_2 = code(x_s, x_m) tmp = 0.0; if (x_m <= 7.5e-68) tmp = 0.0; else tmp = x_m; end tmp_2 = x_s * tmp; end
x_m = N[Abs[x], $MachinePrecision]
x_s = N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
code[x$95$s_, x$95$m_] := N[(x$95$s * If[LessEqual[x$95$m, 7.5e-68], 0.0, x$95$m]), $MachinePrecision]
\begin{array}{l}
x_m = \left|x\right|
\\
x_s = \mathsf{copysign}\left(1, x\right)
\\
x\_s \cdot \begin{array}{l}
\mathbf{if}\;x\_m \leq 7.5 \cdot 10^{-68}:\\
\;\;\;\;0\\
\mathbf{else}:\\
\;\;\;\;x\_m\\
\end{array}
\end{array}
if x < 7.50000000000000081e-68Initial program 91.6%
metadata-eval91.6%
Simplified91.6%
Applied egg-rr89.7%
count-289.7%
+-inverses89.7%
metadata-eval89.7%
Simplified89.7%
if 7.50000000000000081e-68 < x Initial program 13.5%
metadata-eval13.5%
Simplified13.5%
Taylor expanded in x around 0 99.4%
Final simplification90.9%
x_m = (fabs.f64 x) x_s = (copysign.f64 1 x) (FPCore (x_s x_m) :precision binary64 (* x_s x_m))
x_m = fabs(x);
x_s = copysign(1.0, x);
double code(double x_s, double x_m) {
return x_s * x_m;
}
x_m = abs(x)
x_s = copysign(1.0d0, x)
real(8) function code(x_s, x_m)
real(8), intent (in) :: x_s
real(8), intent (in) :: x_m
code = x_s * x_m
end function
x_m = Math.abs(x);
x_s = Math.copySign(1.0, x);
public static double code(double x_s, double x_m) {
return x_s * x_m;
}
x_m = math.fabs(x) x_s = math.copysign(1.0, x) def code(x_s, x_m): return x_s * x_m
x_m = abs(x) x_s = copysign(1.0, x) function code(x_s, x_m) return Float64(x_s * x_m) end
x_m = abs(x); x_s = sign(x) * abs(1.0); function tmp = code(x_s, x_m) tmp = x_s * x_m; end
x_m = N[Abs[x], $MachinePrecision]
x_s = N[With[{TMP1 = Abs[1.0], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision]
code[x$95$s_, x$95$m_] := N[(x$95$s * x$95$m), $MachinePrecision]
\begin{array}{l}
x_m = \left|x\right|
\\
x_s = \mathsf{copysign}\left(1, x\right)
\\
x\_s \cdot x\_m
\end{array}
Initial program 82.4%
metadata-eval82.4%
Simplified82.4%
Taylor expanded in x around 0 25.2%
Final simplification25.2%
herbie shell --seed 2024031
(FPCore (x)
:name "Hyperbolic arc-(co)tangent"
:precision binary64
(* (/ 1.0 2.0) (log (/ (+ 1.0 x) (- 1.0 x)))))