
(FPCore (v) :precision binary64 (acos (/ (- 1.0 (* 5.0 (* v v))) (- (* v v) 1.0))))
double code(double v) {
return acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0)));
}
real(8) function code(v)
real(8), intent (in) :: v
code = acos(((1.0d0 - (5.0d0 * (v * v))) / ((v * v) - 1.0d0)))
end function
public static double code(double v) {
return Math.acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0)));
}
def code(v): return math.acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0)))
function code(v) return acos(Float64(Float64(1.0 - Float64(5.0 * Float64(v * v))) / Float64(Float64(v * v) - 1.0))) end
function tmp = code(v) tmp = acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0))); end
code[v_] := N[ArcCos[N[(N[(1.0 - N[(5.0 * N[(v * v), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] / N[(N[(v * v), $MachinePrecision] - 1.0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\cos^{-1} \left(\frac{1 - 5 \cdot \left(v \cdot v\right)}{v \cdot v - 1}\right)
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 7 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (v) :precision binary64 (acos (/ (- 1.0 (* 5.0 (* v v))) (- (* v v) 1.0))))
double code(double v) {
return acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0)));
}
real(8) function code(v)
real(8), intent (in) :: v
code = acos(((1.0d0 - (5.0d0 * (v * v))) / ((v * v) - 1.0d0)))
end function
public static double code(double v) {
return Math.acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0)));
}
def code(v): return math.acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0)))
function code(v) return acos(Float64(Float64(1.0 - Float64(5.0 * Float64(v * v))) / Float64(Float64(v * v) - 1.0))) end
function tmp = code(v) tmp = acos(((1.0 - (5.0 * (v * v))) / ((v * v) - 1.0))); end
code[v_] := N[ArcCos[N[(N[(1.0 - N[(5.0 * N[(v * v), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] / N[(N[(v * v), $MachinePrecision] - 1.0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\cos^{-1} \left(\frac{1 - 5 \cdot \left(v \cdot v\right)}{v \cdot v - 1}\right)
\end{array}
(FPCore (v)
:precision binary64
(let* ((t_0 (/ (fma -5.0 (* v v) 1.0) (fma v v -1.0)))
(t_1 (asin t_0))
(t_2 (acos t_0))
(t_3 (/ 2.0 t_2))
(t_4 (* (* PI (* PI PI)) 0.125))
(t_5 (/ 1.0 t_2)))
(*
(-
t_4
(pow
(/
(+
(*
(/ PI t_2)
(fma PI (* PI 0.25) (+ (pow t_1 2.0) (* t_1 (* PI 0.5)))))
(* t_3 (- (pow t_1 3.0) t_4)))
(* t_3 (fma PI (* PI 0.25) (* t_1 (fma PI 0.5 t_1)))))
3.0))
(/
1.0
(fma
(asin (/ (fma v (* -5.0 v) 1.0) (fma v v -1.0)))
(fma PI 0.5 (/ (- (* PI t_5) 2.0) (* 2.0 t_5)))
(* (* PI PI) 0.25))))))
double code(double v) {
double t_0 = fma(-5.0, (v * v), 1.0) / fma(v, v, -1.0);
double t_1 = asin(t_0);
double t_2 = acos(t_0);
double t_3 = 2.0 / t_2;
double t_4 = (((double) M_PI) * (((double) M_PI) * ((double) M_PI))) * 0.125;
double t_5 = 1.0 / t_2;
return (t_4 - pow(((((((double) M_PI) / t_2) * fma(((double) M_PI), (((double) M_PI) * 0.25), (pow(t_1, 2.0) + (t_1 * (((double) M_PI) * 0.5))))) + (t_3 * (pow(t_1, 3.0) - t_4))) / (t_3 * fma(((double) M_PI), (((double) M_PI) * 0.25), (t_1 * fma(((double) M_PI), 0.5, t_1))))), 3.0)) * (1.0 / fma(asin((fma(v, (-5.0 * v), 1.0) / fma(v, v, -1.0))), fma(((double) M_PI), 0.5, (((((double) M_PI) * t_5) - 2.0) / (2.0 * t_5))), ((((double) M_PI) * ((double) M_PI)) * 0.25)));
}
function code(v) t_0 = Float64(fma(-5.0, Float64(v * v), 1.0) / fma(v, v, -1.0)) t_1 = asin(t_0) t_2 = acos(t_0) t_3 = Float64(2.0 / t_2) t_4 = Float64(Float64(pi * Float64(pi * pi)) * 0.125) t_5 = Float64(1.0 / t_2) return Float64(Float64(t_4 - (Float64(Float64(Float64(Float64(pi / t_2) * fma(pi, Float64(pi * 0.25), Float64((t_1 ^ 2.0) + Float64(t_1 * Float64(pi * 0.5))))) + Float64(t_3 * Float64((t_1 ^ 3.0) - t_4))) / Float64(t_3 * fma(pi, Float64(pi * 0.25), Float64(t_1 * fma(pi, 0.5, t_1))))) ^ 3.0)) * Float64(1.0 / fma(asin(Float64(fma(v, Float64(-5.0 * v), 1.0) / fma(v, v, -1.0))), fma(pi, 0.5, Float64(Float64(Float64(pi * t_5) - 2.0) / Float64(2.0 * t_5))), Float64(Float64(pi * pi) * 0.25)))) end
code[v_] := Block[{t$95$0 = N[(N[(-5.0 * N[(v * v), $MachinePrecision] + 1.0), $MachinePrecision] / N[(v * v + -1.0), $MachinePrecision]), $MachinePrecision]}, Block[{t$95$1 = N[ArcSin[t$95$0], $MachinePrecision]}, Block[{t$95$2 = N[ArcCos[t$95$0], $MachinePrecision]}, Block[{t$95$3 = N[(2.0 / t$95$2), $MachinePrecision]}, Block[{t$95$4 = N[(N[(Pi * N[(Pi * Pi), $MachinePrecision]), $MachinePrecision] * 0.125), $MachinePrecision]}, Block[{t$95$5 = N[(1.0 / t$95$2), $MachinePrecision]}, N[(N[(t$95$4 - N[Power[N[(N[(N[(N[(Pi / t$95$2), $MachinePrecision] * N[(Pi * N[(Pi * 0.25), $MachinePrecision] + N[(N[Power[t$95$1, 2.0], $MachinePrecision] + N[(t$95$1 * N[(Pi * 0.5), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(t$95$3 * N[(N[Power[t$95$1, 3.0], $MachinePrecision] - t$95$4), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] / N[(t$95$3 * N[(Pi * N[(Pi * 0.25), $MachinePrecision] + N[(t$95$1 * N[(Pi * 0.5 + t$95$1), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision], 3.0], $MachinePrecision]), $MachinePrecision] * N[(1.0 / N[(N[ArcSin[N[(N[(v * N[(-5.0 * v), $MachinePrecision] + 1.0), $MachinePrecision] / N[(v * v + -1.0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision] * N[(Pi * 0.5 + N[(N[(N[(Pi * t$95$5), $MachinePrecision] - 2.0), $MachinePrecision] / N[(2.0 * t$95$5), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(N[(Pi * Pi), $MachinePrecision] * 0.25), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]]]]]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := \frac{\mathsf{fma}\left(-5, v \cdot v, 1\right)}{\mathsf{fma}\left(v, v, -1\right)}\\
t_1 := \sin^{-1} t\_0\\
t_2 := \cos^{-1} t\_0\\
t_3 := \frac{2}{t\_2}\\
t_4 := \left(\pi \cdot \left(\pi \cdot \pi\right)\right) \cdot 0.125\\
t_5 := \frac{1}{t\_2}\\
\left(t\_4 - {\left(\frac{\frac{\pi}{t\_2} \cdot \mathsf{fma}\left(\pi, \pi \cdot 0.25, {t\_1}^{2} + t\_1 \cdot \left(\pi \cdot 0.5\right)\right) + t\_3 \cdot \left({t\_1}^{3} - t\_4\right)}{t\_3 \cdot \mathsf{fma}\left(\pi, \pi \cdot 0.25, t\_1 \cdot \mathsf{fma}\left(\pi, 0.5, t\_1\right)\right)}\right)}^{3}\right) \cdot \frac{1}{\mathsf{fma}\left(\sin^{-1} \left(\frac{\mathsf{fma}\left(v, -5 \cdot v, 1\right)}{\mathsf{fma}\left(v, v, -1\right)}\right), \mathsf{fma}\left(\pi, 0.5, \frac{\pi \cdot t\_5 - 2}{2 \cdot t\_5}\right), \left(\pi \cdot \pi\right) \cdot 0.25\right)}
\end{array}
\end{array}
Initial program 99.5%
Applied egg-rr99.5%
Applied egg-rr99.5%
Applied egg-rr99.5%
Applied egg-rr99.5%
Final simplification99.5%
(FPCore (v) :precision binary64 (exp (- (log (/ 1.0 (acos (/ (fma -5.0 (* v v) 1.0) (fma v v -1.0))))))))
double code(double v) {
return exp(-log((1.0 / acos((fma(-5.0, (v * v), 1.0) / fma(v, v, -1.0))))));
}
function code(v) return exp(Float64(-log(Float64(1.0 / acos(Float64(fma(-5.0, Float64(v * v), 1.0) / fma(v, v, -1.0))))))) end
code[v_] := N[Exp[(-N[Log[N[(1.0 / N[ArcCos[N[(N[(-5.0 * N[(v * v), $MachinePrecision] + 1.0), $MachinePrecision] / N[(v * v + -1.0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]], $MachinePrecision])], $MachinePrecision]
\begin{array}{l}
\\
e^{-\log \left(\frac{1}{\cos^{-1} \left(\frac{\mathsf{fma}\left(-5, v \cdot v, 1\right)}{\mathsf{fma}\left(v, v, -1\right)}\right)}\right)}
\end{array}
Initial program 99.5%
lift-*.f64N/A
lift-*.f64N/A
lift-*.f64N/A
lift--.f64N/A
lift--.f64N/A
lift-/.f64N/A
lift-acos.f6499.5
Applied egg-rr99.5%
Applied egg-rr99.5%
Final simplification99.5%
(FPCore (v) :precision binary64 (acos (/ (fma v (* -5.0 v) 1.0) (fma v v -1.0))))
double code(double v) {
return acos((fma(v, (-5.0 * v), 1.0) / fma(v, v, -1.0)));
}
function code(v) return acos(Float64(fma(v, Float64(-5.0 * v), 1.0) / fma(v, v, -1.0))) end
code[v_] := N[ArcCos[N[(N[(v * N[(-5.0 * v), $MachinePrecision] + 1.0), $MachinePrecision] / N[(v * v + -1.0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\cos^{-1} \left(\frac{\mathsf{fma}\left(v, -5 \cdot v, 1\right)}{\mathsf{fma}\left(v, v, -1\right)}\right)
\end{array}
Initial program 99.5%
lift-*.f64N/A
lift-*.f64N/A
lift-*.f64N/A
lift--.f64N/A
lift--.f64N/A
lift-/.f64N/A
lift-acos.f6499.5
Applied egg-rr99.5%
Final simplification99.5%
(FPCore (v) :precision binary64 (acos (fma v (* v (fma (* v v) 4.0 4.0)) -1.0)))
double code(double v) {
return acos(fma(v, (v * fma((v * v), 4.0, 4.0)), -1.0));
}
function code(v) return acos(fma(v, Float64(v * fma(Float64(v * v), 4.0, 4.0)), -1.0)) end
code[v_] := N[ArcCos[N[(v * N[(v * N[(N[(v * v), $MachinePrecision] * 4.0 + 4.0), $MachinePrecision]), $MachinePrecision] + -1.0), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\cos^{-1} \left(\mathsf{fma}\left(v, v \cdot \mathsf{fma}\left(v \cdot v, 4, 4\right), -1\right)\right)
\end{array}
Initial program 99.5%
Taylor expanded in v around 0
sub-negN/A
unpow2N/A
associate-*l*N/A
*-commutativeN/A
metadata-evalN/A
lower-fma.f64N/A
*-commutativeN/A
lower-*.f64N/A
+-commutativeN/A
*-commutativeN/A
lower-fma.f64N/A
unpow2N/A
lower-*.f6499.3
Simplified99.3%
(FPCore (v) :precision binary64 (fma PI 0.5 (- (asin (fma v (* v 4.0) -1.0)))))
double code(double v) {
return fma(((double) M_PI), 0.5, -asin(fma(v, (v * 4.0), -1.0)));
}
function code(v) return fma(pi, 0.5, Float64(-asin(fma(v, Float64(v * 4.0), -1.0)))) end
code[v_] := N[(Pi * 0.5 + (-N[ArcSin[N[(v * N[(v * 4.0), $MachinePrecision] + -1.0), $MachinePrecision]], $MachinePrecision])), $MachinePrecision]
\begin{array}{l}
\\
\mathsf{fma}\left(\pi, 0.5, -\sin^{-1} \left(\mathsf{fma}\left(v, v \cdot 4, -1\right)\right)\right)
\end{array}
Initial program 99.5%
Taylor expanded in v around 0
sub-negN/A
unpow2N/A
associate-*r*N/A
*-commutativeN/A
metadata-evalN/A
lower-fma.f64N/A
*-commutativeN/A
lower-*.f6498.8
Simplified98.8%
lift-*.f64N/A
lift-fma.f64N/A
acos-asinN/A
lift-PI.f64N/A
div-invN/A
metadata-evalN/A
sub-negN/A
lower-fma.f64N/A
lower-neg.f64N/A
lower-asin.f6498.8
Applied egg-rr98.8%
(FPCore (v) :precision binary64 (acos (fma v (* v 4.0) -1.0)))
double code(double v) {
return acos(fma(v, (v * 4.0), -1.0));
}
function code(v) return acos(fma(v, Float64(v * 4.0), -1.0)) end
code[v_] := N[ArcCos[N[(v * N[(v * 4.0), $MachinePrecision] + -1.0), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\cos^{-1} \left(\mathsf{fma}\left(v, v \cdot 4, -1\right)\right)
\end{array}
Initial program 99.5%
Taylor expanded in v around 0
sub-negN/A
unpow2N/A
associate-*r*N/A
*-commutativeN/A
metadata-evalN/A
lower-fma.f64N/A
*-commutativeN/A
lower-*.f6498.8
Simplified98.8%
(FPCore (v) :precision binary64 (acos -1.0))
double code(double v) {
return acos(-1.0);
}
real(8) function code(v)
real(8), intent (in) :: v
code = acos((-1.0d0))
end function
public static double code(double v) {
return Math.acos(-1.0);
}
def code(v): return math.acos(-1.0)
function code(v) return acos(-1.0) end
function tmp = code(v) tmp = acos(-1.0); end
code[v_] := N[ArcCos[-1.0], $MachinePrecision]
\begin{array}{l}
\\
\cos^{-1} -1
\end{array}
Initial program 99.5%
Taylor expanded in v around 0
Simplified97.9%
herbie shell --seed 2024219
(FPCore (v)
:name "Falkner and Boettcher, Appendix B, 1"
:precision binary64
(acos (/ (- 1.0 (* 5.0 (* v v))) (- (* v v) 1.0))))