
(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:
Herbie found 9 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(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}
(FPCore (u v) :precision binary32 (let* ((t_0 (exp (/ -2.0 v)))) (+ 1.0 (* v (log (- (+ t_0 u) (* t_0 u)))))))
float code(float u, float v) {
float t_0 = expf((-2.0f / v));
return 1.0f + (v * logf(((t_0 + u) - (t_0 * u))));
}
real(4) function code(u, v)
real(4), intent (in) :: u
real(4), intent (in) :: v
real(4) :: t_0
t_0 = exp(((-2.0e0) / v))
code = 1.0e0 + (v * log(((t_0 + u) - (t_0 * u))))
end function
function code(u, v) t_0 = exp(Float32(Float32(-2.0) / v)) return Float32(Float32(1.0) + Float32(v * log(Float32(Float32(t_0 + u) - Float32(t_0 * u))))) end
function tmp = code(u, v) t_0 = exp((single(-2.0) / v)); tmp = single(1.0) + (v * log(((t_0 + u) - (t_0 * u)))); end
\begin{array}{l}
\\
\begin{array}{l}
t_0 := e^{\frac{-2}{v}}\\
1 + v \cdot \log \left(\left(t\_0 + u\right) - t\_0 \cdot u\right)
\end{array}
\end{array}
Initial program 99.6%
lift-+.f32N/A
lift-*.f32N/A
*-commutativeN/A
lift--.f32N/A
sub-negN/A
distribute-rgt-inN/A
*-lft-identityN/A
associate-+r+N/A
lower-+.f32N/A
lower-+.f32N/A
lower-*.f32N/A
lower-neg.f3299.6
Applied rewrites99.6%
lift-+.f32N/A
lift-*.f32N/A
lift-neg.f32N/A
distribute-lft-neg-outN/A
unsub-negN/A
lower--.f32N/A
lift-+.f32N/A
+-commutativeN/A
lower-+.f32N/A
*-commutativeN/A
lower-*.f3299.6
Applied rewrites99.6%
(FPCore (u v)
:precision binary32
(+
1.0
(*
v
(log
(+ u (* (- 1.0 u) (pow (exp 3.0) (* 0.3333333333333333 (/ -2.0 v)))))))))
float code(float u, float v) {
return 1.0f + (v * logf((u + ((1.0f - u) * powf(expf(3.0f), (0.3333333333333333f * (-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(3.0e0) ** (0.3333333333333333e0 * ((-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(3.0)) ^ Float32(Float32(0.3333333333333333) * Float32(Float32(-2.0) / v)))))))) end
function tmp = code(u, v) tmp = single(1.0) + (v * log((u + ((single(1.0) - u) * (exp(single(3.0)) ^ (single(0.3333333333333333) * (single(-2.0) / v))))))); end
\begin{array}{l}
\\
1 + v \cdot \log \left(u + \left(1 - u\right) \cdot {\left(e^{3}\right)}^{\left(0.3333333333333333 \cdot \frac{-2}{v}\right)}\right)
\end{array}
Initial program 99.6%
lift-exp.f32N/A
*-lft-identityN/A
exp-prodN/A
lower-pow.f32N/A
exp-1-eN/A
lower-E.f3299.6
Applied rewrites99.6%
lift-pow.f32N/A
lift-E.f32N/A
add-cbrt-cubeN/A
pow1/3N/A
metadata-evalN/A
log-EN/A
lift-E.f32N/A
log-powN/A
pow1/3N/A
lift-E.f32N/A
pow-powN/A
lower-pow.f32N/A
rem-cube-cbrtN/A
add-cbrt-cubeN/A
e-exp-1N/A
pow-expN/A
metadata-evalN/A
lower-exp.f32N/A
lower-*.f32N/A
Applied rewrites99.6%
(FPCore (u v) :precision binary32 (if (<= v 0.10000000149011612) (+ 1.0 (* v (log (fma (- u) (exp (/ -2.0 v)) u)))) (+ 1.0 (+ (* (- 1.0 u) -2.0) (* (* (* (- (/ 4.0 u) 4.0) u) u) (/ 0.5 v))))))
float code(float u, float v) {
float tmp;
if (v <= 0.10000000149011612f) {
tmp = 1.0f + (v * logf(fmaf(-u, expf((-2.0f / v)), u)));
} else {
tmp = 1.0f + (((1.0f - u) * -2.0f) + (((((4.0f / u) - 4.0f) * u) * u) * (0.5f / v)));
}
return tmp;
}
function code(u, v) tmp = Float32(0.0) if (v <= Float32(0.10000000149011612)) tmp = Float32(Float32(1.0) + Float32(v * log(fma(Float32(-u), exp(Float32(Float32(-2.0) / v)), u)))); else tmp = Float32(Float32(1.0) + Float32(Float32(Float32(Float32(1.0) - u) * Float32(-2.0)) + Float32(Float32(Float32(Float32(Float32(Float32(4.0) / u) - Float32(4.0)) * u) * u) * Float32(Float32(0.5) / v)))); end return tmp end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;v \leq 0.10000000149011612:\\
\;\;\;\;1 + v \cdot \log \left(\mathsf{fma}\left(-u, e^{\frac{-2}{v}}, u\right)\right)\\
\mathbf{else}:\\
\;\;\;\;1 + \left(\left(1 - u\right) \cdot -2 + \left(\left(\left(\frac{4}{u} - 4\right) \cdot u\right) \cdot u\right) \cdot \frac{0.5}{v}\right)\\
\end{array}
\end{array}
if v < 0.100000001Initial program 100.0%
lift-+.f32N/A
lift-*.f32N/A
*-commutativeN/A
lift--.f32N/A
sub-negN/A
distribute-rgt-inN/A
*-lft-identityN/A
associate-+r+N/A
lower-+.f32N/A
lower-+.f32N/A
lower-*.f32N/A
lower-neg.f32100.0
Applied rewrites100.0%
Taylor expanded in u around inf
+-commutativeN/A
distribute-lft-inN/A
associate-*r*N/A
*-commutativeN/A
*-rgt-identityN/A
lower-fma.f32N/A
mul-1-negN/A
lower-neg.f32N/A
metadata-evalN/A
distribute-neg-fracN/A
metadata-evalN/A
associate-*r/N/A
lower-exp.f32N/A
associate-*r/N/A
metadata-evalN/A
distribute-neg-fracN/A
metadata-evalN/A
lower-/.f3299.3
Applied rewrites99.3%
if 0.100000001 < v Initial program 94.7%
Taylor expanded in v around inf
+-commutativeN/A
*-commutativeN/A
lower-fma.f32N/A
lower-/.f32N/A
unpow2N/A
associate-*r*N/A
distribute-rgt-outN/A
lower-*.f32N/A
lower--.f32N/A
lower-fma.f32N/A
lower--.f32N/A
*-commutativeN/A
lower-*.f32N/A
lower--.f3247.3
Applied rewrites47.3%
Taylor expanded in u around inf
Applied rewrites45.2%
Applied rewrites56.3%
(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}
Initial program 99.6%
(FPCore (u v) :precision binary32 (+ 1.0 (* v (log (+ u (* 1.0 (pow (E) (/ -2.0 v))))))))
\begin{array}{l}
\\
1 + v \cdot \log \left(u + 1 \cdot {\mathsf{E}\left(\right)}^{\left(\frac{-2}{v}\right)}\right)
\end{array}
Initial program 99.6%
lift-exp.f32N/A
*-lft-identityN/A
exp-prodN/A
lower-pow.f32N/A
exp-1-eN/A
lower-E.f3299.6
Applied rewrites99.6%
Taylor expanded in u around 0
Applied rewrites96.7%
(FPCore (u v) :precision binary32 (+ 1.0 (* v (log (* (/ u v) 2.0)))))
float code(float u, float v) {
return 1.0f + (v * logf(((u / v) * 2.0f)));
}
real(4) function code(u, v)
real(4), intent (in) :: u
real(4), intent (in) :: v
code = 1.0e0 + (v * log(((u / v) * 2.0e0)))
end function
function code(u, v) return Float32(Float32(1.0) + Float32(v * log(Float32(Float32(u / v) * Float32(2.0))))) end
function tmp = code(u, v) tmp = single(1.0) + (v * log(((u / v) * single(2.0)))); end
\begin{array}{l}
\\
1 + v \cdot \log \left(\frac{u}{v} \cdot 2\right)
\end{array}
Initial program 99.6%
lift-+.f32N/A
lift-*.f32N/A
*-commutativeN/A
lift--.f32N/A
sub-negN/A
distribute-rgt-inN/A
*-lft-identityN/A
associate-+r+N/A
lower-+.f32N/A
lower-+.f32N/A
lower-*.f32N/A
lower-neg.f3299.6
Applied rewrites99.6%
lift-+.f32N/A
lift-*.f32N/A
lift-neg.f32N/A
distribute-lft-neg-outN/A
unsub-negN/A
lower--.f32N/A
lift-+.f32N/A
+-commutativeN/A
lower-+.f32N/A
*-commutativeN/A
lower-*.f3299.6
Applied rewrites99.6%
Taylor expanded in v around inf
+-commutativeN/A
metadata-evalN/A
cancel-sign-sub-invN/A
associate-*r/N/A
cancel-sign-sub-invN/A
metadata-evalN/A
distribute-rgt-inN/A
metadata-evalN/A
metadata-evalN/A
associate-*l*N/A
*-commutativeN/A
distribute-lft-inN/A
mul-1-negN/A
sub-negN/A
associate-*r/N/A
*-commutativeN/A
lower-fma.f32N/A
Applied rewrites81.0%
Taylor expanded in u around inf
Applied rewrites86.7%
Final simplification86.7%
(FPCore (u v) :precision binary32 (if (<= v 0.20000000298023224) 1.0 (+ 1.0 (+ (* (- 1.0 u) -2.0) (* (* (* (- (/ 4.0 u) 4.0) u) u) (/ 0.5 v))))))
float code(float u, float v) {
float tmp;
if (v <= 0.20000000298023224f) {
tmp = 1.0f;
} else {
tmp = 1.0f + (((1.0f - u) * -2.0f) + (((((4.0f / u) - 4.0f) * u) * u) * (0.5f / v)));
}
return tmp;
}
real(4) function code(u, v)
real(4), intent (in) :: u
real(4), intent (in) :: v
real(4) :: tmp
if (v <= 0.20000000298023224e0) then
tmp = 1.0e0
else
tmp = 1.0e0 + (((1.0e0 - u) * (-2.0e0)) + (((((4.0e0 / u) - 4.0e0) * u) * u) * (0.5e0 / v)))
end if
code = tmp
end function
function code(u, v) tmp = Float32(0.0) if (v <= Float32(0.20000000298023224)) tmp = Float32(1.0); else tmp = Float32(Float32(1.0) + Float32(Float32(Float32(Float32(1.0) - u) * Float32(-2.0)) + Float32(Float32(Float32(Float32(Float32(Float32(4.0) / u) - Float32(4.0)) * u) * u) * Float32(Float32(0.5) / v)))); end return tmp end
function tmp_2 = code(u, v) tmp = single(0.0); if (v <= single(0.20000000298023224)) tmp = single(1.0); else tmp = single(1.0) + (((single(1.0) - u) * single(-2.0)) + (((((single(4.0) / u) - single(4.0)) * u) * u) * (single(0.5) / v))); end tmp_2 = tmp; end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;v \leq 0.20000000298023224:\\
\;\;\;\;1\\
\mathbf{else}:\\
\;\;\;\;1 + \left(\left(1 - u\right) \cdot -2 + \left(\left(\left(\frac{4}{u} - 4\right) \cdot u\right) \cdot u\right) \cdot \frac{0.5}{v}\right)\\
\end{array}
\end{array}
if v < 0.200000003Initial program 100.0%
Taylor expanded in v around 0
Applied rewrites91.3%
if 0.200000003 < v Initial program 94.3%
Taylor expanded in v around inf
+-commutativeN/A
*-commutativeN/A
lower-fma.f32N/A
lower-/.f32N/A
unpow2N/A
associate-*r*N/A
distribute-rgt-outN/A
lower-*.f32N/A
lower--.f32N/A
lower-fma.f32N/A
lower--.f32N/A
*-commutativeN/A
lower-*.f32N/A
lower--.f3252.8
Applied rewrites52.8%
Taylor expanded in u around inf
Applied rewrites50.4%
Applied rewrites63.0%
(FPCore (u v) :precision binary32 1.0)
float code(float u, float v) {
return 1.0f;
}
real(4) function code(u, v)
real(4), intent (in) :: u
real(4), intent (in) :: v
code = 1.0e0
end function
function code(u, v) return Float32(1.0) end
function tmp = code(u, v) tmp = single(1.0); end
\begin{array}{l}
\\
1
\end{array}
Initial program 99.6%
Taylor expanded in v around 0
Applied rewrites86.0%
(FPCore (u v) :precision binary32 -1.0)
float code(float u, float v) {
return -1.0f;
}
real(4) function code(u, v)
real(4), intent (in) :: u
real(4), intent (in) :: v
code = -1.0e0
end function
function code(u, v) return Float32(-1.0) end
function tmp = code(u, v) tmp = single(-1.0); end
\begin{array}{l}
\\
-1
\end{array}
Initial program 99.6%
Taylor expanded in u around 0
Applied rewrites5.7%
herbie shell --seed 2024322
(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))))))))