A quarter-circle in the lower-left quadrant

Percentage Accurate: 100.0% → 100.0%
Time: 1.3s
Alternatives: 2
Speedup: 2.7×

Specification

?
\[\mathsf{max}\left(\left({y}^{2} + {x}^{2}\right) - 0.5, \mathsf{max}\left(x, y\right)\right) \]
(FPCore (x y)
  :precision binary64
  :pre TRUE
  (fmax (- (+ (pow y 2.0) (pow x 2.0)) 0.5) (fmax x y)))
double code(double x, double y) {
	return fmax(((pow(y, 2.0) + pow(x, 2.0)) - 0.5), fmax(x, y));
}
real(8) function code(x, y)
use fmin_fmax_functions
    real(8), intent (in) :: x
    real(8), intent (in) :: y
    code = fmax((((y ** 2.0d0) + (x ** 2.0d0)) - 0.5d0), fmax(x, y))
end function
public static double code(double x, double y) {
	return fmax(((Math.pow(y, 2.0) + Math.pow(x, 2.0)) - 0.5), fmax(x, y));
}
def code(x, y):
	return fmax(((math.pow(y, 2.0) + math.pow(x, 2.0)) - 0.5), fmax(x, y))
function code(x, y)
	return fmax(Float64(Float64((y ^ 2.0) + (x ^ 2.0)) - 0.5), fmax(x, y))
end
function tmp = code(x, y)
	tmp = max((((y ^ 2.0) + (x ^ 2.0)) - 0.5), max(x, y));
end
code[x_, y_] := N[Max[N[(N[(N[Power[y, 2.0], $MachinePrecision] + N[Power[x, 2.0], $MachinePrecision]), $MachinePrecision] - 0.5), $MachinePrecision], N[Max[x, y], $MachinePrecision]], $MachinePrecision]
f(x, y):
	x in [-inf, +inf],
	y in [-inf, +inf]
code: THEORY
BEGIN
f(x, y: real): real =
	LET tmp_1 = IF (x > y) THEN x ELSE y ENDIF IN
	LET tmp_2 = IF (x > y) THEN x ELSE y ENDIF IN
	LET tmp = IF ((((y ^ (2)) + (x ^ (2))) - (5e-1)) > tmp_1) THEN (((y ^ (2)) + (x ^ (2))) - (5e-1)) ELSE tmp_2 ENDIF IN
	tmp
END code
\mathsf{max}\left(\left({y}^{2} + {x}^{2}\right) - 0.5, \mathsf{max}\left(x, y\right)\right)

Local Percentage Accuracy vs ?

The average percentage accuracy by input value. Horizontal axis shows value of an input variable; the variable is choosen in the title. Vertical axis is accuracy; higher is better. Red represent the original program, while blue represents Herbie's suggestion. These can be toggled with buttons below the plot. The line is an average while dots represent individual samples.

Accuracy vs Speed?

Herbie found 2 alternatives:

AlternativeAccuracySpeedup
The accuracy (vertical axis) and speed (horizontal axis) of each alternatives. Up and to the right is better. The red square shows the initial program, and each blue circle shows an alternative.The line shows the best available speed-accuracy tradeoffs.

Initial Program: 100.0% accurate, 1.0× speedup?

\[\mathsf{max}\left(\left({y}^{2} + {x}^{2}\right) - 0.5, \mathsf{max}\left(x, y\right)\right) \]
(FPCore (x y)
  :precision binary64
  :pre TRUE
  (fmax (- (+ (pow y 2.0) (pow x 2.0)) 0.5) (fmax x y)))
double code(double x, double y) {
	return fmax(((pow(y, 2.0) + pow(x, 2.0)) - 0.5), fmax(x, y));
}
real(8) function code(x, y)
use fmin_fmax_functions
    real(8), intent (in) :: x
    real(8), intent (in) :: y
    code = fmax((((y ** 2.0d0) + (x ** 2.0d0)) - 0.5d0), fmax(x, y))
end function
public static double code(double x, double y) {
	return fmax(((Math.pow(y, 2.0) + Math.pow(x, 2.0)) - 0.5), fmax(x, y));
}
def code(x, y):
	return fmax(((math.pow(y, 2.0) + math.pow(x, 2.0)) - 0.5), fmax(x, y))
function code(x, y)
	return fmax(Float64(Float64((y ^ 2.0) + (x ^ 2.0)) - 0.5), fmax(x, y))
end
function tmp = code(x, y)
	tmp = max((((y ^ 2.0) + (x ^ 2.0)) - 0.5), max(x, y));
end
code[x_, y_] := N[Max[N[(N[(N[Power[y, 2.0], $MachinePrecision] + N[Power[x, 2.0], $MachinePrecision]), $MachinePrecision] - 0.5), $MachinePrecision], N[Max[x, y], $MachinePrecision]], $MachinePrecision]
f(x, y):
	x in [-inf, +inf],
	y in [-inf, +inf]
code: THEORY
BEGIN
f(x, y: real): real =
	LET tmp_1 = IF (x > y) THEN x ELSE y ENDIF IN
	LET tmp_2 = IF (x > y) THEN x ELSE y ENDIF IN
	LET tmp = IF ((((y ^ (2)) + (x ^ (2))) - (5e-1)) > tmp_1) THEN (((y ^ (2)) + (x ^ (2))) - (5e-1)) ELSE tmp_2 ENDIF IN
	tmp
END code
\mathsf{max}\left(\left({y}^{2} + {x}^{2}\right) - 0.5, \mathsf{max}\left(x, y\right)\right)

Alternative 1: 100.0% accurate, 2.7× speedup?

\[\mathsf{max}\left(\mathsf{fma}\left(x, x, \mathsf{fma}\left(y, y, -0.5\right)\right), \mathsf{max}\left(x, y\right)\right) \]
(FPCore (x y)
  :precision binary64
  :pre TRUE
  (fmax (fma x x (fma y y -0.5)) (fmax x y)))
double code(double x, double y) {
	return fmax(fma(x, x, fma(y, y, -0.5)), fmax(x, y));
}
function code(x, y)
	return fmax(fma(x, x, fma(y, y, -0.5)), fmax(x, y))
end
code[x_, y_] := N[Max[N[(x * x + N[(y * y + -0.5), $MachinePrecision]), $MachinePrecision], N[Max[x, y], $MachinePrecision]], $MachinePrecision]
f(x, y):
	x in [-inf, +inf],
	y in [-inf, +inf]
code: THEORY
BEGIN
f(x, y: real): real =
	LET tmp_1 = IF (x > y) THEN x ELSE y ENDIF IN
	LET tmp_2 = IF (x > y) THEN x ELSE y ENDIF IN
	LET tmp = IF (((x * x) + ((y * y) + (-5e-1))) > tmp_1) THEN ((x * x) + ((y * y) + (-5e-1))) ELSE tmp_2 ENDIF IN
	tmp
END code
\mathsf{max}\left(\mathsf{fma}\left(x, x, \mathsf{fma}\left(y, y, -0.5\right)\right), \mathsf{max}\left(x, y\right)\right)
Derivation
  1. Initial program 100.0%

    \[\mathsf{max}\left(\left({y}^{2} + {x}^{2}\right) - 0.5, \mathsf{max}\left(x, y\right)\right) \]
  2. Step-by-step derivation
    1. Applied rewrites100.0%

      \[\leadsto \mathsf{max}\left(\mathsf{fma}\left(x, x, \mathsf{fma}\left(y, y, -0.5\right)\right), \mathsf{max}\left(x, y\right)\right) \]
    2. Add Preprocessing

    Alternative 2: 66.7% accurate, 1.9× speedup?

    \[\mathsf{max}\left(\mathsf{fma}\left(\mathsf{min}\left(x, y\right), \mathsf{min}\left(x, y\right), -0.5\right), \mathsf{max}\left(\mathsf{min}\left(x, y\right), \mathsf{max}\left(x, y\right)\right)\right) \]
    (FPCore (x y)
      :precision binary64
      :pre TRUE
      (fmax (fma (fmin x y) (fmin x y) -0.5) (fmax (fmin x y) (fmax x y))))
    double code(double x, double y) {
    	return fmax(fma(fmin(x, y), fmin(x, y), -0.5), fmax(fmin(x, y), fmax(x, y)));
    }
    
    function code(x, y)
    	return fmax(fma(fmin(x, y), fmin(x, y), -0.5), fmax(fmin(x, y), fmax(x, y)))
    end
    
    code[x_, y_] := N[Max[N[(N[Min[x, y], $MachinePrecision] * N[Min[x, y], $MachinePrecision] + -0.5), $MachinePrecision], N[Max[N[Min[x, y], $MachinePrecision], N[Max[x, y], $MachinePrecision]], $MachinePrecision]], $MachinePrecision]
    
    f(x, y):
    	x in [-inf, +inf],
    	y in [-inf, +inf]
    code: THEORY
    BEGIN
    f(x, y: real): real =
    	LET tmp_3 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_4 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_7 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_8 = IF (x > y) THEN x ELSE y ENDIF IN
    	LET tmp_9 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_10 = IF (x > y) THEN x ELSE y ENDIF IN
    	LET tmp_6 = IF (tmp_7 > tmp_8) THEN tmp_9 ELSE tmp_10 ENDIF IN
    	LET tmp_11 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_12 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_15 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_16 = IF (x > y) THEN x ELSE y ENDIF IN
    	LET tmp_17 = IF (x < y) THEN x ELSE y ENDIF IN
    	LET tmp_18 = IF (x > y) THEN x ELSE y ENDIF IN
    	LET tmp_14 = IF (tmp_15 > tmp_16) THEN tmp_17 ELSE tmp_18 ENDIF IN
    	LET tmp_2 = IF (((tmp_3 * tmp_4) + (-5e-1)) > tmp_6) THEN ((tmp_11 * tmp_12) + (-5e-1)) ELSE tmp_14 ENDIF IN
    	tmp_2
    END code
    \mathsf{max}\left(\mathsf{fma}\left(\mathsf{min}\left(x, y\right), \mathsf{min}\left(x, y\right), -0.5\right), \mathsf{max}\left(\mathsf{min}\left(x, y\right), \mathsf{max}\left(x, y\right)\right)\right)
    
    Derivation
    1. Initial program 100.0%

      \[\mathsf{max}\left(\left({y}^{2} + {x}^{2}\right) - 0.5, \mathsf{max}\left(x, y\right)\right) \]
    2. Step-by-step derivation
      1. Applied rewrites100.0%

        \[\leadsto \mathsf{max}\left(\mathsf{fma}\left(x, x, \mathsf{fma}\left(y, y, -0.5\right)\right), \mathsf{max}\left(x, y\right)\right) \]
      2. Taylor expanded in y around 0

        \[\leadsto \mathsf{max}\left(\mathsf{fma}\left(x, x, \frac{-1}{2}\right), \mathsf{max}\left(x, y\right)\right) \]
      3. Step-by-step derivation
        1. Applied rewrites66.7%

          \[\leadsto \mathsf{max}\left(\mathsf{fma}\left(x, x, -0.5\right), \mathsf{max}\left(x, y\right)\right) \]
        2. Add Preprocessing

        Reproduce

        ?
        herbie shell --seed 2026086 
        (FPCore (x y)
          :name "A quarter-circle in the lower-left quadrant"
          :precision binary64
          (fmax (- (+ (pow y 2.0) (pow x 2.0)) 0.5) (fmax x y)))