\[\left(\left(x + y \cdot z\right) + t \cdot a\right) + \left(a \cdot z\right) \cdot b
\]
↓
\[\begin{array}{l}
t_1 := x + y \cdot z\\
\mathbf{if}\;z \leq -1.1 \cdot 10^{+57}:\\
\;\;\;\;\left(t \cdot a + t_1\right) + z \cdot \left(b \cdot a\right)\\
\mathbf{elif}\;z \leq 10^{-50}:\\
\;\;\;\;\left(a \cdot \left(b \cdot z\right) + t \cdot a\right) + t_1\\
\mathbf{else}:\\
\;\;\;\;z \cdot \left(y + b \cdot a\right) + \left(x + t \cdot a\right)\\
\end{array}
\]
(FPCore (x y z t a b)
:precision binary64
(+ (+ (+ x (* y z)) (* t a)) (* (* a z) b)))
↓
(FPCore (x y z t a b)
:precision binary64
(let* ((t_1 (+ x (* y z))))
(if (<= z -1.1e+57)
(+ (+ (* t a) t_1) (* z (* b a)))
(if (<= z 1e-50)
(+ (+ (* a (* b z)) (* t a)) t_1)
(+ (* z (+ y (* b a))) (+ x (* t a)))))))
double code(double x, double y, double z, double t, double a, double b) {
double t_1 = x + (y * z);
double tmp;
if (z <= -1.1e+57) {
tmp = ((t * a) + t_1) + (z * (b * a));
} else if (z <= 1e-50) {
tmp = ((a * (b * z)) + (t * a)) + t_1;
} else {
tmp = (z * (y + (b * a))) + (x + (t * a));
}
return tmp;
}
real(8) function code(x, y, z, t, a, b)
real(8), intent (in) :: x
real(8), intent (in) :: y
real(8), intent (in) :: z
real(8), intent (in) :: t
real(8), intent (in) :: a
real(8), intent (in) :: b
code = ((x + (y * z)) + (t * a)) + ((a * z) * b)
end function
↓
real(8) function code(x, y, z, t, a, b)
real(8), intent (in) :: x
real(8), intent (in) :: y
real(8), intent (in) :: z
real(8), intent (in) :: t
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: t_1
real(8) :: tmp
t_1 = x + (y * z)
if (z <= (-1.1d+57)) then
tmp = ((t * a) + t_1) + (z * (b * a))
else if (z <= 1d-50) then
tmp = ((a * (b * z)) + (t * a)) + t_1
else
tmp = (z * (y + (b * a))) + (x + (t * a))
end if
code = tmp
end function
public static double code(double x, double y, double z, double t, double a, double b) {
return ((x + (y * z)) + (t * a)) + ((a * z) * b);
}
↓
public static double code(double x, double y, double z, double t, double a, double b) {
double t_1 = x + (y * z);
double tmp;
if (z <= -1.1e+57) {
tmp = ((t * a) + t_1) + (z * (b * a));
} else if (z <= 1e-50) {
tmp = ((a * (b * z)) + (t * a)) + t_1;
} else {
tmp = (z * (y + (b * a))) + (x + (t * a));
}
return tmp;
}
def code(x, y, z, t, a, b):
return ((x + (y * z)) + (t * a)) + ((a * z) * b)
↓
def code(x, y, z, t, a, b):
t_1 = x + (y * z)
tmp = 0
if z <= -1.1e+57:
tmp = ((t * a) + t_1) + (z * (b * a))
elif z <= 1e-50:
tmp = ((a * (b * z)) + (t * a)) + t_1
else:
tmp = (z * (y + (b * a))) + (x + (t * a))
return tmp
function code(x, y, z, t, a, b)
return Float64(Float64(Float64(x + Float64(y * z)) + Float64(t * a)) + Float64(Float64(a * z) * b))
end
↓
function code(x, y, z, t, a, b)
t_1 = Float64(x + Float64(y * z))
tmp = 0.0
if (z <= -1.1e+57)
tmp = Float64(Float64(Float64(t * a) + t_1) + Float64(z * Float64(b * a)));
elseif (z <= 1e-50)
tmp = Float64(Float64(Float64(a * Float64(b * z)) + Float64(t * a)) + t_1);
else
tmp = Float64(Float64(z * Float64(y + Float64(b * a))) + Float64(x + Float64(t * a)));
end
return tmp
end
function tmp = code(x, y, z, t, a, b)
tmp = ((x + (y * z)) + (t * a)) + ((a * z) * b);
end
↓
function tmp_2 = code(x, y, z, t, a, b)
t_1 = x + (y * z);
tmp = 0.0;
if (z <= -1.1e+57)
tmp = ((t * a) + t_1) + (z * (b * a));
elseif (z <= 1e-50)
tmp = ((a * (b * z)) + (t * a)) + t_1;
else
tmp = (z * (y + (b * a))) + (x + (t * a));
end
tmp_2 = tmp;
end
\left(\left(x + y \cdot z\right) + t \cdot a\right) + \left(a \cdot z\right) \cdot b
↓
\begin{array}{l}
t_1 := x + y \cdot z\\
\mathbf{if}\;z \leq -1.1 \cdot 10^{+57}:\\
\;\;\;\;\left(t \cdot a + t_1\right) + z \cdot \left(b \cdot a\right)\\
\mathbf{elif}\;z \leq 10^{-50}:\\
\;\;\;\;\left(a \cdot \left(b \cdot z\right) + t \cdot a\right) + t_1\\
\mathbf{else}:\\
\;\;\;\;z \cdot \left(y + b \cdot a\right) + \left(x + t \cdot a\right)\\
\end{array}
Error
Try it out
Results
Enter valid numbers for all inputs
Target
Original
2.0
Target
0.3
Herbie
0.2
\[\begin{array}{l}
\mathbf{if}\;z < -11820553527347888000:\\
\;\;\;\;z \cdot \left(b \cdot a + y\right) + \left(x + t \cdot a\right)\\
\mathbf{elif}\;z < 4.7589743188364287 \cdot 10^{-122}:\\
\;\;\;\;\left(b \cdot z + t\right) \cdot a + \left(z \cdot y + x\right)\\
\mathbf{else}:\\
\;\;\;\;z \cdot \left(b \cdot a + y\right) + \left(x + t \cdot a\right)\\
\end{array}
\]
Derivation
Split input into 3 regimes
if z < -1.1e57
Initial program 6.4
\[\left(\left(x + y \cdot z\right) + t \cdot a\right) + \left(a \cdot z\right) \cdot b
\]
Taylor expanded in a around 0 9.5
\[\leadsto \left(\left(x + y \cdot z\right) + t \cdot a\right) + \color{blue}{a \cdot \left(b \cdot z\right)}
\]
Simplified0.1
\[\leadsto \left(\left(x + y \cdot z\right) + t \cdot a\right) + \color{blue}{\left(a \cdot b\right) \cdot z}
\]
Proof
(*.f64 (*.f64 a b) z): 0 points increase in error, 0 points decrease in error
(Rewrite<= associate-*r*_binary64 (*.f64 a (*.f64 b z))): 40 points increase in error, 59 points decrease in error
if -1.1e57 < z < 1.00000000000000001e-50
Initial program 0.5
\[\left(\left(x + y \cdot z\right) + t \cdot a\right) + \left(a \cdot z\right) \cdot b
\]
Simplified0.2
\[\leadsto \color{blue}{\left(x + y \cdot z\right) + \left(t \cdot a + a \cdot \left(z \cdot b\right)\right)}
\]
Proof
(+.f64 (+.f64 x (*.f64 y z)) (+.f64 (*.f64 t a) (*.f64 a (*.f64 z b)))): 0 points increase in error, 0 points decrease in error
(+.f64 (+.f64 x (*.f64 y z)) (+.f64 (*.f64 t a) (Rewrite<= associate-*l*_binary64 (*.f64 (*.f64 a z) b)))): 11 points increase in error, 16 points decrease in error
(Rewrite<= associate-+l+_binary64 (+.f64 (+.f64 (+.f64 x (*.f64 y z)) (*.f64 t a)) (*.f64 (*.f64 a z) b))): 0 points increase in error, 0 points decrease in error
if 1.00000000000000001e-50 < z
Initial program 3.9
\[\left(\left(x + y \cdot z\right) + t \cdot a\right) + \left(a \cdot z\right) \cdot b
\]
Simplified5.5
\[\leadsto \color{blue}{\left(x + y \cdot z\right) + \left(t \cdot a + a \cdot \left(z \cdot b\right)\right)}
\]
Proof
(+.f64 (+.f64 x (*.f64 y z)) (+.f64 (*.f64 t a) (*.f64 a (*.f64 z b)))): 0 points increase in error, 0 points decrease in error
(+.f64 (+.f64 x (*.f64 y z)) (+.f64 (*.f64 t a) (Rewrite<= associate-*l*_binary64 (*.f64 (*.f64 a z) b)))): 11 points increase in error, 16 points decrease in error
(Rewrite<= associate-+l+_binary64 (+.f64 (+.f64 (+.f64 x (*.f64 y z)) (*.f64 t a)) (*.f64 (*.f64 a z) b))): 0 points increase in error, 0 points decrease in error
Taylor expanded in z around 0 0.2
\[\leadsto \color{blue}{z \cdot \left(a \cdot b + y\right) + \left(a \cdot t + x\right)}
\]
Recombined 3 regimes into one program.
Final simplification0.2
\[\leadsto \begin{array}{l}
\mathbf{if}\;z \leq -1.1 \cdot 10^{+57}:\\
\;\;\;\;\left(t \cdot a + \left(x + y \cdot z\right)\right) + z \cdot \left(b \cdot a\right)\\
\mathbf{elif}\;z \leq 10^{-50}:\\
\;\;\;\;\left(a \cdot \left(b \cdot z\right) + t \cdot a\right) + \left(x + y \cdot z\right)\\
\mathbf{else}:\\
\;\;\;\;z \cdot \left(y + b \cdot a\right) + \left(x + t \cdot a\right)\\
\end{array}
\]
Alternatives
Alternative 1
Error
0.3
Cost
13640
\[\begin{array}{l}
t_1 := \left(t \cdot a + \left(x + y \cdot z\right)\right) + b \cdot \left(z \cdot a\right)\\
\mathbf{if}\;b \leq -1 \cdot 10^{+42}:\\
\;\;\;\;t_1\\
\mathbf{elif}\;b \leq 10^{+46}:\\
\;\;\;\;\mathsf{fma}\left(a, t + b \cdot z, \mathsf{fma}\left(y, z, x\right)\right)\\
\mathbf{else}:\\
\;\;\;\;t_1\\
\end{array}
\]
Alternative 2
Error
19.1
Cost
1372
\[\begin{array}{l}
t_1 := y \cdot z + t \cdot a\\
t_2 := x + y \cdot z\\
t_3 := z \cdot \left(y + b \cdot a\right)\\
t_4 := x + t \cdot a\\
\mathbf{if}\;x \leq -4.3 \cdot 10^{-126}:\\
\;\;\;\;t_4\\
\mathbf{elif}\;x \leq 4.7 \cdot 10^{-85}:\\
\;\;\;\;t_1\\
\mathbf{elif}\;x \leq 6.6 \cdot 10^{-18}:\\
\;\;\;\;t_3\\
\mathbf{elif}\;x \leq 10^{+22}:\\
\;\;\;\;t_4\\
\mathbf{elif}\;x \leq 1.5 \cdot 10^{+27}:\\
\;\;\;\;t_3\\
\mathbf{elif}\;x \leq 4 \cdot 10^{+42}:\\
\;\;\;\;t_2\\
\mathbf{elif}\;x \leq 9 \cdot 10^{+48}:\\
\;\;\;\;t_1\\
\mathbf{else}:\\
\;\;\;\;t_2\\
\end{array}
\]
Alternative 3
Error
0.2
Cost
1224
\[\begin{array}{l}
t_1 := z \cdot \left(y + b \cdot a\right) + \left(x + t \cdot a\right)\\
\mathbf{if}\;z \leq -4 \cdot 10^{+57}:\\
\;\;\;\;t_1\\
\mathbf{elif}\;z \leq 10^{-50}:\\
\;\;\;\;\left(a \cdot \left(b \cdot z\right) + t \cdot a\right) + \left(x + y \cdot z\right)\\
\mathbf{else}:\\
\;\;\;\;t_1\\
\end{array}
\]
Alternative 4
Error
0.4
Cost
1224
\[\begin{array}{l}
t_1 := t \cdot a + \left(x + y \cdot z\right)\\
t_2 := t_1 + b \cdot \left(z \cdot a\right)\\
\mathbf{if}\;b \leq -7.5 \cdot 10^{+77}:\\
\;\;\;\;t_2\\
\mathbf{elif}\;b \leq 2 \cdot 10^{+73}:\\
\;\;\;\;t_1 + z \cdot \left(b \cdot a\right)\\
\mathbf{else}:\\
\;\;\;\;t_2\\
\end{array}
\]
herbie shell --seed 2022332
(FPCore (x y z t a b)
:name "Graphics.Rasterific.CubicBezier:cachedBezierAt from Rasterific-0.6.1"
:precision binary64
:herbie-target
(if (< z -11820553527347888000.0) (+ (* z (+ (* b a) y)) (+ x (* t a))) (if (< z 4.7589743188364287e-122) (+ (* (+ (* b z) t) a) (+ (* z y) x)) (+ (* z (+ (* b a) y)) (+ x (* t a)))))
(+ (+ (+ x (* y z)) (* t a)) (* (* a z) b)))