
(FPCore (p x) :precision binary64 (sqrt (* 0.5 (+ 1.0 (/ x (sqrt (+ (* (* 4.0 p) p) (* x x))))))))
double code(double p, double x) {
return sqrt((0.5 * (1.0 + (x / sqrt((((4.0 * p) * p) + (x * x)))))));
}
real(8) function code(p, x)
real(8), intent (in) :: p
real(8), intent (in) :: x
code = sqrt((0.5d0 * (1.0d0 + (x / sqrt((((4.0d0 * p) * p) + (x * x)))))))
end function
public static double code(double p, double x) {
return Math.sqrt((0.5 * (1.0 + (x / Math.sqrt((((4.0 * p) * p) + (x * x)))))));
}
def code(p, x): return math.sqrt((0.5 * (1.0 + (x / math.sqrt((((4.0 * p) * p) + (x * x)))))))
function code(p, x) return sqrt(Float64(0.5 * Float64(1.0 + Float64(x / sqrt(Float64(Float64(Float64(4.0 * p) * p) + Float64(x * x))))))) end
function tmp = code(p, x) tmp = sqrt((0.5 * (1.0 + (x / sqrt((((4.0 * p) * p) + (x * x))))))); end
code[p_, x_] := N[Sqrt[N[(0.5 * N[(1.0 + N[(x / N[Sqrt[N[(N[(N[(4.0 * p), $MachinePrecision] * p), $MachinePrecision] + N[(x * x), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\sqrt{0.5 \cdot \left(1 + \frac{x}{\sqrt{\left(4 \cdot p\right) \cdot p + x \cdot x}}\right)}
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 4 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (p x) :precision binary64 (sqrt (* 0.5 (+ 1.0 (/ x (sqrt (+ (* (* 4.0 p) p) (* x x))))))))
double code(double p, double x) {
return sqrt((0.5 * (1.0 + (x / sqrt((((4.0 * p) * p) + (x * x)))))));
}
real(8) function code(p, x)
real(8), intent (in) :: p
real(8), intent (in) :: x
code = sqrt((0.5d0 * (1.0d0 + (x / sqrt((((4.0d0 * p) * p) + (x * x)))))))
end function
public static double code(double p, double x) {
return Math.sqrt((0.5 * (1.0 + (x / Math.sqrt((((4.0 * p) * p) + (x * x)))))));
}
def code(p, x): return math.sqrt((0.5 * (1.0 + (x / math.sqrt((((4.0 * p) * p) + (x * x)))))))
function code(p, x) return sqrt(Float64(0.5 * Float64(1.0 + Float64(x / sqrt(Float64(Float64(Float64(4.0 * p) * p) + Float64(x * x))))))) end
function tmp = code(p, x) tmp = sqrt((0.5 * (1.0 + (x / sqrt((((4.0 * p) * p) + (x * x))))))); end
code[p_, x_] := N[Sqrt[N[(0.5 * N[(1.0 + N[(x / N[Sqrt[N[(N[(N[(4.0 * p), $MachinePrecision] * p), $MachinePrecision] + N[(x * x), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\sqrt{0.5 \cdot \left(1 + \frac{x}{\sqrt{\left(4 \cdot p\right) \cdot p + x \cdot x}}\right)}
\end{array}
NOTE: p should be positive before calling this function (FPCore (p x) :precision binary64 (if (<= (/ x (sqrt (+ (* p (* 4.0 p)) (* x x)))) -1.0) (/ (- p) x) (sqrt (+ 0.5 (* (/ x (hypot x (* p 2.0))) 0.5)))))
p = abs(p);
double code(double p, double x) {
double tmp;
if ((x / sqrt(((p * (4.0 * p)) + (x * x)))) <= -1.0) {
tmp = -p / x;
} else {
tmp = sqrt((0.5 + ((x / hypot(x, (p * 2.0))) * 0.5)));
}
return tmp;
}
p = Math.abs(p);
public static double code(double p, double x) {
double tmp;
if ((x / Math.sqrt(((p * (4.0 * p)) + (x * x)))) <= -1.0) {
tmp = -p / x;
} else {
tmp = Math.sqrt((0.5 + ((x / Math.hypot(x, (p * 2.0))) * 0.5)));
}
return tmp;
}
p = abs(p) def code(p, x): tmp = 0 if (x / math.sqrt(((p * (4.0 * p)) + (x * x)))) <= -1.0: tmp = -p / x else: tmp = math.sqrt((0.5 + ((x / math.hypot(x, (p * 2.0))) * 0.5))) return tmp
p = abs(p) function code(p, x) tmp = 0.0 if (Float64(x / sqrt(Float64(Float64(p * Float64(4.0 * p)) + Float64(x * x)))) <= -1.0) tmp = Float64(Float64(-p) / x); else tmp = sqrt(Float64(0.5 + Float64(Float64(x / hypot(x, Float64(p * 2.0))) * 0.5))); end return tmp end
p = abs(p) function tmp_2 = code(p, x) tmp = 0.0; if ((x / sqrt(((p * (4.0 * p)) + (x * x)))) <= -1.0) tmp = -p / x; else tmp = sqrt((0.5 + ((x / hypot(x, (p * 2.0))) * 0.5))); end tmp_2 = tmp; end
NOTE: p should be positive before calling this function code[p_, x_] := If[LessEqual[N[(x / N[Sqrt[N[(N[(p * N[(4.0 * p), $MachinePrecision]), $MachinePrecision] + N[(x * x), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision], -1.0], N[((-p) / x), $MachinePrecision], N[Sqrt[N[(0.5 + N[(N[(x / N[Sqrt[x ^ 2 + N[(p * 2.0), $MachinePrecision] ^ 2], $MachinePrecision]), $MachinePrecision] * 0.5), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]]
\begin{array}{l}
p = |p|\\
\\
\begin{array}{l}
\mathbf{if}\;\frac{x}{\sqrt{p \cdot \left(4 \cdot p\right) + x \cdot x}} \leq -1:\\
\;\;\;\;\frac{-p}{x}\\
\mathbf{else}:\\
\;\;\;\;\sqrt{0.5 + \frac{x}{\mathsf{hypot}\left(x, p \cdot 2\right)} \cdot 0.5}\\
\end{array}
\end{array}
if (/.f64 x (sqrt.f64 (+.f64 (*.f64 (*.f64 4 p) p) (*.f64 x x)))) < -1Initial program 19.6%
+-commutative19.6%
distribute-rgt-in19.6%
+-commutative19.6%
add-sqr-sqrt19.6%
hypot-def19.6%
associate-*l*19.6%
sqrt-prod19.6%
metadata-eval19.6%
sqrt-unprod9.0%
add-sqr-sqrt19.6%
metadata-eval19.6%
Applied egg-rr19.6%
Taylor expanded in x around -inf 64.0%
associate-*r/64.0%
neg-mul-164.0%
Simplified64.0%
if -1 < (/.f64 x (sqrt.f64 (+.f64 (*.f64 (*.f64 4 p) p) (*.f64 x x)))) Initial program 99.7%
+-commutative99.7%
distribute-rgt-in99.7%
+-commutative99.7%
add-sqr-sqrt99.7%
hypot-def99.7%
associate-*l*99.7%
sqrt-prod99.7%
metadata-eval99.7%
sqrt-unprod50.0%
add-sqr-sqrt99.7%
metadata-eval99.7%
Applied egg-rr99.7%
Final simplification89.1%
NOTE: p should be positive before calling this function
(FPCore (p x)
:precision binary64
(let* ((t_0 (/ (- p) x)))
(if (<= p 6.5e-189)
t_0
(if (<= p 2.3e-126)
1.0
(if (<= p 3.3e-93)
t_0
(if (<= p 3.8e-48)
(sqrt 0.5)
(if (<= p 1.9e-29) t_0 (if (<= p 5.3e-14) 1.0 (sqrt 0.5)))))))))p = abs(p);
double code(double p, double x) {
double t_0 = -p / x;
double tmp;
if (p <= 6.5e-189) {
tmp = t_0;
} else if (p <= 2.3e-126) {
tmp = 1.0;
} else if (p <= 3.3e-93) {
tmp = t_0;
} else if (p <= 3.8e-48) {
tmp = sqrt(0.5);
} else if (p <= 1.9e-29) {
tmp = t_0;
} else if (p <= 5.3e-14) {
tmp = 1.0;
} else {
tmp = sqrt(0.5);
}
return tmp;
}
NOTE: p should be positive before calling this function
real(8) function code(p, x)
real(8), intent (in) :: p
real(8), intent (in) :: x
real(8) :: t_0
real(8) :: tmp
t_0 = -p / x
if (p <= 6.5d-189) then
tmp = t_0
else if (p <= 2.3d-126) then
tmp = 1.0d0
else if (p <= 3.3d-93) then
tmp = t_0
else if (p <= 3.8d-48) then
tmp = sqrt(0.5d0)
else if (p <= 1.9d-29) then
tmp = t_0
else if (p <= 5.3d-14) then
tmp = 1.0d0
else
tmp = sqrt(0.5d0)
end if
code = tmp
end function
p = Math.abs(p);
public static double code(double p, double x) {
double t_0 = -p / x;
double tmp;
if (p <= 6.5e-189) {
tmp = t_0;
} else if (p <= 2.3e-126) {
tmp = 1.0;
} else if (p <= 3.3e-93) {
tmp = t_0;
} else if (p <= 3.8e-48) {
tmp = Math.sqrt(0.5);
} else if (p <= 1.9e-29) {
tmp = t_0;
} else if (p <= 5.3e-14) {
tmp = 1.0;
} else {
tmp = Math.sqrt(0.5);
}
return tmp;
}
p = abs(p) def code(p, x): t_0 = -p / x tmp = 0 if p <= 6.5e-189: tmp = t_0 elif p <= 2.3e-126: tmp = 1.0 elif p <= 3.3e-93: tmp = t_0 elif p <= 3.8e-48: tmp = math.sqrt(0.5) elif p <= 1.9e-29: tmp = t_0 elif p <= 5.3e-14: tmp = 1.0 else: tmp = math.sqrt(0.5) return tmp
p = abs(p) function code(p, x) t_0 = Float64(Float64(-p) / x) tmp = 0.0 if (p <= 6.5e-189) tmp = t_0; elseif (p <= 2.3e-126) tmp = 1.0; elseif (p <= 3.3e-93) tmp = t_0; elseif (p <= 3.8e-48) tmp = sqrt(0.5); elseif (p <= 1.9e-29) tmp = t_0; elseif (p <= 5.3e-14) tmp = 1.0; else tmp = sqrt(0.5); end return tmp end
p = abs(p) function tmp_2 = code(p, x) t_0 = -p / x; tmp = 0.0; if (p <= 6.5e-189) tmp = t_0; elseif (p <= 2.3e-126) tmp = 1.0; elseif (p <= 3.3e-93) tmp = t_0; elseif (p <= 3.8e-48) tmp = sqrt(0.5); elseif (p <= 1.9e-29) tmp = t_0; elseif (p <= 5.3e-14) tmp = 1.0; else tmp = sqrt(0.5); end tmp_2 = tmp; end
NOTE: p should be positive before calling this function
code[p_, x_] := Block[{t$95$0 = N[((-p) / x), $MachinePrecision]}, If[LessEqual[p, 6.5e-189], t$95$0, If[LessEqual[p, 2.3e-126], 1.0, If[LessEqual[p, 3.3e-93], t$95$0, If[LessEqual[p, 3.8e-48], N[Sqrt[0.5], $MachinePrecision], If[LessEqual[p, 1.9e-29], t$95$0, If[LessEqual[p, 5.3e-14], 1.0, N[Sqrt[0.5], $MachinePrecision]]]]]]]]
\begin{array}{l}
p = |p|\\
\\
\begin{array}{l}
t_0 := \frac{-p}{x}\\
\mathbf{if}\;p \leq 6.5 \cdot 10^{-189}:\\
\;\;\;\;t_0\\
\mathbf{elif}\;p \leq 2.3 \cdot 10^{-126}:\\
\;\;\;\;1\\
\mathbf{elif}\;p \leq 3.3 \cdot 10^{-93}:\\
\;\;\;\;t_0\\
\mathbf{elif}\;p \leq 3.8 \cdot 10^{-48}:\\
\;\;\;\;\sqrt{0.5}\\
\mathbf{elif}\;p \leq 1.9 \cdot 10^{-29}:\\
\;\;\;\;t_0\\
\mathbf{elif}\;p \leq 5.3 \cdot 10^{-14}:\\
\;\;\;\;1\\
\mathbf{else}:\\
\;\;\;\;\sqrt{0.5}\\
\end{array}
\end{array}
if p < 6.5000000000000001e-189 or 2.30000000000000011e-126 < p < 3.3000000000000001e-93 or 3.80000000000000002e-48 < p < 1.89999999999999988e-29Initial program 71.1%
+-commutative71.1%
distribute-rgt-in71.1%
+-commutative71.1%
add-sqr-sqrt71.1%
hypot-def71.1%
associate-*l*71.1%
sqrt-prod71.1%
metadata-eval71.1%
sqrt-unprod11.2%
add-sqr-sqrt71.1%
metadata-eval71.1%
Applied egg-rr71.1%
Taylor expanded in x around -inf 23.0%
associate-*r/23.0%
neg-mul-123.0%
Simplified23.0%
if 6.5000000000000001e-189 < p < 2.30000000000000011e-126 or 1.89999999999999988e-29 < p < 5.3000000000000001e-14Initial program 70.4%
distribute-lft-in70.4%
metadata-eval70.4%
flip3-+70.4%
Applied egg-rr70.4%
associate-*l/70.4%
distribute-rgt-out--70.4%
associate-*l/70.4%
associate-*l/70.4%
Simplified70.4%
Taylor expanded in x around inf 70.1%
if 3.3000000000000001e-93 < p < 3.80000000000000002e-48 or 5.3000000000000001e-14 < p Initial program 87.5%
Taylor expanded in x around 0 80.1%
Final simplification43.1%
NOTE: p should be positive before calling this function (FPCore (p x) :precision binary64 (if (<= x -3.4e-149) (/ (- p) x) 1.0))
p = abs(p);
double code(double p, double x) {
double tmp;
if (x <= -3.4e-149) {
tmp = -p / x;
} else {
tmp = 1.0;
}
return tmp;
}
NOTE: p should be positive before calling this function
real(8) function code(p, x)
real(8), intent (in) :: p
real(8), intent (in) :: x
real(8) :: tmp
if (x <= (-3.4d-149)) then
tmp = -p / x
else
tmp = 1.0d0
end if
code = tmp
end function
p = Math.abs(p);
public static double code(double p, double x) {
double tmp;
if (x <= -3.4e-149) {
tmp = -p / x;
} else {
tmp = 1.0;
}
return tmp;
}
p = abs(p) def code(p, x): tmp = 0 if x <= -3.4e-149: tmp = -p / x else: tmp = 1.0 return tmp
p = abs(p) function code(p, x) tmp = 0.0 if (x <= -3.4e-149) tmp = Float64(Float64(-p) / x); else tmp = 1.0; end return tmp end
p = abs(p) function tmp_2 = code(p, x) tmp = 0.0; if (x <= -3.4e-149) tmp = -p / x; else tmp = 1.0; end tmp_2 = tmp; end
NOTE: p should be positive before calling this function code[p_, x_] := If[LessEqual[x, -3.4e-149], N[((-p) / x), $MachinePrecision], 1.0]
\begin{array}{l}
p = |p|\\
\\
\begin{array}{l}
\mathbf{if}\;x \leq -3.4 \cdot 10^{-149}:\\
\;\;\;\;\frac{-p}{x}\\
\mathbf{else}:\\
\;\;\;\;1\\
\end{array}
\end{array}
if x < -3.3999999999999999e-149Initial program 57.6%
+-commutative57.6%
distribute-rgt-in57.6%
+-commutative57.6%
add-sqr-sqrt57.6%
hypot-def57.6%
associate-*l*57.6%
sqrt-prod57.6%
metadata-eval57.6%
sqrt-unprod26.8%
add-sqr-sqrt57.6%
metadata-eval57.6%
Applied egg-rr57.6%
Taylor expanded in x around -inf 35.1%
associate-*r/35.1%
neg-mul-135.1%
Simplified35.1%
if -3.3999999999999999e-149 < x Initial program 100.0%
distribute-lft-in100.0%
metadata-eval100.0%
flip3-+100.0%
Applied egg-rr100.0%
associate-*l/100.0%
distribute-rgt-out--100.0%
associate-*l/100.0%
associate-*l/100.0%
Simplified100.0%
Taylor expanded in x around inf 55.3%
Final simplification43.9%
NOTE: p should be positive before calling this function (FPCore (p x) :precision binary64 1.0)
p = abs(p);
double code(double p, double x) {
return 1.0;
}
NOTE: p should be positive before calling this function
real(8) function code(p, x)
real(8), intent (in) :: p
real(8), intent (in) :: x
code = 1.0d0
end function
p = Math.abs(p);
public static double code(double p, double x) {
return 1.0;
}
p = abs(p) def code(p, x): return 1.0
p = abs(p) function code(p, x) return 1.0 end
p = abs(p) function tmp = code(p, x) tmp = 1.0; end
NOTE: p should be positive before calling this function code[p_, x_] := 1.0
\begin{array}{l}
p = |p|\\
\\
1
\end{array}
Initial program 76.0%
distribute-lft-in76.0%
metadata-eval76.0%
flip3-+76.0%
Applied egg-rr76.0%
associate-*l/76.0%
distribute-rgt-out--76.0%
associate-*l/76.0%
associate-*l/76.0%
Simplified76.0%
Taylor expanded in x around inf 30.9%
Final simplification30.9%
(FPCore (p x) :precision binary64 (sqrt (+ 0.5 (/ (copysign 0.5 x) (hypot 1.0 (/ (* 2.0 p) x))))))
double code(double p, double x) {
return sqrt((0.5 + (copysign(0.5, x) / hypot(1.0, ((2.0 * p) / x)))));
}
public static double code(double p, double x) {
return Math.sqrt((0.5 + (Math.copySign(0.5, x) / Math.hypot(1.0, ((2.0 * p) / x)))));
}
def code(p, x): return math.sqrt((0.5 + (math.copysign(0.5, x) / math.hypot(1.0, ((2.0 * p) / x)))))
function code(p, x) return sqrt(Float64(0.5 + Float64(copysign(0.5, x) / hypot(1.0, Float64(Float64(2.0 * p) / x))))) end
function tmp = code(p, x) tmp = sqrt((0.5 + ((sign(x) * abs(0.5)) / hypot(1.0, ((2.0 * p) / x))))); end
code[p_, x_] := N[Sqrt[N[(0.5 + N[(N[With[{TMP1 = Abs[0.5], TMP2 = Sign[x]}, TMP1 * If[TMP2 == 0, 1, TMP2]], $MachinePrecision] / N[Sqrt[1.0 ^ 2 + N[(N[(2.0 * p), $MachinePrecision] / x), $MachinePrecision] ^ 2], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l}
\\
\sqrt{0.5 + \frac{\mathsf{copysign}\left(0.5, x\right)}{\mathsf{hypot}\left(1, \frac{2 \cdot p}{x}\right)}}
\end{array}
herbie shell --seed 2023274
(FPCore (p x)
:name "Given's Rotation SVD example"
:precision binary64
:pre (and (< 1e-150 (fabs x)) (< (fabs x) 1e+150))
:herbie-target
(sqrt (+ 0.5 (/ (copysign 0.5 x) (hypot 1.0 (/ (* 2.0 p) x)))))
(sqrt (* 0.5 (+ 1.0 (/ x (sqrt (+ (* (* 4.0 p) p) (* x x))))))))