Average Error: 13.4 → 6.8
Time: 18.2s
Precision: binary64
Cost: 40768
\[wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}} \]
\[\begin{array}{l} t_0 := \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\\ \left(\mathsf{fma}\left(wj, 1, t_0 \cdot \left(1 - wj\right)\right) + \mathsf{fma}\left(1 - wj, t_0, \left(wj + -1\right) \cdot t_0\right)\right) + \frac{x}{\left(wj + 1\right) \cdot e^{wj}} \end{array} \]
(FPCore (wj x)
 :precision binary64
 (- wj (/ (- (* wj (exp wj)) x) (+ (exp wj) (* wj (exp wj))))))
(FPCore (wj x)
 :precision binary64
 (let* ((t_0 (/ wj (fma wj wj -1.0))))
   (+
    (+
     (fma wj 1.0 (* t_0 (- 1.0 wj)))
     (fma (- 1.0 wj) t_0 (* (+ wj -1.0) t_0)))
    (/ x (* (+ wj 1.0) (exp wj))))))
double code(double wj, double x) {
	return wj - (((wj * exp(wj)) - x) / (exp(wj) + (wj * exp(wj))));
}
double code(double wj, double x) {
	double t_0 = wj / fma(wj, wj, -1.0);
	return (fma(wj, 1.0, (t_0 * (1.0 - wj))) + fma((1.0 - wj), t_0, ((wj + -1.0) * t_0))) + (x / ((wj + 1.0) * exp(wj)));
}
function code(wj, x)
	return Float64(wj - Float64(Float64(Float64(wj * exp(wj)) - x) / Float64(exp(wj) + Float64(wj * exp(wj)))))
end
function code(wj, x)
	t_0 = Float64(wj / fma(wj, wj, -1.0))
	return Float64(Float64(fma(wj, 1.0, Float64(t_0 * Float64(1.0 - wj))) + fma(Float64(1.0 - wj), t_0, Float64(Float64(wj + -1.0) * t_0))) + Float64(x / Float64(Float64(wj + 1.0) * exp(wj))))
end
code[wj_, x_] := N[(wj - N[(N[(N[(wj * N[Exp[wj], $MachinePrecision]), $MachinePrecision] - x), $MachinePrecision] / N[(N[Exp[wj], $MachinePrecision] + N[(wj * N[Exp[wj], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
code[wj_, x_] := Block[{t$95$0 = N[(wj / N[(wj * wj + -1.0), $MachinePrecision]), $MachinePrecision]}, N[(N[(N[(wj * 1.0 + N[(t$95$0 * N[(1.0 - wj), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(N[(1.0 - wj), $MachinePrecision] * t$95$0 + N[(N[(wj + -1.0), $MachinePrecision] * t$95$0), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] + N[(x / N[(N[(wj + 1.0), $MachinePrecision] * N[Exp[wj], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]]
wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}}
\begin{array}{l}
t_0 := \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\\
\left(\mathsf{fma}\left(wj, 1, t_0 \cdot \left(1 - wj\right)\right) + \mathsf{fma}\left(1 - wj, t_0, \left(wj + -1\right) \cdot t_0\right)\right) + \frac{x}{\left(wj + 1\right) \cdot e^{wj}}
\end{array}

Error

Target

Original13.4
Target12.9
Herbie6.8
\[wj - \left(\frac{wj}{wj + 1} - \frac{x}{e^{wj} + wj \cdot e^{wj}}\right) \]

Derivation

  1. Initial program 13.4

    \[wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}} \]
  2. Simplified12.9

    \[\leadsto \color{blue}{wj - \frac{wj - \frac{x}{e^{wj}}}{wj + 1}} \]
    Proof
    (-.f64 wj (/.f64 (-.f64 wj (/.f64 x (exp.f64 wj))) (+.f64 wj 1))): 0 points increase in error, 0 points decrease in error
    (-.f64 wj (Rewrite=> div-sub_binary64 (-.f64 (/.f64 wj (+.f64 wj 1)) (/.f64 (/.f64 x (exp.f64 wj)) (+.f64 wj 1))))): 0 points increase in error, 0 points decrease in error
    (-.f64 wj (-.f64 (Rewrite<= *-rgt-identity_binary64 (*.f64 (/.f64 wj (+.f64 wj 1)) 1)) (/.f64 (/.f64 x (exp.f64 wj)) (+.f64 wj 1)))): 0 points increase in error, 0 points decrease in error
    (-.f64 wj (-.f64 (*.f64 (/.f64 wj (+.f64 wj 1)) (Rewrite<= *-inverses_binary64 (/.f64 (exp.f64 wj) (exp.f64 wj)))) (/.f64 (/.f64 x (exp.f64 wj)) (+.f64 wj 1)))): 3 points increase in error, 0 points decrease in error
    (-.f64 wj (-.f64 (Rewrite<= times-frac_binary64 (/.f64 (*.f64 wj (exp.f64 wj)) (*.f64 (+.f64 wj 1) (exp.f64 wj)))) (/.f64 (/.f64 x (exp.f64 wj)) (+.f64 wj 1)))): 3 points increase in error, 1 points decrease in error
    (-.f64 wj (-.f64 (/.f64 (*.f64 wj (exp.f64 wj)) (Rewrite<= distribute-rgt1-in_binary64 (+.f64 (exp.f64 wj) (*.f64 wj (exp.f64 wj))))) (/.f64 (/.f64 x (exp.f64 wj)) (+.f64 wj 1)))): 1 points increase in error, 2 points decrease in error
    (-.f64 wj (-.f64 (/.f64 (*.f64 wj (exp.f64 wj)) (+.f64 (exp.f64 wj) (*.f64 wj (exp.f64 wj)))) (Rewrite=> associate-/l/_binary64 (/.f64 x (*.f64 (+.f64 wj 1) (exp.f64 wj)))))): 4 points increase in error, 2 points decrease in error
    (-.f64 wj (-.f64 (/.f64 (*.f64 wj (exp.f64 wj)) (+.f64 (exp.f64 wj) (*.f64 wj (exp.f64 wj)))) (/.f64 x (Rewrite<= distribute-rgt1-in_binary64 (+.f64 (exp.f64 wj) (*.f64 wj (exp.f64 wj))))))): 1 points increase in error, 3 points decrease in error
    (-.f64 wj (Rewrite<= div-sub_binary64 (/.f64 (-.f64 (*.f64 wj (exp.f64 wj)) x) (+.f64 (exp.f64 wj) (*.f64 wj (exp.f64 wj)))))): 0 points increase in error, 0 points decrease in error
  3. Applied egg-rr6.8

    \[\leadsto \color{blue}{\left(wj - \frac{wj}{wj + 1}\right) + \frac{x}{\left(wj + 1\right) \cdot e^{wj}}} \]
  4. Applied egg-rr6.8

    \[\leadsto \color{blue}{\left(\mathsf{fma}\left(wj, 1, -\left(wj + -1\right) \cdot \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\right) + \mathsf{fma}\left(-\left(wj + -1\right), \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}, \left(wj + -1\right) \cdot \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\right)\right)} + \frac{x}{\left(wj + 1\right) \cdot e^{wj}} \]
  5. Simplified6.8

    \[\leadsto \color{blue}{\left(\mathsf{fma}\left(wj, 1, \left(wj + -1\right) \cdot \left(-\frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\right)\right) + \mathsf{fma}\left(\left(-wj\right) + 1, \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}, \left(wj + -1\right) \cdot \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\right)\right)} + \frac{x}{\left(wj + 1\right) \cdot e^{wj}} \]
    Proof
    (+.f64 (fma.f64 wj 1 (*.f64 (+.f64 wj -1) (neg.f64 (/.f64 wj (fma.f64 wj wj -1))))) (fma.f64 (+.f64 (neg.f64 wj) 1) (/.f64 wj (fma.f64 wj wj -1)) (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1))))): 0 points increase in error, 0 points decrease in error
    (+.f64 (fma.f64 wj 1 (Rewrite<= distribute-rgt-neg-in_binary64 (neg.f64 (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1)))))) (fma.f64 (+.f64 (neg.f64 wj) 1) (/.f64 wj (fma.f64 wj wj -1)) (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1))))): 0 points increase in error, 0 points decrease in error
    (+.f64 (fma.f64 wj 1 (neg.f64 (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1))))) (fma.f64 (+.f64 (neg.f64 wj) (Rewrite<= metadata-eval (neg.f64 -1))) (/.f64 wj (fma.f64 wj wj -1)) (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1))))): 0 points increase in error, 0 points decrease in error
    (+.f64 (fma.f64 wj 1 (neg.f64 (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1))))) (fma.f64 (Rewrite<= distribute-neg-in_binary64 (neg.f64 (+.f64 wj -1))) (/.f64 wj (fma.f64 wj wj -1)) (*.f64 (+.f64 wj -1) (/.f64 wj (fma.f64 wj wj -1))))): 0 points increase in error, 0 points decrease in error
  6. Final simplification6.8

    \[\leadsto \left(\mathsf{fma}\left(wj, 1, \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)} \cdot \left(1 - wj\right)\right) + \mathsf{fma}\left(1 - wj, \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}, \left(wj + -1\right) \cdot \frac{wj}{\mathsf{fma}\left(wj, wj, -1\right)}\right)\right) + \frac{x}{\left(wj + 1\right) \cdot e^{wj}} \]

Alternatives

Alternative 1
Error6.8
Cost8384
\[\frac{x}{\left(wj + 1\right) \cdot e^{wj}} + \frac{wj \cdot wj - \frac{\frac{wj \cdot wj}{wj + 1}}{wj + 1}}{wj + \frac{wj}{wj + 1}} \]
Alternative 2
Error6.8
Cost7360
\[\frac{x}{\left(wj + 1\right) \cdot e^{wj}} + \left(wj - \frac{wj}{wj + 1}\right) \]
Alternative 3
Error17.3
Cost7104
\[wj - \frac{wj + x \cdot e^{wj}}{wj + -1} \]
Alternative 4
Error12.9
Cost7104
\[wj - \frac{wj - \frac{x}{e^{wj}}}{wj + 1} \]

Error

Reproduce

herbie shell --seed 2022334 
(FPCore (wj x)
  :name "Jmat.Real.lambertw, newton loop step"
  :precision binary64

  :herbie-target
  (- wj (- (/ wj (+ wj 1.0)) (/ x (+ (exp wj) (* wj (exp wj))))))

  (- wj (/ (- (* wj (exp wj)) x) (+ (exp wj) (* wj (exp wj))))))