
(FPCore (a b) :precision binary64 (- (+ (pow (+ (* a a) (* b b)) 2.0) (* 4.0 (+ (* (* a a) (- 1.0 a)) (* (* b b) (+ 3.0 a))))) 1.0))
double code(double a, double b) {
return (pow(((a * a) + (b * b)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = ((((a * a) + (b * b)) ** 2.0d0) + (4.0d0 * (((a * a) * (1.0d0 - a)) + ((b * b) * (3.0d0 + a))))) - 1.0d0
end function
public static double code(double a, double b) {
return (Math.pow(((a * a) + (b * b)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0;
}
def code(a, b): return (math.pow(((a * a) + (b * b)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0
function code(a, b) return Float64(Float64((Float64(Float64(a * a) + Float64(b * b)) ^ 2.0) + Float64(4.0 * Float64(Float64(Float64(a * a) * Float64(1.0 - a)) + Float64(Float64(b * b) * Float64(3.0 + a))))) - 1.0) end
function tmp = code(a, b) tmp = ((((a * a) + (b * b)) ^ 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0; end
code[a_, b_] := N[(N[(N[Power[N[(N[(a * a), $MachinePrecision] + N[(b * b), $MachinePrecision]), $MachinePrecision], 2.0], $MachinePrecision] + N[(4.0 * N[(N[(N[(a * a), $MachinePrecision] * N[(1.0 - a), $MachinePrecision]), $MachinePrecision] + N[(N[(b * b), $MachinePrecision] * N[(3.0 + a), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] - 1.0), $MachinePrecision]
\begin{array}{l}
\\
\left({\left(a \cdot a + b \cdot b\right)}^{2} + 4 \cdot \left(\left(a \cdot a\right) \cdot \left(1 - a\right) + \left(b \cdot b\right) \cdot \left(3 + a\right)\right)\right) - 1
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 6 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (a b) :precision binary64 (- (+ (pow (+ (* a a) (* b b)) 2.0) (* 4.0 (+ (* (* a a) (- 1.0 a)) (* (* b b) (+ 3.0 a))))) 1.0))
double code(double a, double b) {
return (pow(((a * a) + (b * b)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = ((((a * a) + (b * b)) ** 2.0d0) + (4.0d0 * (((a * a) * (1.0d0 - a)) + ((b * b) * (3.0d0 + a))))) - 1.0d0
end function
public static double code(double a, double b) {
return (Math.pow(((a * a) + (b * b)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0;
}
def code(a, b): return (math.pow(((a * a) + (b * b)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0
function code(a, b) return Float64(Float64((Float64(Float64(a * a) + Float64(b * b)) ^ 2.0) + Float64(4.0 * Float64(Float64(Float64(a * a) * Float64(1.0 - a)) + Float64(Float64(b * b) * Float64(3.0 + a))))) - 1.0) end
function tmp = code(a, b) tmp = ((((a * a) + (b * b)) ^ 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (3.0 + a))))) - 1.0; end
code[a_, b_] := N[(N[(N[Power[N[(N[(a * a), $MachinePrecision] + N[(b * b), $MachinePrecision]), $MachinePrecision], 2.0], $MachinePrecision] + N[(4.0 * N[(N[(N[(a * a), $MachinePrecision] * N[(1.0 - a), $MachinePrecision]), $MachinePrecision] + N[(N[(b * b), $MachinePrecision] * N[(3.0 + a), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] - 1.0), $MachinePrecision]
\begin{array}{l}
\\
\left({\left(a \cdot a + b \cdot b\right)}^{2} + 4 \cdot \left(\left(a \cdot a\right) \cdot \left(1 - a\right) + \left(b \cdot b\right) \cdot \left(3 + a\right)\right)\right) - 1
\end{array}
(FPCore (a b) :precision binary64 (if (<= a 4.5e+55) (+ (pow (fma a a (* b b)) 2.0) (+ (* 4.0 (- (pow a 2.0) (pow a 3.0))) -1.0)) (pow a 4.0)))
double code(double a, double b) {
double tmp;
if (a <= 4.5e+55) {
tmp = pow(fma(a, a, (b * b)), 2.0) + ((4.0 * (pow(a, 2.0) - pow(a, 3.0))) + -1.0);
} else {
tmp = pow(a, 4.0);
}
return tmp;
}
function code(a, b) tmp = 0.0 if (a <= 4.5e+55) tmp = Float64((fma(a, a, Float64(b * b)) ^ 2.0) + Float64(Float64(4.0 * Float64((a ^ 2.0) - (a ^ 3.0))) + -1.0)); else tmp = a ^ 4.0; end return tmp end
code[a_, b_] := If[LessEqual[a, 4.5e+55], N[(N[Power[N[(a * a + N[(b * b), $MachinePrecision]), $MachinePrecision], 2.0], $MachinePrecision] + N[(N[(4.0 * N[(N[Power[a, 2.0], $MachinePrecision] - N[Power[a, 3.0], $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + -1.0), $MachinePrecision]), $MachinePrecision], N[Power[a, 4.0], $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq 4.5 \cdot 10^{+55}:\\
\;\;\;\;{\left(\mathsf{fma}\left(a, a, b \cdot b\right)\right)}^{2} + \left(4 \cdot \left({a}^{2} - {a}^{3}\right) + -1\right)\\
\mathbf{else}:\\
\;\;\;\;{a}^{4}\\
\end{array}
\end{array}
if a < 4.49999999999999998e55Initial program 88.4%
associate--l+88.3%
fma-def88.3%
distribute-rgt-in87.9%
sqr-neg87.9%
distribute-rgt-in88.3%
fma-def88.3%
sqr-neg88.3%
+-commutative88.3%
Simplified88.3%
Taylor expanded in a around inf 98.8%
+-commutative98.8%
mul-1-neg98.8%
unsub-neg98.8%
Simplified98.8%
if 4.49999999999999998e55 < a Initial program 21.8%
associate--l+21.8%
fma-def21.8%
distribute-rgt-in21.8%
sqr-neg21.8%
distribute-rgt-in21.8%
fma-def27.2%
sqr-neg27.2%
+-commutative27.2%
Simplified27.2%
Taylor expanded in a around inf 100.0%
Final simplification99.1%
(FPCore (a b)
:precision binary64
(let* ((t_0
(+
(pow (+ (* b b) (* a a)) 2.0)
(* 4.0 (+ (* (* a a) (- 1.0 a)) (* (* b b) (+ a 3.0)))))))
(if (<= t_0 INFINITY) (+ t_0 -1.0) (pow a 4.0))))
double code(double a, double b) {
double t_0 = pow(((b * b) + (a * a)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (a + 3.0))));
double tmp;
if (t_0 <= ((double) INFINITY)) {
tmp = t_0 + -1.0;
} else {
tmp = pow(a, 4.0);
}
return tmp;
}
public static double code(double a, double b) {
double t_0 = Math.pow(((b * b) + (a * a)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (a + 3.0))));
double tmp;
if (t_0 <= Double.POSITIVE_INFINITY) {
tmp = t_0 + -1.0;
} else {
tmp = Math.pow(a, 4.0);
}
return tmp;
}
def code(a, b): t_0 = math.pow(((b * b) + (a * a)), 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (a + 3.0)))) tmp = 0 if t_0 <= math.inf: tmp = t_0 + -1.0 else: tmp = math.pow(a, 4.0) return tmp
function code(a, b) t_0 = Float64((Float64(Float64(b * b) + Float64(a * a)) ^ 2.0) + Float64(4.0 * Float64(Float64(Float64(a * a) * Float64(1.0 - a)) + Float64(Float64(b * b) * Float64(a + 3.0))))) tmp = 0.0 if (t_0 <= Inf) tmp = Float64(t_0 + -1.0); else tmp = a ^ 4.0; end return tmp end
function tmp_2 = code(a, b) t_0 = (((b * b) + (a * a)) ^ 2.0) + (4.0 * (((a * a) * (1.0 - a)) + ((b * b) * (a + 3.0)))); tmp = 0.0; if (t_0 <= Inf) tmp = t_0 + -1.0; else tmp = a ^ 4.0; end tmp_2 = tmp; end
code[a_, b_] := Block[{t$95$0 = N[(N[Power[N[(N[(b * b), $MachinePrecision] + N[(a * a), $MachinePrecision]), $MachinePrecision], 2.0], $MachinePrecision] + N[(4.0 * N[(N[(N[(a * a), $MachinePrecision] * N[(1.0 - a), $MachinePrecision]), $MachinePrecision] + N[(N[(b * b), $MachinePrecision] * N[(a + 3.0), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]}, If[LessEqual[t$95$0, Infinity], N[(t$95$0 + -1.0), $MachinePrecision], N[Power[a, 4.0], $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
t_0 := {\left(b \cdot b + a \cdot a\right)}^{2} + 4 \cdot \left(\left(a \cdot a\right) \cdot \left(1 - a\right) + \left(b \cdot b\right) \cdot \left(a + 3\right)\right)\\
\mathbf{if}\;t_0 \leq \infty:\\
\;\;\;\;t_0 + -1\\
\mathbf{else}:\\
\;\;\;\;{a}^{4}\\
\end{array}
\end{array}
if (+.f64 (pow.f64 (+.f64 (*.f64 a a) (*.f64 b b)) 2) (*.f64 4 (+.f64 (*.f64 (*.f64 a a) (-.f64 1 a)) (*.f64 (*.f64 b b) (+.f64 3 a))))) < +inf.0Initial program 99.8%
if +inf.0 < (+.f64 (pow.f64 (+.f64 (*.f64 a a) (*.f64 b b)) 2) (*.f64 4 (+.f64 (*.f64 (*.f64 a a) (-.f64 1 a)) (*.f64 (*.f64 b b) (+.f64 3 a))))) Initial program 0.0%
associate--l+0.0%
fma-def0.0%
distribute-rgt-in0.0%
sqr-neg0.0%
distribute-rgt-in0.0%
fma-def4.5%
sqr-neg4.5%
+-commutative4.5%
Simplified4.5%
Taylor expanded in a around inf 88.6%
Final simplification96.9%
(FPCore (a b) :precision binary64 (if (<= b 4.9e-213) (pow a 4.0) (if (<= b 1.7e-136) -1.0 (if (<= b 3.8e+45) (pow a 4.0) (pow b 4.0)))))
double code(double a, double b) {
double tmp;
if (b <= 4.9e-213) {
tmp = pow(a, 4.0);
} else if (b <= 1.7e-136) {
tmp = -1.0;
} else if (b <= 3.8e+45) {
tmp = pow(a, 4.0);
} else {
tmp = pow(b, 4.0);
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if (b <= 4.9d-213) then
tmp = a ** 4.0d0
else if (b <= 1.7d-136) then
tmp = -1.0d0
else if (b <= 3.8d+45) then
tmp = a ** 4.0d0
else
tmp = b ** 4.0d0
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if (b <= 4.9e-213) {
tmp = Math.pow(a, 4.0);
} else if (b <= 1.7e-136) {
tmp = -1.0;
} else if (b <= 3.8e+45) {
tmp = Math.pow(a, 4.0);
} else {
tmp = Math.pow(b, 4.0);
}
return tmp;
}
def code(a, b): tmp = 0 if b <= 4.9e-213: tmp = math.pow(a, 4.0) elif b <= 1.7e-136: tmp = -1.0 elif b <= 3.8e+45: tmp = math.pow(a, 4.0) else: tmp = math.pow(b, 4.0) return tmp
function code(a, b) tmp = 0.0 if (b <= 4.9e-213) tmp = a ^ 4.0; elseif (b <= 1.7e-136) tmp = -1.0; elseif (b <= 3.8e+45) tmp = a ^ 4.0; else tmp = b ^ 4.0; end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if (b <= 4.9e-213) tmp = a ^ 4.0; elseif (b <= 1.7e-136) tmp = -1.0; elseif (b <= 3.8e+45) tmp = a ^ 4.0; else tmp = b ^ 4.0; end tmp_2 = tmp; end
code[a_, b_] := If[LessEqual[b, 4.9e-213], N[Power[a, 4.0], $MachinePrecision], If[LessEqual[b, 1.7e-136], -1.0, If[LessEqual[b, 3.8e+45], N[Power[a, 4.0], $MachinePrecision], N[Power[b, 4.0], $MachinePrecision]]]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;b \leq 4.9 \cdot 10^{-213}:\\
\;\;\;\;{a}^{4}\\
\mathbf{elif}\;b \leq 1.7 \cdot 10^{-136}:\\
\;\;\;\;-1\\
\mathbf{elif}\;b \leq 3.8 \cdot 10^{+45}:\\
\;\;\;\;{a}^{4}\\
\mathbf{else}:\\
\;\;\;\;{b}^{4}\\
\end{array}
\end{array}
if b < 4.8999999999999998e-213 or 1.7e-136 < b < 3.8000000000000002e45Initial program 74.2%
associate--l+74.2%
fma-def74.2%
distribute-rgt-in74.2%
sqr-neg74.2%
distribute-rgt-in74.2%
fma-def74.7%
sqr-neg74.7%
+-commutative74.7%
Simplified74.7%
Taylor expanded in a around inf 46.7%
if 4.8999999999999998e-213 < b < 1.7e-136Initial program 84.4%
associate--l+84.4%
fma-def84.4%
distribute-rgt-in84.4%
sqr-neg84.4%
distribute-rgt-in84.4%
fma-def84.4%
sqr-neg84.4%
+-commutative84.4%
Simplified84.4%
Taylor expanded in a around inf 84.4%
+-commutative84.4%
mul-1-neg84.4%
unsub-neg84.4%
Simplified84.4%
Taylor expanded in b around 0 84.6%
+-commutative84.6%
associate--l+84.6%
fma-neg84.6%
metadata-eval84.6%
Simplified84.6%
Taylor expanded in a around 0 69.5%
if 3.8000000000000002e45 < b Initial program 71.1%
associate--l+71.1%
fma-def71.1%
distribute-rgt-in69.1%
sqr-neg69.1%
distribute-rgt-in71.1%
fma-def74.9%
sqr-neg74.9%
+-commutative74.9%
Simplified74.9%
Taylor expanded in b around inf 92.8%
Final simplification57.2%
(FPCore (a b) :precision binary64 (if (or (<= a -2.5e+36) (not (<= a 1.8e+20))) (pow a 4.0) (+ (pow b 4.0) -1.0)))
double code(double a, double b) {
double tmp;
if ((a <= -2.5e+36) || !(a <= 1.8e+20)) {
tmp = pow(a, 4.0);
} else {
tmp = pow(b, 4.0) + -1.0;
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if ((a <= (-2.5d+36)) .or. (.not. (a <= 1.8d+20))) then
tmp = a ** 4.0d0
else
tmp = (b ** 4.0d0) + (-1.0d0)
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if ((a <= -2.5e+36) || !(a <= 1.8e+20)) {
tmp = Math.pow(a, 4.0);
} else {
tmp = Math.pow(b, 4.0) + -1.0;
}
return tmp;
}
def code(a, b): tmp = 0 if (a <= -2.5e+36) or not (a <= 1.8e+20): tmp = math.pow(a, 4.0) else: tmp = math.pow(b, 4.0) + -1.0 return tmp
function code(a, b) tmp = 0.0 if ((a <= -2.5e+36) || !(a <= 1.8e+20)) tmp = a ^ 4.0; else tmp = Float64((b ^ 4.0) + -1.0); end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if ((a <= -2.5e+36) || ~((a <= 1.8e+20))) tmp = a ^ 4.0; else tmp = (b ^ 4.0) + -1.0; end tmp_2 = tmp; end
code[a_, b_] := If[Or[LessEqual[a, -2.5e+36], N[Not[LessEqual[a, 1.8e+20]], $MachinePrecision]], N[Power[a, 4.0], $MachinePrecision], N[(N[Power[b, 4.0], $MachinePrecision] + -1.0), $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq -2.5 \cdot 10^{+36} \lor \neg \left(a \leq 1.8 \cdot 10^{+20}\right):\\
\;\;\;\;{a}^{4}\\
\mathbf{else}:\\
\;\;\;\;{b}^{4} + -1\\
\end{array}
\end{array}
if a < -2.49999999999999988e36 or 1.8e20 < a Initial program 44.6%
associate--l+44.6%
fma-def44.6%
distribute-rgt-in43.7%
sqr-neg43.7%
distribute-rgt-in44.6%
fma-def47.2%
sqr-neg47.2%
+-commutative47.2%
Simplified47.2%
Taylor expanded in a around inf 93.4%
if -2.49999999999999988e36 < a < 1.8e20Initial program 97.7%
associate--l+97.7%
fma-def97.7%
distribute-rgt-in97.7%
sqr-neg97.7%
distribute-rgt-in97.7%
fma-def97.7%
sqr-neg97.7%
+-commutative97.7%
Simplified97.7%
Taylor expanded in a around inf 98.4%
+-commutative98.4%
mul-1-neg98.4%
unsub-neg98.4%
Simplified98.4%
Taylor expanded in a around 0 96.1%
Final simplification94.9%
(FPCore (a b) :precision binary64 (if (or (<= a -0.41) (not (<= a 0.74))) (pow a 4.0) -1.0))
double code(double a, double b) {
double tmp;
if ((a <= -0.41) || !(a <= 0.74)) {
tmp = pow(a, 4.0);
} else {
tmp = -1.0;
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if ((a <= (-0.41d0)) .or. (.not. (a <= 0.74d0))) then
tmp = a ** 4.0d0
else
tmp = -1.0d0
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if ((a <= -0.41) || !(a <= 0.74)) {
tmp = Math.pow(a, 4.0);
} else {
tmp = -1.0;
}
return tmp;
}
def code(a, b): tmp = 0 if (a <= -0.41) or not (a <= 0.74): tmp = math.pow(a, 4.0) else: tmp = -1.0 return tmp
function code(a, b) tmp = 0.0 if ((a <= -0.41) || !(a <= 0.74)) tmp = a ^ 4.0; else tmp = -1.0; end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if ((a <= -0.41) || ~((a <= 0.74))) tmp = a ^ 4.0; else tmp = -1.0; end tmp_2 = tmp; end
code[a_, b_] := If[Or[LessEqual[a, -0.41], N[Not[LessEqual[a, 0.74]], $MachinePrecision]], N[Power[a, 4.0], $MachinePrecision], -1.0]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq -0.41 \lor \neg \left(a \leq 0.74\right):\\
\;\;\;\;{a}^{4}\\
\mathbf{else}:\\
\;\;\;\;-1\\
\end{array}
\end{array}
if a < -0.409999999999999976 or 0.73999999999999999 < a Initial program 46.6%
associate--l+46.5%
fma-def46.5%
distribute-rgt-in45.7%
sqr-neg45.7%
distribute-rgt-in46.5%
fma-def49.0%
sqr-neg49.0%
+-commutative49.0%
Simplified49.0%
Taylor expanded in a around inf 86.6%
if -0.409999999999999976 < a < 0.73999999999999999Initial program 99.9%
associate--l+99.9%
fma-def99.9%
distribute-rgt-in99.9%
sqr-neg99.9%
distribute-rgt-in99.9%
fma-def99.9%
sqr-neg99.9%
+-commutative99.9%
Simplified99.9%
Taylor expanded in a around inf 98.3%
+-commutative98.3%
mul-1-neg98.3%
unsub-neg98.3%
Simplified98.3%
Taylor expanded in b around 0 41.7%
+-commutative41.7%
associate--l+41.7%
fma-neg41.7%
metadata-eval41.7%
Simplified41.7%
Taylor expanded in a around 0 41.1%
Final simplification63.1%
(FPCore (a b) :precision binary64 -1.0)
double code(double a, double b) {
return -1.0;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = -1.0d0
end function
public static double code(double a, double b) {
return -1.0;
}
def code(a, b): return -1.0
function code(a, b) return -1.0 end
function tmp = code(a, b) tmp = -1.0; end
code[a_, b_] := -1.0
\begin{array}{l}
\\
-1
\end{array}
Initial program 74.1%
associate--l+74.0%
fma-def74.0%
distribute-rgt-in73.7%
sqr-neg73.7%
distribute-rgt-in74.0%
fma-def75.2%
sqr-neg75.2%
+-commutative75.2%
Simplified75.2%
Taylor expanded in a around inf 82.3%
+-commutative82.3%
mul-1-neg82.3%
unsub-neg82.3%
Simplified82.3%
Taylor expanded in b around 0 47.2%
+-commutative47.2%
associate--l+47.2%
fma-neg47.2%
metadata-eval47.2%
Simplified47.2%
Taylor expanded in a around 0 21.5%
Final simplification21.5%
herbie shell --seed 2024021
(FPCore (a b)
:name "Bouland and Aaronson, Equation (24)"
:precision binary64
(- (+ (pow (+ (* a a) (* b b)) 2.0) (* 4.0 (+ (* (* a a) (- 1.0 a)) (* (* b b) (+ 3.0 a))))) 1.0))