
(FPCore re_sqr (re im) :precision binary64 (- (* re re) (* im im)))
double re_sqr(double re, double im) {
return (re * re) - (im * im);
}
real(8) function re_sqr(re, im)
real(8), intent (in) :: re
real(8), intent (in) :: im
re_sqr = (re * re) - (im * im)
end function
public static double re_sqr(double re, double im) {
return (re * re) - (im * im);
}
def re_sqr(re, im): return (re * re) - (im * im)
function re_sqr(re, im) return Float64(Float64(re * re) - Float64(im * im)) end
function tmp = re_sqr(re, im) tmp = (re * re) - (im * im); end
re$95$sqr[re_, im_] := N[(N[(re * re), $MachinePrecision] - N[(im * im), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
re \cdot re - im \cdot im
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 4 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore re_sqr (re im) :precision binary64 (- (* re re) (* im im)))
double re_sqr(double re, double im) {
return (re * re) - (im * im);
}
real(8) function re_sqr(re, im)
real(8), intent (in) :: re
real(8), intent (in) :: im
re_sqr = (re * re) - (im * im)
end function
public static double re_sqr(double re, double im) {
return (re * re) - (im * im);
}
def re_sqr(re, im): return (re * re) - (im * im)
function re_sqr(re, im) return Float64(Float64(re * re) - Float64(im * im)) end
function tmp = re_sqr(re, im) tmp = (re * re) - (im * im); end
re$95$sqr[re_, im_] := N[(N[(re * re), $MachinePrecision] - N[(im * im), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
re \cdot re - im \cdot im
\end{array}
re_m = (fabs.f64 re) (FPCore re_sqr (re_m im) :precision binary64 (if (<= re_m 5e+211) (fma re_m re_m (* im (- im))) (* (- re_m im) (- re_m im))))
re_m = fabs(re);
double re_sqr(double re_m, double im) {
double tmp;
if (re_m <= 5e+211) {
tmp = fma(re_m, re_m, (im * -im));
} else {
tmp = (re_m - im) * (re_m - im);
}
return tmp;
}
re_m = abs(re) function re_sqr(re_m, im) tmp = 0.0 if (re_m <= 5e+211) tmp = fma(re_m, re_m, Float64(im * Float64(-im))); else tmp = Float64(Float64(re_m - im) * Float64(re_m - im)); end return tmp end
re_m = N[Abs[re], $MachinePrecision] re$95$sqr[re$95$m_, im_] := If[LessEqual[re$95$m, 5e+211], N[(re$95$m * re$95$m + N[(im * (-im)), $MachinePrecision]), $MachinePrecision], N[(N[(re$95$m - im), $MachinePrecision] * N[(re$95$m - im), $MachinePrecision]), $MachinePrecision]]
\begin{array}{l}
re_m = \left|re\right|
\\
\begin{array}{l}
\mathbf{if}\;re_m \leq 5 \cdot 10^{+211}:\\
\;\;\;\;\mathsf{fma}\left(re_m, re_m, im \cdot \left(-im\right)\right)\\
\mathbf{else}:\\
\;\;\;\;\left(re_m - im\right) \cdot \left(re_m - im\right)\\
\end{array}
\end{array}
if re < 4.9999999999999995e211Initial program 95.9%
sqr-neg95.9%
cancel-sign-sub95.9%
fma-def98.3%
Simplified98.3%
if 4.9999999999999995e211 < re Initial program 78.6%
difference-of-squares100.0%
add-sqr-sqrt57.1%
sqrt-prod100.0%
sqr-neg100.0%
sqrt-unprod42.9%
add-sqr-sqrt100.0%
sub-neg100.0%
pow1100.0%
pow1100.0%
pow-prod-up100.0%
metadata-eval100.0%
add-sqr-sqrt100.0%
add-sqr-sqrt57.1%
difference-of-squares57.1%
unpow-prod-down57.1%
Applied egg-rr57.1%
unpow257.1%
unpow257.1%
unswap-sqr57.1%
difference-of-squares57.1%
unpow1/257.1%
unpow1/257.1%
pow-sqr57.1%
metadata-eval57.1%
unpow157.1%
unpow1/257.1%
unpow1/257.1%
pow-sqr57.1%
metadata-eval57.1%
unpow157.1%
difference-of-squares57.1%
unpow1/257.1%
unpow1/257.1%
pow-sqr57.1%
metadata-eval57.1%
unpow157.1%
Simplified100.0%
Final simplification98.4%
re_m = (fabs.f64 re) (FPCore re_sqr (re_m im) :precision binary64 (if (<= (* im im) 2000000.0) (* (- re_m im) (- re_m im)) (* im (- im))))
re_m = fabs(re);
double re_sqr(double re_m, double im) {
double tmp;
if ((im * im) <= 2000000.0) {
tmp = (re_m - im) * (re_m - im);
} else {
tmp = im * -im;
}
return tmp;
}
re_m = abs(re)
real(8) function re_sqr(re_m, im)
real(8), intent (in) :: re_m
real(8), intent (in) :: im
real(8) :: tmp
if ((im * im) <= 2000000.0d0) then
tmp = (re_m - im) * (re_m - im)
else
tmp = im * -im
end if
re_sqr = tmp
end function
re_m = Math.abs(re);
public static double re_sqr(double re_m, double im) {
double tmp;
if ((im * im) <= 2000000.0) {
tmp = (re_m - im) * (re_m - im);
} else {
tmp = im * -im;
}
return tmp;
}
re_m = math.fabs(re) def re_sqr(re_m, im): tmp = 0 if (im * im) <= 2000000.0: tmp = (re_m - im) * (re_m - im) else: tmp = im * -im return tmp
re_m = abs(re) function re_sqr(re_m, im) tmp = 0.0 if (Float64(im * im) <= 2000000.0) tmp = Float64(Float64(re_m - im) * Float64(re_m - im)); else tmp = Float64(im * Float64(-im)); end return tmp end
re_m = abs(re); function tmp_2 = re_sqr(re_m, im) tmp = 0.0; if ((im * im) <= 2000000.0) tmp = (re_m - im) * (re_m - im); else tmp = im * -im; end tmp_2 = tmp; end
re_m = N[Abs[re], $MachinePrecision] re$95$sqr[re$95$m_, im_] := If[LessEqual[N[(im * im), $MachinePrecision], 2000000.0], N[(N[(re$95$m - im), $MachinePrecision] * N[(re$95$m - im), $MachinePrecision]), $MachinePrecision], N[(im * (-im)), $MachinePrecision]]
\begin{array}{l}
re_m = \left|re\right|
\\
\begin{array}{l}
\mathbf{if}\;im \cdot im \leq 2000000:\\
\;\;\;\;\left(re_m - im\right) \cdot \left(re_m - im\right)\\
\mathbf{else}:\\
\;\;\;\;im \cdot \left(-im\right)\\
\end{array}
\end{array}
if (*.f64 im im) < 2e6Initial program 100.0%
difference-of-squares100.0%
add-sqr-sqrt50.7%
sqrt-prod92.1%
sqr-neg92.1%
sqrt-unprod41.3%
add-sqr-sqrt83.1%
sub-neg83.1%
pow183.1%
pow183.1%
pow-prod-up83.1%
metadata-eval83.1%
add-sqr-sqrt45.4%
add-sqr-sqrt21.7%
difference-of-squares21.7%
unpow-prod-down21.7%
Applied egg-rr21.7%
unpow221.7%
unpow221.7%
unswap-sqr21.7%
difference-of-squares21.7%
unpow1/221.7%
unpow1/221.7%
pow-sqr21.8%
metadata-eval21.8%
unpow121.8%
unpow1/221.8%
unpow1/221.8%
pow-sqr21.8%
metadata-eval21.8%
unpow121.8%
difference-of-squares21.8%
unpow1/221.8%
unpow1/221.8%
pow-sqr41.9%
metadata-eval41.9%
unpow141.9%
Simplified83.1%
if 2e6 < (*.f64 im im) Initial program 90.0%
Taylor expanded in re around 0 80.8%
mul-1-neg80.8%
Simplified80.8%
unpow280.8%
Applied egg-rr80.8%
Final simplification82.0%
re_m = (fabs.f64 re) (FPCore re_sqr (re_m im) :precision binary64 (if (<= re_m 1.32e+154) (- (* re_m re_m) (* im im)) (* (- re_m im) (- re_m im))))
re_m = fabs(re);
double re_sqr(double re_m, double im) {
double tmp;
if (re_m <= 1.32e+154) {
tmp = (re_m * re_m) - (im * im);
} else {
tmp = (re_m - im) * (re_m - im);
}
return tmp;
}
re_m = abs(re)
real(8) function re_sqr(re_m, im)
real(8), intent (in) :: re_m
real(8), intent (in) :: im
real(8) :: tmp
if (re_m <= 1.32d+154) then
tmp = (re_m * re_m) - (im * im)
else
tmp = (re_m - im) * (re_m - im)
end if
re_sqr = tmp
end function
re_m = Math.abs(re);
public static double re_sqr(double re_m, double im) {
double tmp;
if (re_m <= 1.32e+154) {
tmp = (re_m * re_m) - (im * im);
} else {
tmp = (re_m - im) * (re_m - im);
}
return tmp;
}
re_m = math.fabs(re) def re_sqr(re_m, im): tmp = 0 if re_m <= 1.32e+154: tmp = (re_m * re_m) - (im * im) else: tmp = (re_m - im) * (re_m - im) return tmp
re_m = abs(re) function re_sqr(re_m, im) tmp = 0.0 if (re_m <= 1.32e+154) tmp = Float64(Float64(re_m * re_m) - Float64(im * im)); else tmp = Float64(Float64(re_m - im) * Float64(re_m - im)); end return tmp end
re_m = abs(re); function tmp_2 = re_sqr(re_m, im) tmp = 0.0; if (re_m <= 1.32e+154) tmp = (re_m * re_m) - (im * im); else tmp = (re_m - im) * (re_m - im); end tmp_2 = tmp; end
re_m = N[Abs[re], $MachinePrecision] re$95$sqr[re$95$m_, im_] := If[LessEqual[re$95$m, 1.32e+154], N[(N[(re$95$m * re$95$m), $MachinePrecision] - N[(im * im), $MachinePrecision]), $MachinePrecision], N[(N[(re$95$m - im), $MachinePrecision] * N[(re$95$m - im), $MachinePrecision]), $MachinePrecision]]
\begin{array}{l}
re_m = \left|re\right|
\\
\begin{array}{l}
\mathbf{if}\;re_m \leq 1.32 \cdot 10^{+154}:\\
\;\;\;\;re_m \cdot re_m - im \cdot im\\
\mathbf{else}:\\
\;\;\;\;\left(re_m - im\right) \cdot \left(re_m - im\right)\\
\end{array}
\end{array}
if re < 1.31999999999999998e154Initial program 97.0%
if 1.31999999999999998e154 < re Initial program 76.0%
difference-of-squares100.0%
add-sqr-sqrt56.0%
sqrt-prod92.0%
sqr-neg92.0%
sqrt-unprod36.0%
add-sqr-sqrt88.0%
sub-neg88.0%
pow188.0%
pow188.0%
pow-prod-up88.0%
metadata-eval88.0%
add-sqr-sqrt88.0%
add-sqr-sqrt52.0%
difference-of-squares52.0%
unpow-prod-down52.0%
Applied egg-rr52.0%
unpow252.0%
unpow252.0%
unswap-sqr52.0%
difference-of-squares52.0%
unpow1/252.0%
unpow1/252.0%
pow-sqr52.0%
metadata-eval52.0%
unpow152.0%
unpow1/252.0%
unpow1/252.0%
pow-sqr52.0%
metadata-eval52.0%
unpow152.0%
difference-of-squares52.0%
unpow1/252.0%
unpow1/252.0%
pow-sqr52.0%
metadata-eval52.0%
unpow152.0%
Simplified88.0%
Final simplification96.1%
re_m = (fabs.f64 re) (FPCore re_sqr (re_m im) :precision binary64 (* im (- im)))
re_m = fabs(re);
double re_sqr(double re_m, double im) {
return im * -im;
}
re_m = abs(re)
real(8) function re_sqr(re_m, im)
real(8), intent (in) :: re_m
real(8), intent (in) :: im
re_sqr = im * -im
end function
re_m = Math.abs(re);
public static double re_sqr(double re_m, double im) {
return im * -im;
}
re_m = math.fabs(re) def re_sqr(re_m, im): return im * -im
re_m = abs(re) function re_sqr(re_m, im) return Float64(im * Float64(-im)) end
re_m = abs(re); function tmp = re_sqr(re_m, im) tmp = im * -im; end
re_m = N[Abs[re], $MachinePrecision] re$95$sqr[re$95$m_, im_] := N[(im * (-im)), $MachinePrecision]
\begin{array}{l}
re_m = \left|re\right|
\\
im \cdot \left(-im\right)
\end{array}
Initial program 94.9%
Taylor expanded in re around 0 53.3%
mul-1-neg53.3%
Simplified53.3%
unpow253.3%
Applied egg-rr53.3%
Final simplification53.3%
herbie shell --seed 2023321
(FPCore re_sqr (re im)
:name "math.square on complex, real part"
:precision binary64
(- (* re re) (* im im)))