(FPCore (v1x v1y v1z v2x v2y v2z) :precision binary64 (fabs (+ (+ (* v1x v2x) (* v1y v2y)) (* v1z v2z))))
double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return fabs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))); }
real(8) function code(v1x, v1y, v1z, v2x, v2y, v2z) real(8), intent (in) :: v1x real(8), intent (in) :: v1y real(8), intent (in) :: v1z real(8), intent (in) :: v2x real(8), intent (in) :: v2y real(8), intent (in) :: v2z code = abs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))) end function
public static double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return Math.abs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))); }
def code(v1x, v1y, v1z, v2x, v2y, v2z): return math.fabs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z)))
function code(v1x, v1y, v1z, v2x, v2y, v2z) return abs(Float64(Float64(Float64(v1x * v2x) + Float64(v1y * v2y)) + Float64(v1z * v2z))) end
function tmp = code(v1x, v1y, v1z, v2x, v2y, v2z) tmp = abs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))); end
code[v1x_, v1y_, v1z_, v2x_, v2y_, v2z_] := N[Abs[N[(N[(N[(v1x * v2x), $MachinePrecision] + N[(v1y * v2y), $MachinePrecision]), $MachinePrecision] + N[(v1z * v2z), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \left|\left(v1x \cdot v2x + v1y \cdot v2y\right) + v1z \cdot v2z\right| \end{array}
Sampling outcomes in binary64 precision:
Herbie found 4 alternatives:
Alternative | Accuracy | Speedup |
---|
(FPCore (v1x v1y v1z v2x v2y v2z) :precision binary64 (fabs (+ (+ (* v1x v2x) (* v1y v2y)) (* v1z v2z))))
double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return fabs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))); }
real(8) function code(v1x, v1y, v1z, v2x, v2y, v2z) real(8), intent (in) :: v1x real(8), intent (in) :: v1y real(8), intent (in) :: v1z real(8), intent (in) :: v2x real(8), intent (in) :: v2y real(8), intent (in) :: v2z code = abs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))) end function
public static double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return Math.abs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))); }
def code(v1x, v1y, v1z, v2x, v2y, v2z): return math.fabs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z)))
function code(v1x, v1y, v1z, v2x, v2y, v2z) return abs(Float64(Float64(Float64(v1x * v2x) + Float64(v1y * v2y)) + Float64(v1z * v2z))) end
function tmp = code(v1x, v1y, v1z, v2x, v2y, v2z) tmp = abs((((v1x * v2x) + (v1y * v2y)) + (v1z * v2z))); end
code[v1x_, v1y_, v1z_, v2x_, v2y_, v2z_] := N[Abs[N[(N[(N[(v1x * v2x), $MachinePrecision] + N[(v1y * v2y), $MachinePrecision]), $MachinePrecision] + N[(v1z * v2z), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \left|\left(v1x \cdot v2x + v1y \cdot v2y\right) + v1z \cdot v2z\right| \end{array}
(FPCore (v1x v1y v1z v2x v2y v2z) :precision binary64 (fabs (fma v2x v1x (fma v2z v1z (* v2y v1y)))))
double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return fabs(fma(v2x, v1x, fma(v2z, v1z, (v2y * v1y)))); }
function code(v1x, v1y, v1z, v2x, v2y, v2z) return abs(fma(v2x, v1x, fma(v2z, v1z, Float64(v2y * v1y)))) end
code[v1x_, v1y_, v1z_, v2x_, v2y_, v2z_] := N[Abs[N[(v2x * v1x + N[(v2z * v1z + N[(v2y * v1y), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \left|\mathsf{fma}\left(v2x, v1x, \mathsf{fma}\left(v2z, v1z, v2y \cdot v1y\right)\right)\right| \end{array}
Initial program 100.0%
lift-+.f64
N/A
lift-+.f64
N/A
associate-+l+
N/A
lift-*.f64
N/A
*-commutative
N/A
lower-fma.f64
N/A
+-commutative
N/A
lift-*.f64
N/A
*-commutative
N/A
lower-fma.f64
100.0
lift-*.f64
N/A
*-commutative
N/A
lower-*.f64
100.0
Applied rewrites100.0%
(FPCore (v1x v1y v1z v2x v2y v2z) :precision binary64 (if (or (<= (* v1y v2y) -2e-254) (not (<= (* v1y v2y) 2e-253))) (fabs (fma v2z v1z (* v2y v1y))) (fabs (fma v2x v1x (* v1z v2z)))))
double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { double tmp; if (((v1y * v2y) <= -2e-254) || !((v1y * v2y) <= 2e-253)) { tmp = fabs(fma(v2z, v1z, (v2y * v1y))); } else { tmp = fabs(fma(v2x, v1x, (v1z * v2z))); } return tmp; }
function code(v1x, v1y, v1z, v2x, v2y, v2z) tmp = 0.0 if ((Float64(v1y * v2y) <= -2e-254) || !(Float64(v1y * v2y) <= 2e-253)) tmp = abs(fma(v2z, v1z, Float64(v2y * v1y))); else tmp = abs(fma(v2x, v1x, Float64(v1z * v2z))); end return tmp end
code[v1x_, v1y_, v1z_, v2x_, v2y_, v2z_] := If[Or[LessEqual[N[(v1y * v2y), $MachinePrecision], -2e-254], N[Not[LessEqual[N[(v1y * v2y), $MachinePrecision], 2e-253]], $MachinePrecision]], N[Abs[N[(v2z * v1z + N[(v2y * v1y), $MachinePrecision]), $MachinePrecision]], $MachinePrecision], N[Abs[N[(v2x * v1x + N[(v1z * v2z), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]]
\begin{array}{l} \\ \begin{array}{l} \mathbf{if}\;v1y \cdot v2y \leq -2 \cdot 10^{-254} \lor \neg \left(v1y \cdot v2y \leq 2 \cdot 10^{-253}\right):\\ \;\;\;\;\left|\mathsf{fma}\left(v2z, v1z, v2y \cdot v1y\right)\right|\\ \mathbf{else}:\\ \;\;\;\;\left|\mathsf{fma}\left(v2x, v1x, v1z \cdot v2z\right)\right|\\ \end{array} \end{array}
if (*.f64 v1y v2y) < -1.9999999999999998e-254 or 2.0000000000000001e-253 < (*.f64 v1y v2y)
Initial program 99.9%
Taylor expanded in v1x around 0
+-commutative
N/A
*-commutative
N/A
lower-fma.f64
N/A
*-commutative
N/A
lower-*.f64
83.9
Applied rewrites83.9%
if -1.9999999999999998e-254 < (*.f64 v1y v2y) < 2.0000000000000001e-253
Initial program 100.0%
Taylor expanded in v1y around 0
+-commutative
N/A
*-commutative
N/A
lower-fma.f64
N/A
*-commutative
N/A
lower-*.f64
92.3
Applied rewrites92.3%
Applied rewrites92.3%
Final simplification89.5%
(FPCore (v1x v1y v1z v2x v2y v2z) :precision binary64 (fabs (fma v2x v1x (* v1z v2z))))
double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return fabs(fma(v2x, v1x, (v1z * v2z))); }
function code(v1x, v1y, v1z, v2x, v2y, v2z) return abs(fma(v2x, v1x, Float64(v1z * v2z))) end
code[v1x_, v1y_, v1z_, v2x_, v2y_, v2z_] := N[Abs[N[(v2x * v1x + N[(v1z * v2z), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \left|\mathsf{fma}\left(v2x, v1x, v1z \cdot v2z\right)\right| \end{array}
Initial program 100.0%
Taylor expanded in v1y around 0
+-commutative
N/A
*-commutative
N/A
lower-fma.f64
N/A
*-commutative
N/A
lower-*.f64
72.2
Applied rewrites72.2%
Applied rewrites72.2%
(FPCore (v1x v1y v1z v2x v2y v2z) :precision binary64 (fabs (* v2z v1z)))
double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return fabs((v2z * v1z)); }
real(8) function code(v1x, v1y, v1z, v2x, v2y, v2z) real(8), intent (in) :: v1x real(8), intent (in) :: v1y real(8), intent (in) :: v1z real(8), intent (in) :: v2x real(8), intent (in) :: v2y real(8), intent (in) :: v2z code = abs((v2z * v1z)) end function
public static double code(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) { return Math.abs((v2z * v1z)); }
def code(v1x, v1y, v1z, v2x, v2y, v2z): return math.fabs((v2z * v1z))
function code(v1x, v1y, v1z, v2x, v2y, v2z) return abs(Float64(v2z * v1z)) end
function tmp = code(v1x, v1y, v1z, v2x, v2y, v2z) tmp = abs((v2z * v1z)); end
code[v1x_, v1y_, v1z_, v2x_, v2y_, v2z_] := N[Abs[N[(v2z * v1z), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \left|v2z \cdot v1z\right| \end{array}
Initial program 100.0%
Taylor expanded in v1z around inf
*-commutative
N/A
lower-*.f64
43.0
Applied rewrites43.0%
herbie shell --seed 1
(FPCore (v1x v1y v1z v2x v2y v2z)
:name "perp_calc_using_dot_prod"
:precision binary64
:pre (and (and (and (and (and (and (<= -1.0 v1x) (<= v1x 1.0)) (and (<= -1.0 v1y) (<= v1y 1.0))) (and (<= -1.0 v1z) (<= v1z 1.0))) (and (<= -1.0 v2x) (<= v2x 1.0))) (and (<= -1.0 v2y) (<= v2y 1.0))) (and (<= -1.0 v2z) (<= v2z 1.0)))
(fabs (+ (+ (* v1x v2x) (* v1y v2y)) (* v1z v2z))))