HairBSDF, sample_f, cosTheta

Percentage Accurate: 99.5% → 99.5%
Time: 13.9s
Alternatives: 23
Speedup: N/A×

Specification

?
\[\left(10^{-5} \leq u \land u \leq 1\right) \land \left(0 \leq v \land v \leq 109.746574\right)\]
\[\begin{array}{l} \\ 1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \end{array} \]
(FPCore (u v)
 :precision binary32
 (+ 1.0 (* v (log (+ u (* (- 1.0 u) (exp (/ -2.0 v))))))))
float code(float u, float v) {
	return 1.0f + (v * logf((u + ((1.0f - u) * expf((-2.0f / v))))));
}
real(4) function code(u, v)
    real(4), intent (in) :: u
    real(4), intent (in) :: v
    code = 1.0e0 + (v * log((u + ((1.0e0 - u) * exp(((-2.0e0) / v))))))
end function
function code(u, v)
	return Float32(Float32(1.0) + Float32(v * log(Float32(u + Float32(Float32(Float32(1.0) - u) * exp(Float32(Float32(-2.0) / v)))))))
end
function tmp = code(u, v)
	tmp = single(1.0) + (v * log((u + ((single(1.0) - u) * exp((single(-2.0) / v))))));
end
\begin{array}{l}

\\
1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right)
\end{array}

Sampling outcomes in binary32 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 23 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: 99.5% accurate, 1.0× speedup?

\[\begin{array}{l} \\ 1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \end{array} \]
(FPCore (u v)
 :precision binary32
 (+ 1.0 (* v (log (+ u (* (- 1.0 u) (exp (/ -2.0 v))))))))
float code(float u, float v) {
	return 1.0f + (v * logf((u + ((1.0f - u) * expf((-2.0f / v))))));
}
real(4) function code(u, v)
    real(4), intent (in) :: u
    real(4), intent (in) :: v
    code = 1.0e0 + (v * log((u + ((1.0e0 - u) * exp(((-2.0e0) / v))))))
end function
function code(u, v)
	return Float32(Float32(1.0) + Float32(v * log(Float32(u + Float32(Float32(Float32(1.0) - u) * exp(Float32(Float32(-2.0) / v)))))))
end
function tmp = code(u, v)
	tmp = single(1.0) + (v * log((u + ((single(1.0) - u) * exp((single(-2.0) / v))))));
end
\begin{array}{l}

\\
1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right)
\end{array}

Alternative 1: 99.5% accurate, 1.0× speedup?

\[\begin{array}{l} \\ \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\frac{1}{e^{\frac{2}{v}}}, 1 - u, u\right)\right), 1\right) \end{array} \]
(FPCore (u v)
 :precision binary32
 (fma v (log (fma (/ 1.0 (exp (/ 2.0 v))) (- 1.0 u) u)) 1.0))
float code(float u, float v) {
	return fmaf(v, logf(fmaf((1.0f / expf((2.0f / v))), (1.0f - u), u)), 1.0f);
}
function code(u, v)
	return fma(v, log(fma(Float32(Float32(1.0) / exp(Float32(Float32(2.0) / v))), Float32(Float32(1.0) - u), u)), Float32(1.0))
end
\begin{array}{l}

\\
\mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\frac{1}{e^{\frac{2}{v}}}, 1 - u, u\right)\right), 1\right)
\end{array}
Derivation
  1. Initial program 99.5%

    \[1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \]
  2. Add Preprocessing
  3. Taylor expanded in v around 0

    \[\leadsto \color{blue}{1 + v \cdot \log \left(u + e^{\frac{-2}{v}} \cdot \left(1 - u\right)\right)} \]
  4. Step-by-step derivation
    1. +-commutativeN/A

      \[\leadsto \color{blue}{v \cdot \log \left(u + e^{\frac{-2}{v}} \cdot \left(1 - u\right)\right) + 1} \]
    2. lower-fma.f32N/A

      \[\leadsto \color{blue}{\mathsf{fma}\left(v, \log \left(u + e^{\frac{-2}{v}} \cdot \left(1 - u\right)\right), 1\right)} \]
    3. lower-log.f32N/A

      \[\leadsto \mathsf{fma}\left(v, \color{blue}{\log \left(u + e^{\frac{-2}{v}} \cdot \left(1 - u\right)\right)}, 1\right) \]
    4. +-commutativeN/A

      \[\leadsto \mathsf{fma}\left(v, \log \color{blue}{\left(e^{\frac{-2}{v}} \cdot \left(1 - u\right) + u\right)}, 1\right) \]
    5. lower-fma.f32N/A

      \[\leadsto \mathsf{fma}\left(v, \log \color{blue}{\left(\mathsf{fma}\left(e^{\frac{-2}{v}}, 1 - u, u\right)\right)}, 1\right) \]
    6. metadata-evalN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\frac{\color{blue}{\mathsf{neg}\left(2\right)}}{v}}, 1 - u, u\right)\right), 1\right) \]
    7. distribute-neg-fracN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\color{blue}{\mathsf{neg}\left(\frac{2}{v}\right)}}, 1 - u, u\right)\right), 1\right) \]
    8. metadata-evalN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\mathsf{neg}\left(\frac{\color{blue}{2 \cdot 1}}{v}\right)}, 1 - u, u\right)\right), 1\right) \]
    9. associate-*r/N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\mathsf{neg}\left(\color{blue}{2 \cdot \frac{1}{v}}\right)}, 1 - u, u\right)\right), 1\right) \]
    10. lower-exp.f32N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\color{blue}{e^{\mathsf{neg}\left(2 \cdot \frac{1}{v}\right)}}, 1 - u, u\right)\right), 1\right) \]
    11. associate-*r/N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\mathsf{neg}\left(\color{blue}{\frac{2 \cdot 1}{v}}\right)}, 1 - u, u\right)\right), 1\right) \]
    12. metadata-evalN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\mathsf{neg}\left(\frac{\color{blue}{2}}{v}\right)}, 1 - u, u\right)\right), 1\right) \]
    13. distribute-neg-fracN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\color{blue}{\frac{\mathsf{neg}\left(2\right)}{v}}}, 1 - u, u\right)\right), 1\right) \]
    14. metadata-evalN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\frac{\color{blue}{-2}}{v}}, 1 - u, u\right)\right), 1\right) \]
    15. lower-/.f32N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\color{blue}{\frac{-2}{v}}}, 1 - u, u\right)\right), 1\right) \]
    16. lower--.f3299.5

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\frac{-2}{v}}, \color{blue}{1 - u}, u\right)\right), 1\right) \]
  5. Simplified99.5%

    \[\leadsto \color{blue}{\mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\frac{-2}{v}}, 1 - u, u\right)\right), 1\right)} \]
  6. Step-by-step derivation
    1. frac-2negN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\color{blue}{\frac{\mathsf{neg}\left(-2\right)}{\mathsf{neg}\left(v\right)}}}, 1 - u, u\right)\right), 1\right) \]
    2. metadata-evalN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\frac{\color{blue}{2}}{\mathsf{neg}\left(v\right)}}, 1 - u, u\right)\right), 1\right) \]
    3. distribute-frac-neg2N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(e^{\color{blue}{\mathsf{neg}\left(\frac{2}{v}\right)}}, 1 - u, u\right)\right), 1\right) \]
    4. exp-negN/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\color{blue}{\frac{1}{e^{\frac{2}{v}}}}, 1 - u, u\right)\right), 1\right) \]
    5. lower-/.f32N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\color{blue}{\frac{1}{e^{\frac{2}{v}}}}, 1 - u, u\right)\right), 1\right) \]
    6. lower-exp.f32N/A

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\frac{1}{\color{blue}{e^{\frac{2}{v}}}}, 1 - u, u\right)\right), 1\right) \]
    7. lower-/.f3299.5

      \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\frac{1}{e^{\color{blue}{\frac{2}{v}}}}, 1 - u, u\right)\right), 1\right) \]
  7. Applied egg-rr99.5%

    \[\leadsto \mathsf{fma}\left(v, \log \left(\mathsf{fma}\left(\color{blue}{\frac{1}{e^{\frac{2}{v}}}}, 1 - u, u\right)\right), 1\right) \]
  8. Add Preprocessing

Alternative 2: 90.6% accurate, 0.9× speedup?

\[\begin{array}{l} \\ \begin{array}{l} \mathbf{if}\;v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \leq -1:\\ \;\;\;\;1 + \mathsf{fma}\left(u, 2, \mathsf{fma}\left(u, \frac{\mathsf{fma}\left(v, 2, 1.3333333333333333\right)}{v \cdot v}, -2\right)\right)\\ \mathbf{else}:\\ \;\;\;\;1\\ \end{array} \end{array} \]
(FPCore (u v)
 :precision binary32
 (if (<= (* v (log (+ u (* (- 1.0 u) (exp (/ -2.0 v)))))) -1.0)
   (+ 1.0 (fma u 2.0 (fma u (/ (fma v 2.0 1.3333333333333333) (* v v)) -2.0)))
   1.0))
float code(float u, float v) {
	float tmp;
	if ((v * logf((u + ((1.0f - u) * expf((-2.0f / v)))))) <= -1.0f) {
		tmp = 1.0f + fmaf(u, 2.0f, fmaf(u, (fmaf(v, 2.0f, 1.3333333333333333f) / (v * v)), -2.0f));
	} else {
		tmp = 1.0f;
	}
	return tmp;
}
function code(u, v)
	tmp = Float32(0.0)
	if (Float32(v * log(Float32(u + Float32(Float32(Float32(1.0) - u) * exp(Float32(Float32(-2.0) / v)))))) <= Float32(-1.0))
		tmp = Float32(Float32(1.0) + fma(u, Float32(2.0), fma(u, Float32(fma(v, Float32(2.0), Float32(1.3333333333333333)) / Float32(v * v)), Float32(-2.0))));
	else
		tmp = Float32(1.0);
	end
	return tmp
end
\begin{array}{l}

\\
\begin{array}{l}
\mathbf{if}\;v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \leq -1:\\
\;\;\;\;1 + \mathsf{fma}\left(u, 2, \mathsf{fma}\left(u, \frac{\mathsf{fma}\left(v, 2, 1.3333333333333333\right)}{v \cdot v}, -2\right)\right)\\

\mathbf{else}:\\
\;\;\;\;1\\


\end{array}
\end{array}
Derivation
  1. Split input into 2 regimes
  2. if (*.f32 v (log.f32 (+.f32 u (*.f32 (-.f32 #s(literal 1 binary32) u) (exp.f32 (/.f32 #s(literal -2 binary32) v)))))) < -1

    1. Initial program 93.1%

      \[1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \]
    2. Add Preprocessing
    3. Taylor expanded in v around -inf

      \[\leadsto 1 + v \cdot \color{blue}{\left(-1 \cdot \frac{-1 \cdot \frac{\frac{-1}{6} \cdot \frac{-24 \cdot {\left(1 - u\right)}^{2} + \left(8 \cdot \left(1 - u\right) + 16 \cdot {\left(1 - u\right)}^{3}\right)}{v} + \frac{1}{2} \cdot \left(-4 \cdot {\left(1 - u\right)}^{2} + 4 \cdot \left(1 - u\right)\right)}{v} + 2 \cdot \left(1 - u\right)}{v}\right)} \]
    4. Simplified69.9%

      \[\leadsto 1 + v \cdot \color{blue}{\frac{\mathsf{fma}\left(1 - u, 2, \frac{\mathsf{fma}\left(0.5, \left(1 - u\right) \cdot \mathsf{fma}\left(1 - u, -4, 4\right), \mathsf{fma}\left(\left(1 - u\right) \cdot \left(1 - u\right), \mathsf{fma}\left(1 - u, 16, -24\right), \mathsf{fma}\left(8, -u, 8\right)\right) \cdot \frac{-0.16666666666666666}{v}\right)}{-v}\right)}{-v}} \]
    5. Taylor expanded in u around 0

      \[\leadsto 1 + \color{blue}{\left(-1 \cdot \left(u \cdot \left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right)\right) - 2\right)} \]
    6. Step-by-step derivation
      1. sub-negN/A

        \[\leadsto 1 + \color{blue}{\left(-1 \cdot \left(u \cdot \left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right)\right) + \left(\mathsf{neg}\left(2\right)\right)\right)} \]
      2. mul-1-negN/A

        \[\leadsto 1 + \left(\color{blue}{\left(\mathsf{neg}\left(u \cdot \left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right)\right)\right)} + \left(\mathsf{neg}\left(2\right)\right)\right) \]
      3. distribute-rgt-neg-inN/A

        \[\leadsto 1 + \left(\color{blue}{u \cdot \left(\mathsf{neg}\left(\left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right)\right)\right)} + \left(\mathsf{neg}\left(2\right)\right)\right) \]
      4. mul-1-negN/A

        \[\leadsto 1 + \left(u \cdot \color{blue}{\left(-1 \cdot \left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right)\right)} + \left(\mathsf{neg}\left(2\right)\right)\right) \]
      5. metadata-evalN/A

        \[\leadsto 1 + \left(u \cdot \left(-1 \cdot \left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right)\right) + \color{blue}{-2}\right) \]
      6. lower-fma.f32N/A

        \[\leadsto 1 + \color{blue}{\mathsf{fma}\left(u, -1 \cdot \left(-1 \cdot \frac{2 + \frac{4}{3} \cdot \frac{1}{v}}{v} - 2\right), -2\right)} \]
    7. Simplified64.3%

      \[\leadsto 1 + \color{blue}{\mathsf{fma}\left(u, 2 + \frac{2 + \frac{1.3333333333333333}{v}}{v}, -2\right)} \]
    8. Taylor expanded in v around 0

      \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \color{blue}{\frac{\frac{4}{3} + 2 \cdot v}{{v}^{2}}}, -2\right) \]
    9. Step-by-step derivation
      1. lower-/.f32N/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \color{blue}{\frac{\frac{4}{3} + 2 \cdot v}{{v}^{2}}}, -2\right) \]
      2. +-commutativeN/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \frac{\color{blue}{2 \cdot v + \frac{4}{3}}}{{v}^{2}}, -2\right) \]
      3. lower-fma.f32N/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \frac{\color{blue}{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}}{{v}^{2}}, -2\right) \]
      4. unpow2N/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{\color{blue}{v \cdot v}}, -2\right) \]
      5. lower-*.f3264.3

        \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \frac{\mathsf{fma}\left(2, v, 1.3333333333333333\right)}{\color{blue}{v \cdot v}}, -2\right) \]
    10. Simplified64.3%

      \[\leadsto 1 + \mathsf{fma}\left(u, 2 + \color{blue}{\frac{\mathsf{fma}\left(2, v, 1.3333333333333333\right)}{v \cdot v}}, -2\right) \]
    11. Step-by-step derivation
      1. lift-fma.f32N/A

        \[\leadsto 1 + \left(u \cdot \left(2 + \frac{\color{blue}{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}}{v \cdot v}\right) + -2\right) \]
      2. lift-*.f32N/A

        \[\leadsto 1 + \left(u \cdot \left(2 + \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{\color{blue}{v \cdot v}}\right) + -2\right) \]
      3. lift-/.f32N/A

        \[\leadsto 1 + \left(u \cdot \left(2 + \color{blue}{\frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v}}\right) + -2\right) \]
      4. lift-+.f32N/A

        \[\leadsto 1 + \left(u \cdot \color{blue}{\left(2 + \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v}\right)} + -2\right) \]
      5. lift-+.f32N/A

        \[\leadsto 1 + \left(u \cdot \color{blue}{\left(2 + \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v}\right)} + -2\right) \]
      6. distribute-rgt-inN/A

        \[\leadsto 1 + \left(\color{blue}{\left(2 \cdot u + \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v} \cdot u\right)} + -2\right) \]
      7. *-commutativeN/A

        \[\leadsto 1 + \left(\left(\color{blue}{u \cdot 2} + \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v} \cdot u\right) + -2\right) \]
      8. associate-+l+N/A

        \[\leadsto 1 + \color{blue}{\left(u \cdot 2 + \left(\frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v} \cdot u + -2\right)\right)} \]
      9. lower-fma.f32N/A

        \[\leadsto 1 + \color{blue}{\mathsf{fma}\left(u, 2, \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v} \cdot u + -2\right)} \]
      10. *-commutativeN/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2, \color{blue}{u \cdot \frac{\mathsf{fma}\left(2, v, \frac{4}{3}\right)}{v \cdot v}} + -2\right) \]
      11. lower-fma.f3264.3

        \[\leadsto 1 + \mathsf{fma}\left(u, 2, \color{blue}{\mathsf{fma}\left(u, \frac{\mathsf{fma}\left(2, v, 1.3333333333333333\right)}{v \cdot v}, -2\right)}\right) \]
      12. lift-fma.f32N/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2, \mathsf{fma}\left(u, \frac{\color{blue}{2 \cdot v + \frac{4}{3}}}{v \cdot v}, -2\right)\right) \]
      13. *-commutativeN/A

        \[\leadsto 1 + \mathsf{fma}\left(u, 2, \mathsf{fma}\left(u, \frac{\color{blue}{v \cdot 2} + \frac{4}{3}}{v \cdot v}, -2\right)\right) \]
      14. lower-fma.f3264.3

        \[\leadsto 1 + \mathsf{fma}\left(u, 2, \mathsf{fma}\left(u, \frac{\color{blue}{\mathsf{fma}\left(v, 2, 1.3333333333333333\right)}}{v \cdot v}, -2\right)\right) \]
    12. Applied egg-rr64.3%

      \[\leadsto 1 + \color{blue}{\mathsf{fma}\left(u, 2, \mathsf{fma}\left(u, \frac{\mathsf{fma}\left(v, 2, 1.3333333333333333\right)}{v \cdot v}, -2\right)\right)} \]

    if -1 < (*.f32 v (log.f32 (+.f32 u (*.f32 (-.f32 #s(literal 1 binary32) u) (exp.f32 (/.f32 #s(literal -2 binary32) v))))))

    1. Initial program 99.9%

      \[1 + v \cdot \log \left(u + \left(1 - u\right) \cdot e^{\frac{-2}{v}}\right) \]
    2. Add Preprocessing
    3. Taylor expanded in v around 0

      \[\leadsto \color{blue}{1} \]
    4. Step-by-step derivation
      1. Simplified92.4%

        \[\leadsto \color{blue}{1} \]
    5. Recombined 2 regimes into one program.
    6. Add Preprocessing

    Reproduce

    ?
    herbie shell --seed 2024218 
    (FPCore (u v)
      :name "HairBSDF, sample_f, cosTheta"
      :precision binary32
      :pre (and (and (<= 1e-5 u) (<= u 1.0)) (and (<= 0.0 v) (<= v 109.746574)))
      (+ 1.0 (* v (log (+ u (* (- 1.0 u) (exp (/ -2.0 v))))))))