Average Error: 14.0 → 0.9
Time: 9.4m
Precision: 64
\[wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}}\]
\[\begin{array}{l} \mathbf{if}\;wj \le 2.2715176642429625 \cdot 10^{-09}:\\ \;\;\;\;\mathsf{fma}\left(\left(\mathsf{fma}\left(x, -2, wj\right)\right), wj, x\right)\\ \mathbf{else}:\\ \;\;\;\;wj - \frac{\frac{wj - \frac{x}{e^{wj}}}{\sqrt{wj + 1}}}{\sqrt{wj + 1}}\\ \end{array}\]
wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}}
\begin{array}{l}
\mathbf{if}\;wj \le 2.2715176642429625 \cdot 10^{-09}:\\
\;\;\;\;\mathsf{fma}\left(\left(\mathsf{fma}\left(x, -2, wj\right)\right), wj, x\right)\\

\mathbf{else}:\\
\;\;\;\;wj - \frac{\frac{wj - \frac{x}{e^{wj}}}{\sqrt{wj + 1}}}{\sqrt{wj + 1}}\\

\end{array}
double f(double wj, double x) {
        double r100274271 = wj;
        double r100274272 = exp(r100274271);
        double r100274273 = r100274271 * r100274272;
        double r100274274 = x;
        double r100274275 = r100274273 - r100274274;
        double r100274276 = r100274272 + r100274273;
        double r100274277 = r100274275 / r100274276;
        double r100274278 = r100274271 - r100274277;
        return r100274278;
}

double f(double wj, double x) {
        double r100274279 = wj;
        double r100274280 = 2.2715176642429625e-09;
        bool r100274281 = r100274279 <= r100274280;
        double r100274282 = x;
        double r100274283 = -2.0;
        double r100274284 = fma(r100274282, r100274283, r100274279);
        double r100274285 = fma(r100274284, r100274279, r100274282);
        double r100274286 = exp(r100274279);
        double r100274287 = r100274282 / r100274286;
        double r100274288 = r100274279 - r100274287;
        double r100274289 = 1.0;
        double r100274290 = r100274279 + r100274289;
        double r100274291 = sqrt(r100274290);
        double r100274292 = r100274288 / r100274291;
        double r100274293 = r100274292 / r100274291;
        double r100274294 = r100274279 - r100274293;
        double r100274295 = r100274281 ? r100274285 : r100274294;
        return r100274295;
}

Error

Bits error versus wj

Bits error versus x

Target

Original14.0
Target13.4
Herbie0.9
\[wj - \left(\frac{wj}{wj + 1} - \frac{x}{e^{wj} + wj \cdot e^{wj}}\right)\]

Derivation

  1. Split input into 2 regimes
  2. if wj < 2.2715176642429625e-09

    1. Initial program 13.7

      \[wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}}\]
    2. Taylor expanded around 0 0.8

      \[\leadsto \color{blue}{\left({wj}^{2} + x\right) - 2 \cdot \left(x \cdot wj\right)}\]
    3. Simplified0.8

      \[\leadsto \color{blue}{\mathsf{fma}\left(\left(\mathsf{fma}\left(x, -2, wj\right)\right), wj, x\right)}\]

    if 2.2715176642429625e-09 < wj

    1. Initial program 25.4

      \[wj - \frac{wj \cdot e^{wj} - x}{e^{wj} + wj \cdot e^{wj}}\]
    2. Using strategy rm
    3. Applied *-un-lft-identity25.4

      \[\leadsto wj - \frac{wj \cdot e^{wj} - x}{\color{blue}{1 \cdot e^{wj}} + wj \cdot e^{wj}}\]
    4. Applied distribute-rgt-out25.5

      \[\leadsto wj - \frac{wj \cdot e^{wj} - x}{\color{blue}{e^{wj} \cdot \left(1 + wj\right)}}\]
    5. Applied associate-/r*25.5

      \[\leadsto wj - \color{blue}{\frac{\frac{wj \cdot e^{wj} - x}{e^{wj}}}{1 + wj}}\]
    6. Simplified2.7

      \[\leadsto wj - \frac{\color{blue}{wj - \frac{x}{e^{wj}}}}{1 + wj}\]
    7. Using strategy rm
    8. Applied add-sqr-sqrt3.0

      \[\leadsto wj - \frac{wj - \frac{x}{e^{wj}}}{\color{blue}{\sqrt{1 + wj} \cdot \sqrt{1 + wj}}}\]
    9. Applied associate-/r*2.9

      \[\leadsto wj - \color{blue}{\frac{\frac{wj - \frac{x}{e^{wj}}}{\sqrt{1 + wj}}}{\sqrt{1 + wj}}}\]
  3. Recombined 2 regimes into one program.
  4. Final simplification0.9

    \[\leadsto \begin{array}{l} \mathbf{if}\;wj \le 2.2715176642429625 \cdot 10^{-09}:\\ \;\;\;\;\mathsf{fma}\left(\left(\mathsf{fma}\left(x, -2, wj\right)\right), wj, x\right)\\ \mathbf{else}:\\ \;\;\;\;wj - \frac{\frac{wj - \frac{x}{e^{wj}}}{\sqrt{wj + 1}}}{\sqrt{wj + 1}}\\ \end{array}\]

Reproduce

herbie shell --seed 2019128 +o rules:numerics
(FPCore (wj x)
  :name "Jmat.Real.lambertw, newton loop step"

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

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