
(FPCore (x) :precision binary32 (atanh x))
float code(float x) {
return atanhf(x);
}
function code(x) return atanh(x) end
function tmp = code(x) tmp = atanh(x); end
\begin{array}{l}
\\
\tanh^{-1} x
\end{array}
Sampling outcomes in binary32 precision:
Herbie found 10 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x) :precision binary32 (* 0.5 (log1p (/ (* 2.0 x) (- 1.0 x)))))
float code(float x) {
return 0.5f * log1pf(((2.0f * x) / (1.0f - x)));
}
function code(x) return Float32(Float32(0.5) * log1p(Float32(Float32(Float32(2.0) * x) / Float32(Float32(1.0) - x)))) end
\begin{array}{l}
\\
0.5 \cdot \mathsf{log1p}\left(\frac{2 \cdot x}{1 - x}\right)
\end{array}
(FPCore (x) :precision binary32 (* 0.5 (log1p (/ (* 2.0 x) (- 1.0 x)))))
float code(float x) {
return 0.5f * log1pf(((2.0f * x) / (1.0f - x)));
}
function code(x) return Float32(Float32(0.5) * log1p(Float32(Float32(Float32(2.0) * x) / Float32(Float32(1.0) - x)))) end
\begin{array}{l}
\\
0.5 \cdot \mathsf{log1p}\left(\frac{2 \cdot x}{1 - x}\right)
\end{array}
Initial program 99.8%
(FPCore (x) :precision binary32 (* 0.5 (log1p (* x (/ -2.0 (+ x -1.0))))))
float code(float x) {
return 0.5f * log1pf((x * (-2.0f / (x + -1.0f))));
}
function code(x) return Float32(Float32(0.5) * log1p(Float32(x * Float32(Float32(-2.0) / Float32(x + Float32(-1.0)))))) end
\begin{array}{l}
\\
0.5 \cdot \mathsf{log1p}\left(x \cdot \frac{-2}{x + -1}\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
(FPCore (x)
:precision binary32
(*
0.5
(*
x
(+
2.0
(+
-1.0
(+
1.0
(*
x
(*
x
(+
0.6666666666666666
(* x (* x (+ 0.4 (* x (* x 0.2857142857142857))))))))))))))
float code(float x) {
return 0.5f * (x * (2.0f + (-1.0f + (1.0f + (x * (x * (0.6666666666666666f + (x * (x * (0.4f + (x * (x * 0.2857142857142857f))))))))))));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * (x * (2.0e0 + ((-1.0e0) + (1.0e0 + (x * (x * (0.6666666666666666e0 + (x * (x * (0.4e0 + (x * (x * 0.2857142857142857e0))))))))))))
end function
function code(x) return Float32(Float32(0.5) * Float32(x * Float32(Float32(2.0) + Float32(Float32(-1.0) + Float32(Float32(1.0) + Float32(x * Float32(x * Float32(Float32(0.6666666666666666) + Float32(x * Float32(x * Float32(Float32(0.4) + Float32(x * Float32(x * Float32(0.2857142857142857)))))))))))))) end
function tmp = code(x) tmp = single(0.5) * (x * (single(2.0) + (single(-1.0) + (single(1.0) + (x * (x * (single(0.6666666666666666) + (x * (x * (single(0.4) + (x * (x * single(0.2857142857142857))))))))))))); end
\begin{array}{l}
\\
0.5 \cdot \left(x \cdot \left(2 + \left(-1 + \left(1 + x \cdot \left(x \cdot \left(0.6666666666666666 + x \cdot \left(x \cdot \left(0.4 + x \cdot \left(x \cdot 0.2857142857142857\right)\right)\right)\right)\right)\right)\right)\right)\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 99.5%
unpow299.5%
associate-*l*99.5%
unpow299.5%
*-commutative99.5%
unpow299.5%
Simplified99.5%
expm1-log1p-u99.5%
expm1-undefine99.5%
associate-*l*99.5%
Applied egg-rr99.5%
sub-neg99.5%
log1p-undefine99.5%
rem-exp-log99.5%
associate-*r*99.5%
metadata-eval99.5%
Simplified99.5%
Final simplification99.5%
(FPCore (x)
:precision binary32
(*
0.5
(*
x
(+
2.0
(*
x
(+
-1.0
(+
1.0
(*
x
(+
0.6666666666666666
(* x (* x (+ 0.4 (* x (* x 0.2857142857142857))))))))))))))
float code(float x) {
return 0.5f * (x * (2.0f + (x * (-1.0f + (1.0f + (x * (0.6666666666666666f + (x * (x * (0.4f + (x * (x * 0.2857142857142857f))))))))))));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * (x * (2.0e0 + (x * ((-1.0e0) + (1.0e0 + (x * (0.6666666666666666e0 + (x * (x * (0.4e0 + (x * (x * 0.2857142857142857e0))))))))))))
end function
function code(x) return Float32(Float32(0.5) * Float32(x * Float32(Float32(2.0) + Float32(x * Float32(Float32(-1.0) + Float32(Float32(1.0) + Float32(x * Float32(Float32(0.6666666666666666) + Float32(x * Float32(x * Float32(Float32(0.4) + Float32(x * Float32(x * Float32(0.2857142857142857)))))))))))))) end
function tmp = code(x) tmp = single(0.5) * (x * (single(2.0) + (x * (single(-1.0) + (single(1.0) + (x * (single(0.6666666666666666) + (x * (x * (single(0.4) + (x * (x * single(0.2857142857142857))))))))))))); end
\begin{array}{l}
\\
0.5 \cdot \left(x \cdot \left(2 + x \cdot \left(-1 + \left(1 + x \cdot \left(0.6666666666666666 + x \cdot \left(x \cdot \left(0.4 + x \cdot \left(x \cdot 0.2857142857142857\right)\right)\right)\right)\right)\right)\right)\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 99.5%
unpow299.5%
associate-*l*99.5%
unpow299.5%
*-commutative99.5%
unpow299.5%
Simplified99.5%
expm1-log1p-u99.5%
expm1-undefine99.5%
associate-*l*99.5%
Applied egg-rr99.5%
sub-neg99.5%
log1p-undefine99.5%
rem-exp-log99.5%
associate-*r*99.5%
metadata-eval99.5%
Simplified99.5%
Final simplification99.5%
(FPCore (x)
:precision binary32
(*
0.5
(*
x
(+
2.0
(*
x
(*
x
(+
0.6666666666666666
(* (* x x) (+ 0.4 (* 0.2857142857142857 (* x x)))))))))))
float code(float x) {
return 0.5f * (x * (2.0f + (x * (x * (0.6666666666666666f + ((x * x) * (0.4f + (0.2857142857142857f * (x * x)))))))));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * (x * (2.0e0 + (x * (x * (0.6666666666666666e0 + ((x * x) * (0.4e0 + (0.2857142857142857e0 * (x * x)))))))))
end function
function code(x) return Float32(Float32(0.5) * Float32(x * Float32(Float32(2.0) + Float32(x * Float32(x * Float32(Float32(0.6666666666666666) + Float32(Float32(x * x) * Float32(Float32(0.4) + Float32(Float32(0.2857142857142857) * Float32(x * x)))))))))) end
function tmp = code(x) tmp = single(0.5) * (x * (single(2.0) + (x * (x * (single(0.6666666666666666) + ((x * x) * (single(0.4) + (single(0.2857142857142857) * (x * x))))))))); end
\begin{array}{l}
\\
0.5 \cdot \left(x \cdot \left(2 + x \cdot \left(x \cdot \left(0.6666666666666666 + \left(x \cdot x\right) \cdot \left(0.4 + 0.2857142857142857 \cdot \left(x \cdot x\right)\right)\right)\right)\right)\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 99.5%
unpow299.5%
associate-*l*99.5%
unpow299.5%
*-commutative99.5%
unpow299.5%
Simplified99.5%
Final simplification99.5%
(FPCore (x) :precision binary32 (* 0.5 (+ (* x (* (* x x) (+ 0.6666666666666666 (* x (* x 0.4))))) (* 2.0 x))))
float code(float x) {
return 0.5f * ((x * ((x * x) * (0.6666666666666666f + (x * (x * 0.4f))))) + (2.0f * x));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * ((x * ((x * x) * (0.6666666666666666e0 + (x * (x * 0.4e0))))) + (2.0e0 * x))
end function
function code(x) return Float32(Float32(0.5) * Float32(Float32(x * Float32(Float32(x * x) * Float32(Float32(0.6666666666666666) + Float32(x * Float32(x * Float32(0.4)))))) + Float32(Float32(2.0) * x))) end
function tmp = code(x) tmp = single(0.5) * ((x * ((x * x) * (single(0.6666666666666666) + (x * (x * single(0.4)))))) + (single(2.0) * x)); end
\begin{array}{l}
\\
0.5 \cdot \left(x \cdot \left(\left(x \cdot x\right) \cdot \left(0.6666666666666666 + x \cdot \left(x \cdot 0.4\right)\right)\right) + 2 \cdot x\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 99.1%
unpow299.1%
*-commutative99.1%
unpow299.1%
Simplified99.1%
+-commutative99.1%
distribute-rgt-in99.2%
associate-*l*99.2%
*-commutative99.2%
Applied egg-rr99.2%
Final simplification99.2%
(FPCore (x) :precision binary32 (* 0.5 (* x (+ 2.0 (* (* x x) (+ 0.6666666666666666 (* 0.4 (* x x))))))))
float code(float x) {
return 0.5f * (x * (2.0f + ((x * x) * (0.6666666666666666f + (0.4f * (x * x))))));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * (x * (2.0e0 + ((x * x) * (0.6666666666666666e0 + (0.4e0 * (x * x))))))
end function
function code(x) return Float32(Float32(0.5) * Float32(x * Float32(Float32(2.0) + Float32(Float32(x * x) * Float32(Float32(0.6666666666666666) + Float32(Float32(0.4) * Float32(x * x))))))) end
function tmp = code(x) tmp = single(0.5) * (x * (single(2.0) + ((x * x) * (single(0.6666666666666666) + (single(0.4) * (x * x)))))); end
\begin{array}{l}
\\
0.5 \cdot \left(x \cdot \left(2 + \left(x \cdot x\right) \cdot \left(0.6666666666666666 + 0.4 \cdot \left(x \cdot x\right)\right)\right)\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 99.1%
unpow299.1%
*-commutative99.1%
unpow299.1%
Simplified99.1%
Final simplification99.1%
(FPCore (x) :precision binary32 (* 0.5 (+ (* 2.0 x) (* x (* 0.6666666666666666 (* x x))))))
float code(float x) {
return 0.5f * ((2.0f * x) + (x * (0.6666666666666666f * (x * x))));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * ((2.0e0 * x) + (x * (0.6666666666666666e0 * (x * x))))
end function
function code(x) return Float32(Float32(0.5) * Float32(Float32(Float32(2.0) * x) + Float32(x * Float32(Float32(0.6666666666666666) * Float32(x * x))))) end
function tmp = code(x) tmp = single(0.5) * ((single(2.0) * x) + (x * (single(0.6666666666666666) * (x * x)))); end
\begin{array}{l}
\\
0.5 \cdot \left(2 \cdot x + x \cdot \left(0.6666666666666666 \cdot \left(x \cdot x\right)\right)\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 98.6%
*-commutative98.6%
unpow298.6%
Simplified98.6%
+-commutative98.6%
distribute-rgt-in98.6%
*-commutative98.6%
Applied egg-rr98.6%
Final simplification98.6%
(FPCore (x) :precision binary32 (* 0.5 (* x (+ 2.0 (* 0.6666666666666666 (* x x))))))
float code(float x) {
return 0.5f * (x * (2.0f + (0.6666666666666666f * (x * x))));
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * (x * (2.0e0 + (0.6666666666666666e0 * (x * x))))
end function
function code(x) return Float32(Float32(0.5) * Float32(x * Float32(Float32(2.0) + Float32(Float32(0.6666666666666666) * Float32(x * x))))) end
function tmp = code(x) tmp = single(0.5) * (x * (single(2.0) + (single(0.6666666666666666) * (x * x)))); end
\begin{array}{l}
\\
0.5 \cdot \left(x \cdot \left(2 + 0.6666666666666666 \cdot \left(x \cdot x\right)\right)\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 98.6%
*-commutative98.6%
unpow298.6%
Simplified98.6%
Final simplification98.6%
(FPCore (x) :precision binary32 (* 0.5 (* 2.0 x)))
float code(float x) {
return 0.5f * (2.0f * x);
}
real(4) function code(x)
real(4), intent (in) :: x
code = 0.5e0 * (2.0e0 * x)
end function
function code(x) return Float32(Float32(0.5) * Float32(Float32(2.0) * x)) end
function tmp = code(x) tmp = single(0.5) * (single(2.0) * x); end
\begin{array}{l}
\\
0.5 \cdot \left(2 \cdot x\right)
\end{array}
Initial program 99.8%
associate-*l/99.7%
*-commutative99.7%
sub-neg99.7%
+-commutative99.7%
neg-sub099.7%
associate-+l-99.7%
sub0-neg99.7%
distribute-frac-neg299.7%
distribute-neg-frac99.7%
metadata-eval99.7%
sub-neg99.7%
metadata-eval99.7%
Simplified99.7%
Taylor expanded in x around 0 97.4%
herbie shell --seed 2024107
(FPCore (x)
:name "Rust f32::atanh"
:precision binary32
(* 0.5 (log1p (/ (* 2.0 x) (- 1.0 x)))))