
(FPCore (alphax alphay u0 cos2phi sin2phi) :precision binary32 (/ (- (log (- 1.0 u0))) (+ (/ cos2phi (* alphax alphax)) (/ sin2phi (* alphay alphay)))))
float code(float alphax, float alphay, float u0, float cos2phi, float sin2phi) {
return -logf((1.0f - u0)) / ((cos2phi / (alphax * alphax)) + (sin2phi / (alphay * alphay)));
}
real(4) function code(alphax, alphay, u0, cos2phi, sin2phi)
real(4), intent (in) :: alphax
real(4), intent (in) :: alphay
real(4), intent (in) :: u0
real(4), intent (in) :: cos2phi
real(4), intent (in) :: sin2phi
code = -log((1.0e0 - u0)) / ((cos2phi / (alphax * alphax)) + (sin2phi / (alphay * alphay)))
end function
function code(alphax, alphay, u0, cos2phi, sin2phi) return Float32(Float32(-log(Float32(Float32(1.0) - u0))) / Float32(Float32(cos2phi / Float32(alphax * alphax)) + Float32(sin2phi / Float32(alphay * alphay)))) end
function tmp = code(alphax, alphay, u0, cos2phi, sin2phi) tmp = -log((single(1.0) - u0)) / ((cos2phi / (alphax * alphax)) + (sin2phi / (alphay * alphay))); end
\begin{array}{l}
\\
\frac{-\log \left(1 - u0\right)}{\frac{cos2phi}{alphax \cdot alphax} + \frac{sin2phi}{alphay \cdot alphay}}
\end{array}
Sampling outcomes in binary32 precision:
Herbie found 25 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (alphax alphay u0 cos2phi sin2phi) :precision binary32 (/ (- (log (- 1.0 u0))) (+ (/ cos2phi (* alphax alphax)) (/ sin2phi (* alphay alphay)))))
float code(float alphax, float alphay, float u0, float cos2phi, float sin2phi) {
return -logf((1.0f - u0)) / ((cos2phi / (alphax * alphax)) + (sin2phi / (alphay * alphay)));
}
real(4) function code(alphax, alphay, u0, cos2phi, sin2phi)
real(4), intent (in) :: alphax
real(4), intent (in) :: alphay
real(4), intent (in) :: u0
real(4), intent (in) :: cos2phi
real(4), intent (in) :: sin2phi
code = -log((1.0e0 - u0)) / ((cos2phi / (alphax * alphax)) + (sin2phi / (alphay * alphay)))
end function
function code(alphax, alphay, u0, cos2phi, sin2phi) return Float32(Float32(-log(Float32(Float32(1.0) - u0))) / Float32(Float32(cos2phi / Float32(alphax * alphax)) + Float32(sin2phi / Float32(alphay * alphay)))) end
function tmp = code(alphax, alphay, u0, cos2phi, sin2phi) tmp = -log((single(1.0) - u0)) / ((cos2phi / (alphax * alphax)) + (sin2phi / (alphay * alphay))); end
\begin{array}{l}
\\
\frac{-\log \left(1 - u0\right)}{\frac{cos2phi}{alphax \cdot alphax} + \frac{sin2phi}{alphay \cdot alphay}}
\end{array}
(FPCore (alphax alphay u0 cos2phi sin2phi) :precision binary32 (* (/ (log1p (- u0)) (- (fma alphax (* alphax (/ sin2phi alphay)) (* alphay cos2phi)))) (* alphax (* alphax alphay))))
float code(float alphax, float alphay, float u0, float cos2phi, float sin2phi) {
return (log1pf(-u0) / -fmaf(alphax, (alphax * (sin2phi / alphay)), (alphay * cos2phi))) * (alphax * (alphax * alphay));
}
function code(alphax, alphay, u0, cos2phi, sin2phi) return Float32(Float32(log1p(Float32(-u0)) / Float32(-fma(alphax, Float32(alphax * Float32(sin2phi / alphay)), Float32(alphay * cos2phi)))) * Float32(alphax * Float32(alphax * alphay))) end
\begin{array}{l}
\\
\frac{\mathsf{log1p}\left(-u0\right)}{-\mathsf{fma}\left(alphax, alphax \cdot \frac{sin2phi}{alphay}, alphay \cdot cos2phi\right)} \cdot \left(alphax \cdot \left(alphax \cdot alphay\right)\right)
\end{array}
Initial program 60.6%
lift-/.f32N/A
frac-2negN/A
div-invN/A
lift-neg.f32N/A
remove-double-negN/A
frac-2negN/A
metadata-evalN/A
remove-double-negN/A
lower-*.f32N/A
lift-log.f32N/A
lift--.f32N/A
sub-negN/A
lower-log1p.f32N/A
lower-neg.f32N/A
lower-/.f3298.1
Applied rewrites98.1%
lift-*.f32N/A
*-commutativeN/A
lift-/.f32N/A
associate-*l/N/A
lift-log1p.f32N/A
lift-neg.f32N/A
sub-negN/A
neg-mul-1N/A
lift-+.f32N/A
lift-/.f32N/A
lift-/.f32N/A
lift-*.f32N/A
associate-/r*N/A
lift-/.f32N/A
frac-addN/A
associate-/r/N/A
Applied rewrites98.4%
Final simplification98.4%
(FPCore (alphax alphay u0 cos2phi sin2phi)
:precision binary32
(*
(* alphay alphay)
(*
(- (* alphax alphax))
(/
(log1p (- u0))
(fma (* alphax alphax) sin2phi (* cos2phi (* alphay alphay)))))))
float code(float alphax, float alphay, float u0, float cos2phi, float sin2phi) {
return (alphay * alphay) * (-(alphax * alphax) * (log1pf(-u0) / fmaf((alphax * alphax), sin2phi, (cos2phi * (alphay * alphay)))));
}
function code(alphax, alphay, u0, cos2phi, sin2phi) return Float32(Float32(alphay * alphay) * Float32(Float32(-Float32(alphax * alphax)) * Float32(log1p(Float32(-u0)) / fma(Float32(alphax * alphax), sin2phi, Float32(cos2phi * Float32(alphay * alphay)))))) end
\begin{array}{l}
\\
\left(alphay \cdot alphay\right) \cdot \left(\left(-alphax \cdot alphax\right) \cdot \frac{\mathsf{log1p}\left(-u0\right)}{\mathsf{fma}\left(alphax \cdot alphax, sin2phi, cos2phi \cdot \left(alphay \cdot alphay\right)\right)}\right)
\end{array}
Initial program 60.9%
lift-/.f32N/A
lift-+.f32N/A
lift-/.f32N/A
lift-/.f32N/A
frac-addN/A
associate-/r/N/A
associate-*r*N/A
lower-*.f32N/A
Applied rewrites98.4%
Final simplification98.4%
herbie shell --seed 2024228
(FPCore (alphax alphay u0 cos2phi sin2phi)
:name "Beckmann Distribution sample, tan2theta, alphax != alphay, u1 <= 0.5"
:precision binary32
:pre (and (and (and (and (and (<= 0.0001 alphax) (<= alphax 1.0)) (and (<= 0.0001 alphay) (<= alphay 1.0))) (and (<= 2.328306437e-10 u0) (<= u0 1.0))) (and (<= 0.0 cos2phi) (<= cos2phi 1.0))) (<= 0.0 sin2phi))
(/ (- (log (- 1.0 u0))) (+ (/ cos2phi (* alphax alphax)) (/ sin2phi (* alphay alphay)))))