
(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 2 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 5.1e-29)
(* 0.5 (log (/ (+ x_m 1.0) (- 1.0 x_m))))
(* 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 <= 5.1e-29) {
tmp = 0.5 * log(((x_m + 1.0) / (1.0 - x_m)));
} 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 <= 5.1e-29) {
tmp = 0.5 * Math.log(((x_m + 1.0) / (1.0 - x_m)));
} 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 <= 5.1e-29: tmp = 0.5 * math.log(((x_m + 1.0) / (1.0 - x_m))) 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 <= 5.1e-29) tmp = Float64(0.5 * log(Float64(Float64(x_m + 1.0) / Float64(1.0 - x_m)))); 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, 5.1e-29], N[(0.5 * N[Log[N[(N[(x$95$m + 1.0), $MachinePrecision] / N[(1.0 - x$95$m), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision], 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 5.1 \cdot 10^{-29}:\\
\;\;\;\;0.5 \cdot \log \left(\frac{x\_m + 1}{1 - x\_m}\right)\\
\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 < 5.09999999999999986e-29Initial program 96.9%
metadata-eval96.9%
Simplified96.9%
if 5.09999999999999986e-29 < x Initial program 55.9%
metadata-eval55.9%
log-div55.2%
log1p-def57.1%
sub-neg57.1%
log1p-def97.5%
Simplified97.5%
Final simplification96.9%
x_m = (fabs.f64 x) x_s = (copysign.f64 1 x) (FPCore (x_s x_m) :precision binary64 (* x_s (* 0.5 (log (/ (+ x_m 1.0) (- 1.0 x_m))))))
x_m = fabs(x);
x_s = copysign(1.0, x);
double code(double x_s, double x_m) {
return x_s * (0.5 * log(((x_m + 1.0) / (1.0 - 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 * (0.5d0 * log(((x_m + 1.0d0) / (1.0d0 - 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 * (0.5 * Math.log(((x_m + 1.0) / (1.0 - x_m))));
}
x_m = math.fabs(x) x_s = math.copysign(1.0, x) def code(x_s, x_m): return x_s * (0.5 * math.log(((x_m + 1.0) / (1.0 - x_m))))
x_m = abs(x) x_s = copysign(1.0, x) function code(x_s, x_m) return Float64(x_s * Float64(0.5 * log(Float64(Float64(x_m + 1.0) / Float64(1.0 - x_m))))) end
x_m = abs(x); x_s = sign(x) * abs(1.0); function tmp = code(x_s, x_m) tmp = x_s * (0.5 * log(((x_m + 1.0) / (1.0 - 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 * N[(0.5 * N[Log[N[(N[(x$95$m + 1.0), $MachinePrecision] / N[(1.0 - x$95$m), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
x_m = \left|x\right|
\\
x_s = \mathsf{copysign}\left(1, x\right)
\\
x\_s \cdot \left(0.5 \cdot \log \left(\frac{x\_m + 1}{1 - x\_m}\right)\right)
\end{array}
Initial program 95.6%
metadata-eval95.6%
Simplified95.6%
Final simplification95.6%
herbie shell --seed 2024039
(FPCore (x)
:name "Hyperbolic arc-(co)tangent"
:precision binary64
(* (/ 1.0 2.0) (log (/ (+ 1.0 x) (- 1.0 x)))))