(FPCore (x y z) :precision binary64 (sqrt (/ (+ (+ (* x x) (* y y)) (* z z)) 3.0)))
double code(double x, double y, double z) { return sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0)); }
module fmin_fmax_functions implicit none private public fmax public fmin interface fmax module procedure fmax88 module procedure fmax44 module procedure fmax84 module procedure fmax48 end interface interface fmin module procedure fmin88 module procedure fmin44 module procedure fmin84 module procedure fmin48 end interface contains real(8) function fmax88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(4) function fmax44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(8) function fmax84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, max(x, dble(y)), y /= y), x /= x) end function real(8) function fmax48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), max(dble(x), y), y /= y), x /= x) end function real(8) function fmin88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(4) function fmin44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(8) function fmin84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, min(x, dble(y)), y /= y), x /= x) end function real(8) function fmin48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), min(dble(x), y), y /= y), x /= x) end function end module real(8) function code(x, y, z) use fmin_fmax_functions real(8), intent (in) :: x real(8), intent (in) :: y real(8), intent (in) :: z code = sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0d0)) end function
public static double code(double x, double y, double z) { return Math.sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0)); }
def code(x, y, z): return math.sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0))
function code(x, y, z) return sqrt(Float64(Float64(Float64(Float64(x * x) + Float64(y * y)) + Float64(z * z)) / 3.0)) end
function tmp = code(x, y, z) tmp = sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0)); end
code[x_, y_, z_] := N[Sqrt[N[(N[(N[(N[(x * x), $MachinePrecision] + N[(y * y), $MachinePrecision]), $MachinePrecision] + N[(z * z), $MachinePrecision]), $MachinePrecision] / 3.0), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \sqrt{\frac{\left(x \cdot x + y \cdot y\right) + z \cdot z}{3}} \end{array}
Sampling outcomes in binary64 precision:
Herbie found 2 alternatives:
Alternative | Accuracy | Speedup |
---|
(FPCore (x y z) :precision binary64 (sqrt (/ (+ (+ (* x x) (* y y)) (* z z)) 3.0)))
double code(double x, double y, double z) { return sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0)); }
module fmin_fmax_functions implicit none private public fmax public fmin interface fmax module procedure fmax88 module procedure fmax44 module procedure fmax84 module procedure fmax48 end interface interface fmin module procedure fmin88 module procedure fmin44 module procedure fmin84 module procedure fmin48 end interface contains real(8) function fmax88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(4) function fmax44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(8) function fmax84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, max(x, dble(y)), y /= y), x /= x) end function real(8) function fmax48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), max(dble(x), y), y /= y), x /= x) end function real(8) function fmin88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(4) function fmin44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(8) function fmin84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, min(x, dble(y)), y /= y), x /= x) end function real(8) function fmin48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), min(dble(x), y), y /= y), x /= x) end function end module real(8) function code(x, y, z) use fmin_fmax_functions real(8), intent (in) :: x real(8), intent (in) :: y real(8), intent (in) :: z code = sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0d0)) end function
public static double code(double x, double y, double z) { return Math.sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0)); }
def code(x, y, z): return math.sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0))
function code(x, y, z) return sqrt(Float64(Float64(Float64(Float64(x * x) + Float64(y * y)) + Float64(z * z)) / 3.0)) end
function tmp = code(x, y, z) tmp = sqrt(((((x * x) + (y * y)) + (z * z)) / 3.0)); end
code[x_, y_, z_] := N[Sqrt[N[(N[(N[(N[(x * x), $MachinePrecision] + N[(y * y), $MachinePrecision]), $MachinePrecision] + N[(z * z), $MachinePrecision]), $MachinePrecision] / 3.0), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \sqrt{\frac{\left(x \cdot x + y \cdot y\right) + z \cdot z}{3}} \end{array}
x_m = (fabs.f64 x) y_m = (fabs.f64 y) z_m = (fabs.f64 z) NOTE: x_m, y_m, and z_m should be sorted in increasing order before calling this function. (FPCore (x_m y_m z_m) :precision binary64 (* (hypot z_m y_m) (sqrt 0.3333333333333333)))
x_m = fabs(x); y_m = fabs(y); z_m = fabs(z); assert(x_m < y_m && y_m < z_m); double code(double x_m, double y_m, double z_m) { return hypot(z_m, y_m) * sqrt(0.3333333333333333); }
x_m = Math.abs(x); y_m = Math.abs(y); z_m = Math.abs(z); assert x_m < y_m && y_m < z_m; public static double code(double x_m, double y_m, double z_m) { return Math.hypot(z_m, y_m) * Math.sqrt(0.3333333333333333); }
x_m = math.fabs(x) y_m = math.fabs(y) z_m = math.fabs(z) [x_m, y_m, z_m] = sort([x_m, y_m, z_m]) def code(x_m, y_m, z_m): return math.hypot(z_m, y_m) * math.sqrt(0.3333333333333333)
x_m = abs(x) y_m = abs(y) z_m = abs(z) x_m, y_m, z_m = sort([x_m, y_m, z_m]) function code(x_m, y_m, z_m) return Float64(hypot(z_m, y_m) * sqrt(0.3333333333333333)) end
x_m = abs(x); y_m = abs(y); z_m = abs(z); x_m, y_m, z_m = num2cell(sort([x_m, y_m, z_m])){:} function tmp = code(x_m, y_m, z_m) tmp = hypot(z_m, y_m) * sqrt(0.3333333333333333); end
x_m = N[Abs[x], $MachinePrecision] y_m = N[Abs[y], $MachinePrecision] z_m = N[Abs[z], $MachinePrecision] NOTE: x_m, y_m, and z_m should be sorted in increasing order before calling this function. code[x$95$m_, y$95$m_, z$95$m_] := N[(N[Sqrt[z$95$m ^ 2 + y$95$m ^ 2], $MachinePrecision] * N[Sqrt[0.3333333333333333], $MachinePrecision]), $MachinePrecision]
\begin{array}{l} x_m = \left|x\right| \\ y_m = \left|y\right| \\ z_m = \left|z\right| \\ [x_m, y_m, z_m] = \mathsf{sort}([x_m, y_m, z_m])\\ \\ \mathsf{hypot}\left(z\_m, y\_m\right) \cdot \sqrt{0.3333333333333333} \end{array}
Initial program 44.2%
Taylor expanded in x around 0
*-commutative
N/A
lower-*.f64
N/A
+-commutative
N/A
pow2
N/A
pow2
N/A
lower-hypot.f64
N/A
lower-sqrt.f64
70.9
Applied rewrites70.9%
x_m = (fabs.f64 x) y_m = (fabs.f64 y) z_m = (fabs.f64 z) NOTE: x_m, y_m, and z_m should be sorted in increasing order before calling this function. (FPCore (x_m y_m z_m) :precision binary64 (* (sqrt 0.3333333333333333) z_m))
x_m = fabs(x); y_m = fabs(y); z_m = fabs(z); assert(x_m < y_m && y_m < z_m); double code(double x_m, double y_m, double z_m) { return sqrt(0.3333333333333333) * z_m; }
x_m = private y_m = private z_m = private NOTE: x_m, y_m, and z_m should be sorted in increasing order before calling this function. module fmin_fmax_functions implicit none private public fmax public fmin interface fmax module procedure fmax88 module procedure fmax44 module procedure fmax84 module procedure fmax48 end interface interface fmin module procedure fmin88 module procedure fmin44 module procedure fmin84 module procedure fmin48 end interface contains real(8) function fmax88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(4) function fmax44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(8) function fmax84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, max(x, dble(y)), y /= y), x /= x) end function real(8) function fmax48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), max(dble(x), y), y /= y), x /= x) end function real(8) function fmin88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(4) function fmin44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(8) function fmin84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, min(x, dble(y)), y /= y), x /= x) end function real(8) function fmin48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), min(dble(x), y), y /= y), x /= x) end function end module real(8) function code(x_m, y_m, z_m) use fmin_fmax_functions real(8), intent (in) :: x_m real(8), intent (in) :: y_m real(8), intent (in) :: z_m code = sqrt(0.3333333333333333d0) * z_m end function
x_m = Math.abs(x); y_m = Math.abs(y); z_m = Math.abs(z); assert x_m < y_m && y_m < z_m; public static double code(double x_m, double y_m, double z_m) { return Math.sqrt(0.3333333333333333) * z_m; }
x_m = math.fabs(x) y_m = math.fabs(y) z_m = math.fabs(z) [x_m, y_m, z_m] = sort([x_m, y_m, z_m]) def code(x_m, y_m, z_m): return math.sqrt(0.3333333333333333) * z_m
x_m = abs(x) y_m = abs(y) z_m = abs(z) x_m, y_m, z_m = sort([x_m, y_m, z_m]) function code(x_m, y_m, z_m) return Float64(sqrt(0.3333333333333333) * z_m) end
x_m = abs(x); y_m = abs(y); z_m = abs(z); x_m, y_m, z_m = num2cell(sort([x_m, y_m, z_m])){:} function tmp = code(x_m, y_m, z_m) tmp = sqrt(0.3333333333333333) * z_m; end
x_m = N[Abs[x], $MachinePrecision] y_m = N[Abs[y], $MachinePrecision] z_m = N[Abs[z], $MachinePrecision] NOTE: x_m, y_m, and z_m should be sorted in increasing order before calling this function. code[x$95$m_, y$95$m_, z$95$m_] := N[(N[Sqrt[0.3333333333333333], $MachinePrecision] * z$95$m), $MachinePrecision]
\begin{array}{l} x_m = \left|x\right| \\ y_m = \left|y\right| \\ z_m = \left|z\right| \\ [x_m, y_m, z_m] = \mathsf{sort}([x_m, y_m, z_m])\\ \\ \sqrt{0.3333333333333333} \cdot z\_m \end{array}
Initial program 44.2%
Taylor expanded in z around inf
*-commutative
N/A
lower-*.f64
N/A
lower-sqrt.f64
20.4
Applied rewrites20.4%
(FPCore (x y z) :precision binary64 (if (< z -6.396479394109776e+136) (/ (- z) (sqrt 3.0)) (if (< z 7.320293694404182e+117) (/ (sqrt (+ (+ (* z z) (* x x)) (* y y))) (sqrt 3.0)) (* (sqrt 0.3333333333333333) z))))
double code(double x, double y, double z) { double tmp; if (z < -6.396479394109776e+136) { tmp = -z / sqrt(3.0); } else if (z < 7.320293694404182e+117) { tmp = sqrt((((z * z) + (x * x)) + (y * y))) / sqrt(3.0); } else { tmp = sqrt(0.3333333333333333) * z; } return tmp; }
module fmin_fmax_functions implicit none private public fmax public fmin interface fmax module procedure fmax88 module procedure fmax44 module procedure fmax84 module procedure fmax48 end interface interface fmin module procedure fmin88 module procedure fmin44 module procedure fmin84 module procedure fmin48 end interface contains real(8) function fmax88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(4) function fmax44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, max(x, y), y /= y), x /= x) end function real(8) function fmax84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, max(x, dble(y)), y /= y), x /= x) end function real(8) function fmax48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), max(dble(x), y), y /= y), x /= x) end function real(8) function fmin88(x, y) result (res) real(8), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(4) function fmin44(x, y) result (res) real(4), intent (in) :: x real(4), intent (in) :: y res = merge(y, merge(x, min(x, y), y /= y), x /= x) end function real(8) function fmin84(x, y) result(res) real(8), intent (in) :: x real(4), intent (in) :: y res = merge(dble(y), merge(x, min(x, dble(y)), y /= y), x /= x) end function real(8) function fmin48(x, y) result(res) real(4), intent (in) :: x real(8), intent (in) :: y res = merge(y, merge(dble(x), min(dble(x), y), y /= y), x /= x) end function end module real(8) function code(x, y, z) use fmin_fmax_functions real(8), intent (in) :: x real(8), intent (in) :: y real(8), intent (in) :: z real(8) :: tmp if (z < (-6.396479394109776d+136)) then tmp = -z / sqrt(3.0d0) else if (z < 7.320293694404182d+117) then tmp = sqrt((((z * z) + (x * x)) + (y * y))) / sqrt(3.0d0) else tmp = sqrt(0.3333333333333333d0) * z end if code = tmp end function
public static double code(double x, double y, double z) { double tmp; if (z < -6.396479394109776e+136) { tmp = -z / Math.sqrt(3.0); } else if (z < 7.320293694404182e+117) { tmp = Math.sqrt((((z * z) + (x * x)) + (y * y))) / Math.sqrt(3.0); } else { tmp = Math.sqrt(0.3333333333333333) * z; } return tmp; }
def code(x, y, z): tmp = 0 if z < -6.396479394109776e+136: tmp = -z / math.sqrt(3.0) elif z < 7.320293694404182e+117: tmp = math.sqrt((((z * z) + (x * x)) + (y * y))) / math.sqrt(3.0) else: tmp = math.sqrt(0.3333333333333333) * z return tmp
function code(x, y, z) tmp = 0.0 if (z < -6.396479394109776e+136) tmp = Float64(Float64(-z) / sqrt(3.0)); elseif (z < 7.320293694404182e+117) tmp = Float64(sqrt(Float64(Float64(Float64(z * z) + Float64(x * x)) + Float64(y * y))) / sqrt(3.0)); else tmp = Float64(sqrt(0.3333333333333333) * z); end return tmp end
function tmp_2 = code(x, y, z) tmp = 0.0; if (z < -6.396479394109776e+136) tmp = -z / sqrt(3.0); elseif (z < 7.320293694404182e+117) tmp = sqrt((((z * z) + (x * x)) + (y * y))) / sqrt(3.0); else tmp = sqrt(0.3333333333333333) * z; end tmp_2 = tmp; end
code[x_, y_, z_] := If[Less[z, -6.396479394109776e+136], N[((-z) / N[Sqrt[3.0], $MachinePrecision]), $MachinePrecision], If[Less[z, 7.320293694404182e+117], N[(N[Sqrt[N[(N[(N[(z * z), $MachinePrecision] + N[(x * x), $MachinePrecision]), $MachinePrecision] + N[(y * y), $MachinePrecision]), $MachinePrecision]], $MachinePrecision] / N[Sqrt[3.0], $MachinePrecision]), $MachinePrecision], N[(N[Sqrt[0.3333333333333333], $MachinePrecision] * z), $MachinePrecision]]]
\begin{array}{l} \\ \begin{array}{l} \mathbf{if}\;z < -6.396479394109776 \cdot 10^{+136}:\\ \;\;\;\;\frac{-z}{\sqrt{3}}\\ \mathbf{elif}\;z < 7.320293694404182 \cdot 10^{+117}:\\ \;\;\;\;\frac{\sqrt{\left(z \cdot z + x \cdot x\right) + y \cdot y}}{\sqrt{3}}\\ \mathbf{else}:\\ \;\;\;\;\sqrt{0.3333333333333333} \cdot z\\ \end{array} \end{array}
herbie shell --seed 2025061
(FPCore (x y z)
:name "Data.Array.Repa.Algorithms.Pixel:doubleRmsOfRGB8 from repa-algorithms-3.4.0.1"
:precision binary64
:alt
(! :herbie-platform default (if (< z -63964793941097760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) (/ (- z) (sqrt 3)) (if (< z 7320293694404182000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) (/ (sqrt (+ (+ (* z z) (* x x)) (* y y))) (sqrt 3)) (* (sqrt 3333333333333333/10000000000000000) z))))
(sqrt (/ (+ (+ (* x x) (* y y)) (* z z)) 3.0)))