
(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 4 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.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 <= 5.1e-29) {
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 <= 5.1e-29) {
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 <= 5.1e-29: 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 <= 5.1e-29) 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, 5.1e-29], 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 5.1 \cdot 10^{-29}:\\
\;\;\;\;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 < 5.09999999999999986e-29Initial program 95.9%
metadata-eval95.9%
Simplified95.9%
*-un-lft-identity95.9%
*-commutative95.9%
log-prod95.9%
sub-neg95.9%
add-sqr-sqrt44.9%
sqrt-unprod95.9%
sqr-neg95.9%
sqrt-unprod51.0%
add-sqr-sqrt94.5%
diff-log94.5%
log1p-undefine6.1%
log1p-undefine94.5%
metadata-eval94.5%
Applied egg-rr94.5%
+-rgt-identity94.5%
+-inverses94.5%
Simplified94.5%
if 5.09999999999999986e-29 < x Initial program 34.5%
Simplified84.4%
Final simplification94.2%
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.0 (+ x_m (* (pow x_m 3.0) 0.3333333333333333)))))
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.0;
} else {
tmp = x_m + (pow(x_m, 3.0) * 0.3333333333333333);
}
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 <= 5.1d-29) then
tmp = 0.0d0
else
tmp = x_m + ((x_m ** 3.0d0) * 0.3333333333333333d0)
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 <= 5.1e-29) {
tmp = 0.0;
} else {
tmp = x_m + (Math.pow(x_m, 3.0) * 0.3333333333333333);
}
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.0 else: tmp = x_m + (math.pow(x_m, 3.0) * 0.3333333333333333) 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 = 0.0; else tmp = Float64(x_m + Float64((x_m ^ 3.0) * 0.3333333333333333)); 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 <= 5.1e-29) tmp = 0.0; else tmp = x_m + ((x_m ^ 3.0) * 0.3333333333333333); 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, 5.1e-29], 0.0, N[(x$95$m + N[(N[Power[x$95$m, 3.0], $MachinePrecision] * 0.3333333333333333), $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\\
\mathbf{else}:\\
\;\;\;\;x\_m + {x\_m}^{3} \cdot 0.3333333333333333\\
\end{array}
\end{array}
if x < 5.09999999999999986e-29Initial program 95.9%
metadata-eval95.9%
Simplified95.9%
*-un-lft-identity95.9%
*-commutative95.9%
log-prod95.9%
sub-neg95.9%
add-sqr-sqrt44.9%
sqrt-unprod95.9%
sqr-neg95.9%
sqrt-unprod51.0%
add-sqr-sqrt94.5%
diff-log94.5%
log1p-undefine6.1%
log1p-undefine94.5%
metadata-eval94.5%
Applied egg-rr94.5%
+-rgt-identity94.5%
+-inverses94.5%
Simplified94.5%
if 5.09999999999999986e-29 < x Initial program 34.5%
metadata-eval34.5%
Simplified34.5%
Taylor expanded in x around 0 80.8%
*-commutative80.8%
Simplified80.8%
Final simplification94.0%
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.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 <= 5.1e-29) {
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 <= 5.1d-29) 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 <= 5.1e-29) {
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 <= 5.1e-29: 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 <= 5.1e-29) 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 <= 5.1e-29) 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, 5.1e-29], 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 5.1 \cdot 10^{-29}:\\
\;\;\;\;0\\
\mathbf{else}:\\
\;\;\;\;x\_m\\
\end{array}
\end{array}
if x < 5.09999999999999986e-29Initial program 95.9%
metadata-eval95.9%
Simplified95.9%
*-un-lft-identity95.9%
*-commutative95.9%
log-prod95.9%
sub-neg95.9%
add-sqr-sqrt44.9%
sqrt-unprod95.9%
sqr-neg95.9%
sqrt-unprod51.0%
add-sqr-sqrt94.5%
diff-log94.5%
log1p-undefine6.1%
log1p-undefine94.5%
metadata-eval94.5%
Applied egg-rr94.5%
+-rgt-identity94.5%
+-inverses94.5%
Simplified94.5%
if 5.09999999999999986e-29 < x Initial program 34.5%
metadata-eval34.5%
Simplified34.5%
Taylor expanded in x around 0 78.2%
Final simplification93.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 93.8%
metadata-eval93.8%
Simplified93.8%
Taylor expanded in x around 0 11.2%
Final simplification11.2%
herbie shell --seed 2024047
(FPCore (x)
:name "Hyperbolic arc-(co)tangent"
:precision binary64
(* (/ 1.0 2.0) (log (/ (+ 1.0 x) (- 1.0 x)))))