
(FPCore (f) :precision binary64 (let* ((t_0 (* (/ PI 4.0) f)) (t_1 (exp t_0)) (t_2 (exp (- t_0)))) (- (* (/ 1.0 (/ PI 4.0)) (log (/ (+ t_1 t_2) (- t_1 t_2)))))))
double code(double f) {
double t_0 = (((double) M_PI) / 4.0) * f;
double t_1 = exp(t_0);
double t_2 = exp(-t_0);
return -((1.0 / (((double) M_PI) / 4.0)) * log(((t_1 + t_2) / (t_1 - t_2))));
}
public static double code(double f) {
double t_0 = (Math.PI / 4.0) * f;
double t_1 = Math.exp(t_0);
double t_2 = Math.exp(-t_0);
return -((1.0 / (Math.PI / 4.0)) * Math.log(((t_1 + t_2) / (t_1 - t_2))));
}
def code(f): t_0 = (math.pi / 4.0) * f t_1 = math.exp(t_0) t_2 = math.exp(-t_0) return -((1.0 / (math.pi / 4.0)) * math.log(((t_1 + t_2) / (t_1 - t_2))))
function code(f) t_0 = Float64(Float64(pi / 4.0) * f) t_1 = exp(t_0) t_2 = exp(Float64(-t_0)) return Float64(-Float64(Float64(1.0 / Float64(pi / 4.0)) * log(Float64(Float64(t_1 + t_2) / Float64(t_1 - t_2))))) end
function tmp = code(f) t_0 = (pi / 4.0) * f; t_1 = exp(t_0); t_2 = exp(-t_0); tmp = -((1.0 / (pi / 4.0)) * log(((t_1 + t_2) / (t_1 - t_2)))); end
code[f_] := Block[{t$95$0 = N[(N[(Pi / 4.0), $MachinePrecision] * f), $MachinePrecision]}, Block[{t$95$1 = N[Exp[t$95$0], $MachinePrecision]}, Block[{t$95$2 = N[Exp[(-t$95$0)], $MachinePrecision]}, (-N[(N[(1.0 / N[(Pi / 4.0), $MachinePrecision]), $MachinePrecision] * N[Log[N[(N[(t$95$1 + t$95$2), $MachinePrecision] / N[(t$95$1 - t$95$2), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision])]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := \frac{\pi}{4} \cdot f\\
t_1 := e^{t_0}\\
t_2 := e^{-t_0}\\
-\frac{1}{\frac{\pi}{4}} \cdot \log \left(\frac{t_1 + t_2}{t_1 - t_2}\right)
\end{array}
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 6 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (f) :precision binary64 (let* ((t_0 (* (/ PI 4.0) f)) (t_1 (exp t_0)) (t_2 (exp (- t_0)))) (- (* (/ 1.0 (/ PI 4.0)) (log (/ (+ t_1 t_2) (- t_1 t_2)))))))
double code(double f) {
double t_0 = (((double) M_PI) / 4.0) * f;
double t_1 = exp(t_0);
double t_2 = exp(-t_0);
return -((1.0 / (((double) M_PI) / 4.0)) * log(((t_1 + t_2) / (t_1 - t_2))));
}
public static double code(double f) {
double t_0 = (Math.PI / 4.0) * f;
double t_1 = Math.exp(t_0);
double t_2 = Math.exp(-t_0);
return -((1.0 / (Math.PI / 4.0)) * Math.log(((t_1 + t_2) / (t_1 - t_2))));
}
def code(f): t_0 = (math.pi / 4.0) * f t_1 = math.exp(t_0) t_2 = math.exp(-t_0) return -((1.0 / (math.pi / 4.0)) * math.log(((t_1 + t_2) / (t_1 - t_2))))
function code(f) t_0 = Float64(Float64(pi / 4.0) * f) t_1 = exp(t_0) t_2 = exp(Float64(-t_0)) return Float64(-Float64(Float64(1.0 / Float64(pi / 4.0)) * log(Float64(Float64(t_1 + t_2) / Float64(t_1 - t_2))))) end
function tmp = code(f) t_0 = (pi / 4.0) * f; t_1 = exp(t_0); t_2 = exp(-t_0); tmp = -((1.0 / (pi / 4.0)) * log(((t_1 + t_2) / (t_1 - t_2)))); end
code[f_] := Block[{t$95$0 = N[(N[(Pi / 4.0), $MachinePrecision] * f), $MachinePrecision]}, Block[{t$95$1 = N[Exp[t$95$0], $MachinePrecision]}, Block[{t$95$2 = N[Exp[(-t$95$0)], $MachinePrecision]}, (-N[(N[(1.0 / N[(Pi / 4.0), $MachinePrecision]), $MachinePrecision] * N[Log[N[(N[(t$95$1 + t$95$2), $MachinePrecision] / N[(t$95$1 - t$95$2), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision])]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := \frac{\pi}{4} \cdot f\\
t_1 := e^{t_0}\\
t_2 := e^{-t_0}\\
-\frac{1}{\frac{\pi}{4}} \cdot \log \left(\frac{t_1 + t_2}{t_1 - t_2}\right)
\end{array}
\end{array}
(FPCore (f) :precision binary64 (let* ((t_0 (* (/ PI 4.0) f)) (t_1 (exp t_0)) (t_2 (exp (- t_0)))) (- (* (/ 1.0 (/ PI 4.0)) (log (/ (+ t_1 t_2) (- t_1 t_2)))))))
double code(double f) {
double t_0 = (((double) M_PI) / 4.0) * f;
double t_1 = exp(t_0);
double t_2 = exp(-t_0);
return -((1.0 / (((double) M_PI) / 4.0)) * log(((t_1 + t_2) / (t_1 - t_2))));
}
public static double code(double f) {
double t_0 = (Math.PI / 4.0) * f;
double t_1 = Math.exp(t_0);
double t_2 = Math.exp(-t_0);
return -((1.0 / (Math.PI / 4.0)) * Math.log(((t_1 + t_2) / (t_1 - t_2))));
}
def code(f): t_0 = (math.pi / 4.0) * f t_1 = math.exp(t_0) t_2 = math.exp(-t_0) return -((1.0 / (math.pi / 4.0)) * math.log(((t_1 + t_2) / (t_1 - t_2))))
function code(f) t_0 = Float64(Float64(pi / 4.0) * f) t_1 = exp(t_0) t_2 = exp(Float64(-t_0)) return Float64(-Float64(Float64(1.0 / Float64(pi / 4.0)) * log(Float64(Float64(t_1 + t_2) / Float64(t_1 - t_2))))) end
function tmp = code(f) t_0 = (pi / 4.0) * f; t_1 = exp(t_0); t_2 = exp(-t_0); tmp = -((1.0 / (pi / 4.0)) * log(((t_1 + t_2) / (t_1 - t_2)))); end
code[f_] := Block[{t$95$0 = N[(N[(Pi / 4.0), $MachinePrecision] * f), $MachinePrecision]}, Block[{t$95$1 = N[Exp[t$95$0], $MachinePrecision]}, Block[{t$95$2 = N[Exp[(-t$95$0)], $MachinePrecision]}, (-N[(N[(1.0 / N[(Pi / 4.0), $MachinePrecision]), $MachinePrecision] * N[Log[N[(N[(t$95$1 + t$95$2), $MachinePrecision] / N[(t$95$1 - t$95$2), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision])]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := \frac{\pi}{4} \cdot f\\
t_1 := e^{t_0}\\
t_2 := e^{-t_0}\\
-\frac{1}{\frac{\pi}{4}} \cdot \log \left(\frac{t_1 + t_2}{t_1 - t_2}\right)
\end{array}
\end{array}
Initial program 5.4%
(FPCore (f) :precision binary64 (let* ((t_0 (exp (/ (* PI f) 4.0))) (t_1 (pow (exp (/ PI 4.0)) (- f)))) (* (/ 1.0 (/ PI 4.0)) (- (log (/ (+ t_0 t_1) (- t_0 t_1)))))))
double code(double f) {
double t_0 = exp(((((double) M_PI) * f) / 4.0));
double t_1 = pow(exp((((double) M_PI) / 4.0)), -f);
return (1.0 / (((double) M_PI) / 4.0)) * -log(((t_0 + t_1) / (t_0 - t_1)));
}
public static double code(double f) {
double t_0 = Math.exp(((Math.PI * f) / 4.0));
double t_1 = Math.pow(Math.exp((Math.PI / 4.0)), -f);
return (1.0 / (Math.PI / 4.0)) * -Math.log(((t_0 + t_1) / (t_0 - t_1)));
}
def code(f): t_0 = math.exp(((math.pi * f) / 4.0)) t_1 = math.pow(math.exp((math.pi / 4.0)), -f) return (1.0 / (math.pi / 4.0)) * -math.log(((t_0 + t_1) / (t_0 - t_1)))
function code(f) t_0 = exp(Float64(Float64(pi * f) / 4.0)) t_1 = exp(Float64(pi / 4.0)) ^ Float64(-f) return Float64(Float64(1.0 / Float64(pi / 4.0)) * Float64(-log(Float64(Float64(t_0 + t_1) / Float64(t_0 - t_1))))) end
function tmp = code(f) t_0 = exp(((pi * f) / 4.0)); t_1 = exp((pi / 4.0)) ^ -f; tmp = (1.0 / (pi / 4.0)) * -log(((t_0 + t_1) / (t_0 - t_1))); end
code[f_] := Block[{t$95$0 = N[Exp[N[(N[(Pi * f), $MachinePrecision] / 4.0), $MachinePrecision]], $MachinePrecision]}, Block[{t$95$1 = N[Power[N[Exp[N[(Pi / 4.0), $MachinePrecision]], $MachinePrecision], (-f)], $MachinePrecision]}, N[(N[(1.0 / N[(Pi / 4.0), $MachinePrecision]), $MachinePrecision] * (-N[Log[N[(N[(t$95$0 + t$95$1), $MachinePrecision] / N[(t$95$0 - t$95$1), $MachinePrecision]), $MachinePrecision]], $MachinePrecision])), $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := e^{\frac{\pi \cdot f}{4}}\\
t_1 := {\left(e^{\frac{\pi}{4}}\right)}^{\left(-f\right)}\\
\frac{1}{\frac{\pi}{4}} \cdot \left(-\log \left(\frac{t_0 + t_1}{t_0 - t_1}\right)\right)
\end{array}
\end{array}
Initial program 5.4%
(FPCore (f) :precision binary64 (let* ((t_0 (exp (* (/ PI 4.0) (- f)))) (t_1 (pow (exp f) (/ PI 4.0)))) (* (log (/ (+ t_0 t_1) (- t_1 t_0))) (- (/ 4.0 PI)))))
double code(double f) {
double t_0 = exp(((((double) M_PI) / 4.0) * -f));
double t_1 = pow(exp(f), (((double) M_PI) / 4.0));
return log(((t_0 + t_1) / (t_1 - t_0))) * -(4.0 / ((double) M_PI));
}
public static double code(double f) {
double t_0 = Math.exp(((Math.PI / 4.0) * -f));
double t_1 = Math.pow(Math.exp(f), (Math.PI / 4.0));
return Math.log(((t_0 + t_1) / (t_1 - t_0))) * -(4.0 / Math.PI);
}
def code(f): t_0 = math.exp(((math.pi / 4.0) * -f)) t_1 = math.pow(math.exp(f), (math.pi / 4.0)) return math.log(((t_0 + t_1) / (t_1 - t_0))) * -(4.0 / math.pi)
function code(f) t_0 = exp(Float64(Float64(pi / 4.0) * Float64(-f))) t_1 = exp(f) ^ Float64(pi / 4.0) return Float64(log(Float64(Float64(t_0 + t_1) / Float64(t_1 - t_0))) * Float64(-Float64(4.0 / pi))) end
function tmp = code(f) t_0 = exp(((pi / 4.0) * -f)); t_1 = exp(f) ^ (pi / 4.0); tmp = log(((t_0 + t_1) / (t_1 - t_0))) * -(4.0 / pi); end
code[f_] := Block[{t$95$0 = N[Exp[N[(N[(Pi / 4.0), $MachinePrecision] * (-f)), $MachinePrecision]], $MachinePrecision]}, Block[{t$95$1 = N[Power[N[Exp[f], $MachinePrecision], N[(Pi / 4.0), $MachinePrecision]], $MachinePrecision]}, N[(N[Log[N[(N[(t$95$0 + t$95$1), $MachinePrecision] / N[(t$95$1 - t$95$0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision] * (-N[(4.0 / Pi), $MachinePrecision])), $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := e^{\frac{\pi}{4} \cdot \left(-f\right)}\\
t_1 := {\left(e^{f}\right)}^{\left(\frac{\pi}{4}\right)}\\
\log \left(\frac{t_0 + t_1}{t_1 - t_0}\right) \cdot \left(-\frac{4}{\pi}\right)
\end{array}
\end{array}
Initial program 5.4%
(FPCore (f) :precision binary64 (let* ((t_0 (exp (/ PI (/ -4.0 f)))) (t_1 (pow (exp (/ PI 4.0)) f))) (* (log (/ (+ t_0 t_1) (- t_1 t_0))) (/ -4.0 PI))))
double code(double f) {
double t_0 = exp((((double) M_PI) / (-4.0 / f)));
double t_1 = pow(exp((((double) M_PI) / 4.0)), f);
return log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / ((double) M_PI));
}
public static double code(double f) {
double t_0 = Math.exp((Math.PI / (-4.0 / f)));
double t_1 = Math.pow(Math.exp((Math.PI / 4.0)), f);
return Math.log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / Math.PI);
}
def code(f): t_0 = math.exp((math.pi / (-4.0 / f))) t_1 = math.pow(math.exp((math.pi / 4.0)), f) return math.log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / math.pi)
function code(f) t_0 = exp(Float64(pi / Float64(-4.0 / f))) t_1 = exp(Float64(pi / 4.0)) ^ f return Float64(log(Float64(Float64(t_0 + t_1) / Float64(t_1 - t_0))) * Float64(-4.0 / pi)) end
function tmp = code(f) t_0 = exp((pi / (-4.0 / f))); t_1 = exp((pi / 4.0)) ^ f; tmp = log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / pi); end
code[f_] := Block[{t$95$0 = N[Exp[N[(Pi / N[(-4.0 / f), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]}, Block[{t$95$1 = N[Power[N[Exp[N[(Pi / 4.0), $MachinePrecision]], $MachinePrecision], f], $MachinePrecision]}, N[(N[Log[N[(N[(t$95$0 + t$95$1), $MachinePrecision] / N[(t$95$1 - t$95$0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision] * N[(-4.0 / Pi), $MachinePrecision]), $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := e^{\frac{\pi}{\frac{-4}{f}}}\\
t_1 := {\left(e^{\frac{\pi}{4}}\right)}^{f}\\
\log \left(\frac{t_0 + t_1}{t_1 - t_0}\right) \cdot \frac{-4}{\pi}
\end{array}
\end{array}
Initial program 5.4%
(FPCore (f) :precision binary64 (let* ((t_0 (pow (exp f) (/ PI -4.0))) (t_1 (pow (exp (/ PI 4.0)) f))) (* (log (/ (+ t_0 t_1) (- t_1 t_0))) (/ -4.0 PI))))
double code(double f) {
double t_0 = pow(exp(f), (((double) M_PI) / -4.0));
double t_1 = pow(exp((((double) M_PI) / 4.0)), f);
return log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / ((double) M_PI));
}
public static double code(double f) {
double t_0 = Math.pow(Math.exp(f), (Math.PI / -4.0));
double t_1 = Math.pow(Math.exp((Math.PI / 4.0)), f);
return Math.log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / Math.PI);
}
def code(f): t_0 = math.pow(math.exp(f), (math.pi / -4.0)) t_1 = math.pow(math.exp((math.pi / 4.0)), f) return math.log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / math.pi)
function code(f) t_0 = exp(f) ^ Float64(pi / -4.0) t_1 = exp(Float64(pi / 4.0)) ^ f return Float64(log(Float64(Float64(t_0 + t_1) / Float64(t_1 - t_0))) * Float64(-4.0 / pi)) end
function tmp = code(f) t_0 = exp(f) ^ (pi / -4.0); t_1 = exp((pi / 4.0)) ^ f; tmp = log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / pi); end
code[f_] := Block[{t$95$0 = N[Power[N[Exp[f], $MachinePrecision], N[(Pi / -4.0), $MachinePrecision]], $MachinePrecision]}, Block[{t$95$1 = N[Power[N[Exp[N[(Pi / 4.0), $MachinePrecision]], $MachinePrecision], f], $MachinePrecision]}, N[(N[Log[N[(N[(t$95$0 + t$95$1), $MachinePrecision] / N[(t$95$1 - t$95$0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision] * N[(-4.0 / Pi), $MachinePrecision]), $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := {\left(e^{f}\right)}^{\left(\frac{\pi}{-4}\right)}\\
t_1 := {\left(e^{\frac{\pi}{4}}\right)}^{f}\\
\log \left(\frac{t_0 + t_1}{t_1 - t_0}\right) \cdot \frac{-4}{\pi}
\end{array}
\end{array}
Initial program 5.4%
(FPCore (f) :precision binary64 (let* ((t_0 (pow (exp f) (* -0.25 PI))) (t_1 (pow (exp f) (* 0.25 PI)))) (* (log (/ (+ t_0 t_1) (- t_1 t_0))) (/ -4.0 PI))))
double code(double f) {
double t_0 = pow(exp(f), (-0.25 * ((double) M_PI)));
double t_1 = pow(exp(f), (0.25 * ((double) M_PI)));
return log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / ((double) M_PI));
}
public static double code(double f) {
double t_0 = Math.pow(Math.exp(f), (-0.25 * Math.PI));
double t_1 = Math.pow(Math.exp(f), (0.25 * Math.PI));
return Math.log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / Math.PI);
}
def code(f): t_0 = math.pow(math.exp(f), (-0.25 * math.pi)) t_1 = math.pow(math.exp(f), (0.25 * math.pi)) return math.log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / math.pi)
function code(f) t_0 = exp(f) ^ Float64(-0.25 * pi) t_1 = exp(f) ^ Float64(0.25 * pi) return Float64(log(Float64(Float64(t_0 + t_1) / Float64(t_1 - t_0))) * Float64(-4.0 / pi)) end
function tmp = code(f) t_0 = exp(f) ^ (-0.25 * pi); t_1 = exp(f) ^ (0.25 * pi); tmp = log(((t_0 + t_1) / (t_1 - t_0))) * (-4.0 / pi); end
code[f_] := Block[{t$95$0 = N[Power[N[Exp[f], $MachinePrecision], N[(-0.25 * Pi), $MachinePrecision]], $MachinePrecision]}, Block[{t$95$1 = N[Power[N[Exp[f], $MachinePrecision], N[(0.25 * Pi), $MachinePrecision]], $MachinePrecision]}, N[(N[Log[N[(N[(t$95$0 + t$95$1), $MachinePrecision] / N[(t$95$1 - t$95$0), $MachinePrecision]), $MachinePrecision]], $MachinePrecision] * N[(-4.0 / Pi), $MachinePrecision]), $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := {\left(e^{f}\right)}^{\left(-0.25 \cdot \pi\right)}\\
t_1 := {\left(e^{f}\right)}^{\left(0.25 \cdot \pi\right)}\\
\log \left(\frac{t_0 + t_1}{t_1 - t_0}\right) \cdot \frac{-4}{\pi}
\end{array}
\end{array}
Initial program 5.4%
herbie shell --seed 2023276
(FPCore (f)
:name "VandenBroeck and Keller, Equation (20)"
:precision binary64
(- (* (/ 1.0 (/ PI 4.0)) (log (/ (+ (exp (* (/ PI 4.0) f)) (exp (- (* (/ PI 4.0) f)))) (- (exp (* (/ PI 4.0) f)) (exp (- (* (/ PI 4.0) f)))))))))