-2*sqrt(m12)*sqrt(m32) - m32 + s15+ s35

Percentage Accurate: 100.0% → 100.0%
Time: 4.9s
Alternatives: 4
Speedup: 1.5×

Specification

?
\[\left(\left(\left(2.6111896789072276 \cdot 10^{-7} \leq m12 \land m12 \leq 2.6111896789072276 \cdot 10^{-7}\right) \land \left(0.01947989372100387 \leq m32 \land m32 \leq 0.01947989372100387\right)\right) \land \left(12.9767 \leq s15 \land s15 \leq 12.9767\right)\right) \land \left(-0.14672413413675064 \leq s35 \land s35 \leq -0.14672413413675064\right)\]
\[\begin{array}{l} \\ \left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35 \end{array} \]
(FPCore (m12 m32 s15 s35)
 :precision binary64
 (+ (+ (- (* (* (- 2.0) (sqrt m12)) (sqrt m32)) m32) s15) s35))
double code(double m12, double m32, double s15, double s35) {
	return ((((-2.0 * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35;
}
real(8) function code(m12, m32, s15, s35)
    real(8), intent (in) :: m12
    real(8), intent (in) :: m32
    real(8), intent (in) :: s15
    real(8), intent (in) :: s35
    code = ((((-2.0d0 * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35
end function
public static double code(double m12, double m32, double s15, double s35) {
	return ((((-2.0 * Math.sqrt(m12)) * Math.sqrt(m32)) - m32) + s15) + s35;
}
def code(m12, m32, s15, s35):
	return ((((-2.0 * math.sqrt(m12)) * math.sqrt(m32)) - m32) + s15) + s35
function code(m12, m32, s15, s35)
	return Float64(Float64(Float64(Float64(Float64(Float64(-2.0) * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35)
end
function tmp = code(m12, m32, s15, s35)
	tmp = ((((-2.0 * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35;
end
code[m12_, m32_, s15_, s35_] := N[(N[(N[(N[(N[((-2.0) * N[Sqrt[m12], $MachinePrecision]), $MachinePrecision] * N[Sqrt[m32], $MachinePrecision]), $MachinePrecision] - m32), $MachinePrecision] + s15), $MachinePrecision] + s35), $MachinePrecision]
\begin{array}{l}

\\
\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35
\end{array}

Sampling outcomes in binary64 precision:

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 4 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?

\[\begin{array}{l} \\ \left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35 \end{array} \]
(FPCore (m12 m32 s15 s35)
 :precision binary64
 (+ (+ (- (* (* (- 2.0) (sqrt m12)) (sqrt m32)) m32) s15) s35))
double code(double m12, double m32, double s15, double s35) {
	return ((((-2.0 * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35;
}
real(8) function code(m12, m32, s15, s35)
    real(8), intent (in) :: m12
    real(8), intent (in) :: m32
    real(8), intent (in) :: s15
    real(8), intent (in) :: s35
    code = ((((-2.0d0 * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35
end function
public static double code(double m12, double m32, double s15, double s35) {
	return ((((-2.0 * Math.sqrt(m12)) * Math.sqrt(m32)) - m32) + s15) + s35;
}
def code(m12, m32, s15, s35):
	return ((((-2.0 * math.sqrt(m12)) * math.sqrt(m32)) - m32) + s15) + s35
function code(m12, m32, s15, s35)
	return Float64(Float64(Float64(Float64(Float64(Float64(-2.0) * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35)
end
function tmp = code(m12, m32, s15, s35)
	tmp = ((((-2.0 * sqrt(m12)) * sqrt(m32)) - m32) + s15) + s35;
end
code[m12_, m32_, s15_, s35_] := N[(N[(N[(N[(N[((-2.0) * N[Sqrt[m12], $MachinePrecision]), $MachinePrecision] * N[Sqrt[m32], $MachinePrecision]), $MachinePrecision] - m32), $MachinePrecision] + s15), $MachinePrecision] + s35), $MachinePrecision]
\begin{array}{l}

\\
\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35
\end{array}

Alternative 1: 100.0% accurate, 1.5× speedup?

\[\begin{array}{l} \\ \mathsf{fma}\left(\sqrt{m32 \cdot m12}, -2, s35\right) - \left(m32 - s15\right) \end{array} \]
(FPCore (m12 m32 s15 s35)
 :precision binary64
 (- (fma (sqrt (* m32 m12)) -2.0 s35) (- m32 s15)))
double code(double m12, double m32, double s15, double s35) {
	return fma(sqrt((m32 * m12)), -2.0, s35) - (m32 - s15);
}
function code(m12, m32, s15, s35)
	return Float64(fma(sqrt(Float64(m32 * m12)), -2.0, s35) - Float64(m32 - s15))
end
code[m12_, m32_, s15_, s35_] := N[(N[(N[Sqrt[N[(m32 * m12), $MachinePrecision]], $MachinePrecision] * -2.0 + s35), $MachinePrecision] - N[(m32 - s15), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}

\\
\mathsf{fma}\left(\sqrt{m32 \cdot m12}, -2, s35\right) - \left(m32 - s15\right)
\end{array}
Derivation
  1. Initial program 100.0%

    \[\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35 \]
  2. Add Preprocessing
  3. Step-by-step derivation
    1. lift-+.f64N/A

      \[\leadsto \color{blue}{\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35} \]
    2. +-commutativeN/A

      \[\leadsto \color{blue}{s35 + \left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right)} \]
    3. lift-+.f64N/A

      \[\leadsto s35 + \color{blue}{\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right)} \]
    4. lift--.f64N/A

      \[\leadsto s35 + \left(\color{blue}{\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right)} + s15\right) \]
    5. associate-+l-N/A

      \[\leadsto s35 + \color{blue}{\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - \left(m32 - s15\right)\right)} \]
    6. associate-+r-N/A

      \[\leadsto \color{blue}{\left(s35 + \left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32}\right) - \left(m32 - s15\right)} \]
    7. lower--.f64N/A

      \[\leadsto \color{blue}{\left(s35 + \left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32}\right) - \left(m32 - s15\right)} \]
  4. Applied rewrites100.0%

    \[\leadsto \color{blue}{\mathsf{fma}\left(\sqrt{m32 \cdot m12}, -2, s35\right) - \left(m32 - s15\right)} \]
  5. Add Preprocessing

Alternative 2: 32.3% accurate, 1.7× speedup?

\[\begin{array}{l} \\ \mathsf{fma}\left(\sqrt{m32 \cdot m12}, -2, s15\right) + s35 \end{array} \]
(FPCore (m12 m32 s15 s35)
 :precision binary64
 (+ (fma (sqrt (* m32 m12)) -2.0 s15) s35))
double code(double m12, double m32, double s15, double s35) {
	return fma(sqrt((m32 * m12)), -2.0, s15) + s35;
}
function code(m12, m32, s15, s35)
	return Float64(fma(sqrt(Float64(m32 * m12)), -2.0, s15) + s35)
end
code[m12_, m32_, s15_, s35_] := N[(N[(N[Sqrt[N[(m32 * m12), $MachinePrecision]], $MachinePrecision] * -2.0 + s15), $MachinePrecision] + s35), $MachinePrecision]
\begin{array}{l}

\\
\mathsf{fma}\left(\sqrt{m32 \cdot m12}, -2, s15\right) + s35
\end{array}
Derivation
  1. Initial program 100.0%

    \[\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35 \]
  2. Add Preprocessing
  3. Taylor expanded in m32 around 0

    \[\leadsto \color{blue}{\left(s15 + -2 \cdot \sqrt{m12 \cdot m32}\right)} + s35 \]
  4. Step-by-step derivation
    1. +-commutativeN/A

      \[\leadsto \color{blue}{\left(-2 \cdot \sqrt{m12 \cdot m32} + s15\right)} + s35 \]
    2. *-commutativeN/A

      \[\leadsto \left(\color{blue}{\sqrt{m12 \cdot m32} \cdot -2} + s15\right) + s35 \]
    3. lower-fma.f64N/A

      \[\leadsto \color{blue}{\mathsf{fma}\left(\sqrt{m12 \cdot m32}, -2, s15\right)} + s35 \]
    4. lower-sqrt.f64N/A

      \[\leadsto \mathsf{fma}\left(\color{blue}{\sqrt{m12 \cdot m32}}, -2, s15\right) + s35 \]
    5. *-commutativeN/A

      \[\leadsto \mathsf{fma}\left(\sqrt{\color{blue}{m32 \cdot m12}}, -2, s15\right) + s35 \]
    6. lower-*.f6432.3

      \[\leadsto \mathsf{fma}\left(\sqrt{\color{blue}{m32 \cdot m12}}, -2, s15\right) + s35 \]
  5. Applied rewrites32.3%

    \[\leadsto \color{blue}{\mathsf{fma}\left(\sqrt{m32 \cdot m12}, -2, s15\right)} + s35 \]
  6. Add Preprocessing

Alternative 3: 1.6% accurate, 1.8× speedup?

\[\begin{array}{l} \\ \sqrt{m32 \cdot m12} \cdot -2 + s35 \end{array} \]
(FPCore (m12 m32 s15 s35)
 :precision binary64
 (+ (* (sqrt (* m32 m12)) -2.0) s35))
double code(double m12, double m32, double s15, double s35) {
	return (sqrt((m32 * m12)) * -2.0) + s35;
}
real(8) function code(m12, m32, s15, s35)
    real(8), intent (in) :: m12
    real(8), intent (in) :: m32
    real(8), intent (in) :: s15
    real(8), intent (in) :: s35
    code = (sqrt((m32 * m12)) * (-2.0d0)) + s35
end function
public static double code(double m12, double m32, double s15, double s35) {
	return (Math.sqrt((m32 * m12)) * -2.0) + s35;
}
def code(m12, m32, s15, s35):
	return (math.sqrt((m32 * m12)) * -2.0) + s35
function code(m12, m32, s15, s35)
	return Float64(Float64(sqrt(Float64(m32 * m12)) * -2.0) + s35)
end
function tmp = code(m12, m32, s15, s35)
	tmp = (sqrt((m32 * m12)) * -2.0) + s35;
end
code[m12_, m32_, s15_, s35_] := N[(N[(N[Sqrt[N[(m32 * m12), $MachinePrecision]], $MachinePrecision] * -2.0), $MachinePrecision] + s35), $MachinePrecision]
\begin{array}{l}

\\
\sqrt{m32 \cdot m12} \cdot -2 + s35
\end{array}
Derivation
  1. Initial program 100.0%

    \[\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35 \]
  2. Add Preprocessing
  3. Taylor expanded in m12 around -inf

    \[\leadsto \color{blue}{2 \cdot \left(\sqrt{m12 \cdot m32} \cdot {\left(\sqrt{-1}\right)}^{2}\right)} + s35 \]
  4. Step-by-step derivation
    1. associate-*r*N/A

      \[\leadsto \color{blue}{\left(2 \cdot \sqrt{m12 \cdot m32}\right) \cdot {\left(\sqrt{-1}\right)}^{2}} + s35 \]
    2. unpow2N/A

      \[\leadsto \left(2 \cdot \sqrt{m12 \cdot m32}\right) \cdot \color{blue}{\left(\sqrt{-1} \cdot \sqrt{-1}\right)} + s35 \]
    3. rem-square-sqrtN/A

      \[\leadsto \left(2 \cdot \sqrt{m12 \cdot m32}\right) \cdot \color{blue}{-1} + s35 \]
    4. *-commutativeN/A

      \[\leadsto \color{blue}{\left(\sqrt{m12 \cdot m32} \cdot 2\right)} \cdot -1 + s35 \]
    5. associate-*l*N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32} \cdot \left(2 \cdot -1\right)} + s35 \]
    6. metadata-evalN/A

      \[\leadsto \sqrt{m12 \cdot m32} \cdot \color{blue}{-2} + s35 \]
    7. lower-*.f64N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32} \cdot -2} + s35 \]
    8. lower-sqrt.f64N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32}} \cdot -2 + s35 \]
    9. *-commutativeN/A

      \[\leadsto \sqrt{\color{blue}{m32 \cdot m12}} \cdot -2 + s35 \]
    10. lower-*.f641.6

      \[\leadsto \sqrt{\color{blue}{m32 \cdot m12}} \cdot -2 + s35 \]
  5. Applied rewrites1.6%

    \[\leadsto \color{blue}{\sqrt{m32 \cdot m12} \cdot -2} + s35 \]
  6. Add Preprocessing

Alternative 4: 1.6% accurate, 2.0× speedup?

\[\begin{array}{l} \\ \sqrt{m32 \cdot m12} \cdot -2 \end{array} \]
(FPCore (m12 m32 s15 s35) :precision binary64 (* (sqrt (* m32 m12)) -2.0))
double code(double m12, double m32, double s15, double s35) {
	return sqrt((m32 * m12)) * -2.0;
}
real(8) function code(m12, m32, s15, s35)
    real(8), intent (in) :: m12
    real(8), intent (in) :: m32
    real(8), intent (in) :: s15
    real(8), intent (in) :: s35
    code = sqrt((m32 * m12)) * (-2.0d0)
end function
public static double code(double m12, double m32, double s15, double s35) {
	return Math.sqrt((m32 * m12)) * -2.0;
}
def code(m12, m32, s15, s35):
	return math.sqrt((m32 * m12)) * -2.0
function code(m12, m32, s15, s35)
	return Float64(sqrt(Float64(m32 * m12)) * -2.0)
end
function tmp = code(m12, m32, s15, s35)
	tmp = sqrt((m32 * m12)) * -2.0;
end
code[m12_, m32_, s15_, s35_] := N[(N[Sqrt[N[(m32 * m12), $MachinePrecision]], $MachinePrecision] * -2.0), $MachinePrecision]
\begin{array}{l}

\\
\sqrt{m32 \cdot m12} \cdot -2
\end{array}
Derivation
  1. Initial program 100.0%

    \[\left(\left(\left(\left(-2\right) \cdot \sqrt{m12}\right) \cdot \sqrt{m32} - m32\right) + s15\right) + s35 \]
  2. Add Preprocessing
  3. Taylor expanded in m12 around -inf

    \[\leadsto \color{blue}{2 \cdot \left(\sqrt{m12 \cdot m32} \cdot {\left(\sqrt{-1}\right)}^{2}\right)} + s35 \]
  4. Step-by-step derivation
    1. associate-*r*N/A

      \[\leadsto \color{blue}{\left(2 \cdot \sqrt{m12 \cdot m32}\right) \cdot {\left(\sqrt{-1}\right)}^{2}} + s35 \]
    2. unpow2N/A

      \[\leadsto \left(2 \cdot \sqrt{m12 \cdot m32}\right) \cdot \color{blue}{\left(\sqrt{-1} \cdot \sqrt{-1}\right)} + s35 \]
    3. rem-square-sqrtN/A

      \[\leadsto \left(2 \cdot \sqrt{m12 \cdot m32}\right) \cdot \color{blue}{-1} + s35 \]
    4. *-commutativeN/A

      \[\leadsto \color{blue}{\left(\sqrt{m12 \cdot m32} \cdot 2\right)} \cdot -1 + s35 \]
    5. associate-*l*N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32} \cdot \left(2 \cdot -1\right)} + s35 \]
    6. metadata-evalN/A

      \[\leadsto \sqrt{m12 \cdot m32} \cdot \color{blue}{-2} + s35 \]
    7. lower-*.f64N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32} \cdot -2} + s35 \]
    8. lower-sqrt.f64N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32}} \cdot -2 + s35 \]
    9. *-commutativeN/A

      \[\leadsto \sqrt{\color{blue}{m32 \cdot m12}} \cdot -2 + s35 \]
    10. lower-*.f641.6

      \[\leadsto \sqrt{\color{blue}{m32 \cdot m12}} \cdot -2 + s35 \]
  5. Applied rewrites1.6%

    \[\leadsto \color{blue}{\sqrt{m32 \cdot m12} \cdot -2} + s35 \]
  6. Taylor expanded in m12 around -inf

    \[\leadsto \color{blue}{2 \cdot \left(\sqrt{m12 \cdot m32} \cdot {\left(\sqrt{-1}\right)}^{2}\right)} \]
  7. Step-by-step derivation
    1. *-commutativeN/A

      \[\leadsto 2 \cdot \color{blue}{\left({\left(\sqrt{-1}\right)}^{2} \cdot \sqrt{m12 \cdot m32}\right)} \]
    2. unpow2N/A

      \[\leadsto 2 \cdot \left(\color{blue}{\left(\sqrt{-1} \cdot \sqrt{-1}\right)} \cdot \sqrt{m12 \cdot m32}\right) \]
    3. rem-square-sqrtN/A

      \[\leadsto 2 \cdot \left(\color{blue}{-1} \cdot \sqrt{m12 \cdot m32}\right) \]
    4. associate-*r*N/A

      \[\leadsto \color{blue}{\left(2 \cdot -1\right) \cdot \sqrt{m12 \cdot m32}} \]
    5. metadata-evalN/A

      \[\leadsto \color{blue}{-2} \cdot \sqrt{m12 \cdot m32} \]
    6. *-commutativeN/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32} \cdot -2} \]
    7. lower-*.f64N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32} \cdot -2} \]
    8. lower-sqrt.f64N/A

      \[\leadsto \color{blue}{\sqrt{m12 \cdot m32}} \cdot -2 \]
    9. *-commutativeN/A

      \[\leadsto \sqrt{\color{blue}{m32 \cdot m12}} \cdot -2 \]
    10. lower-*.f641.6

      \[\leadsto \sqrt{\color{blue}{m32 \cdot m12}} \cdot -2 \]
  8. Applied rewrites1.6%

    \[\leadsto \color{blue}{\sqrt{m32 \cdot m12} \cdot -2} \]
  9. Add Preprocessing

Reproduce

?
herbie shell --seed 1 
(FPCore (m12 m32 s15 s35)
  :name "-2*sqrt(m12)*sqrt(m32) - m32 + s15+ s35"
  :precision binary64
  :pre (and (and (and (and (<= 2.6111896789072276e-7 m12) (<= m12 2.6111896789072276e-7)) (and (<= 0.01947989372100387 m32) (<= m32 0.01947989372100387))) (and (<= 12.9767 s15) (<= s15 12.9767))) (and (<= -0.14672413413675064 s35) (<= s35 -0.14672413413675064)))
  (+ (+ (- (* (* (- 2.0) (sqrt m12)) (sqrt m32)) m32) s15) s35))