
(FPCore (ux uy maxCos) :precision binary32 (+ (- 1.0 ux) (* ux maxCos)))
float code(float ux, float uy, float maxCos) {
return (1.0f - ux) + (ux * maxCos);
}
real(4) function code(ux, uy, maxcos)
real(4), intent (in) :: ux
real(4), intent (in) :: uy
real(4), intent (in) :: maxcos
code = (1.0e0 - ux) + (ux * maxcos)
end function
function code(ux, uy, maxCos) return Float32(Float32(Float32(1.0) - ux) + Float32(ux * maxCos)) end
function tmp = code(ux, uy, maxCos) tmp = (single(1.0) - ux) + (ux * maxCos); end
\begin{array}{l}
\\
\left(1 - ux\right) + ux \cdot maxCos
\end{array}
Sampling outcomes in binary32 precision:
Herbie found 4 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (ux uy maxCos) :precision binary32 (+ (- 1.0 ux) (* ux maxCos)))
float code(float ux, float uy, float maxCos) {
return (1.0f - ux) + (ux * maxCos);
}
real(4) function code(ux, uy, maxcos)
real(4), intent (in) :: ux
real(4), intent (in) :: uy
real(4), intent (in) :: maxcos
code = (1.0e0 - ux) + (ux * maxcos)
end function
function code(ux, uy, maxCos) return Float32(Float32(Float32(1.0) - ux) + Float32(ux * maxCos)) end
function tmp = code(ux, uy, maxCos) tmp = (single(1.0) - ux) + (ux * maxCos); end
\begin{array}{l}
\\
\left(1 - ux\right) + ux \cdot maxCos
\end{array}
(FPCore (ux uy maxCos) :precision binary32 (+ 1.0 (/ (* (- 1.0 (* maxCos maxCos)) ux) (- -1.0 maxCos))))
float code(float ux, float uy, float maxCos) {
return 1.0f + (((1.0f - (maxCos * maxCos)) * ux) / (-1.0f - maxCos));
}
real(4) function code(ux, uy, maxcos)
real(4), intent (in) :: ux
real(4), intent (in) :: uy
real(4), intent (in) :: maxcos
code = 1.0e0 + (((1.0e0 - (maxcos * maxcos)) * ux) / ((-1.0e0) - maxcos))
end function
function code(ux, uy, maxCos) return Float32(Float32(1.0) + Float32(Float32(Float32(Float32(1.0) - Float32(maxCos * maxCos)) * ux) / Float32(Float32(-1.0) - maxCos))) end
function tmp = code(ux, uy, maxCos) tmp = single(1.0) + (((single(1.0) - (maxCos * maxCos)) * ux) / (single(-1.0) - maxCos)); end
\begin{array}{l}
\\
1 + \frac{\left(1 - maxCos \cdot maxCos\right) \cdot ux}{-1 - maxCos}
\end{array}
Initial program 99.9%
sub-negN/A
associate-+l+N/A
+-lowering-+.f32N/A
neg-mul-1N/A
*-commutativeN/A
distribute-rgt-outN/A
*-lowering-*.f32N/A
+-commutativeN/A
+-lowering-+.f32100.0%
Simplified100.0%
*-commutativeN/A
+-commutativeN/A
flip-+N/A
associate-*l/N/A
/-lowering-/.f32N/A
*-lowering-*.f32N/A
metadata-evalN/A
--lowering--.f32N/A
*-lowering-*.f32N/A
--lowering--.f32100.0%
Applied egg-rr100.0%
(FPCore (ux uy maxCos) :precision binary32 (+ 1.0 (* ux (+ maxCos -1.0))))
float code(float ux, float uy, float maxCos) {
return 1.0f + (ux * (maxCos + -1.0f));
}
real(4) function code(ux, uy, maxcos)
real(4), intent (in) :: ux
real(4), intent (in) :: uy
real(4), intent (in) :: maxcos
code = 1.0e0 + (ux * (maxcos + (-1.0e0)))
end function
function code(ux, uy, maxCos) return Float32(Float32(1.0) + Float32(ux * Float32(maxCos + Float32(-1.0)))) end
function tmp = code(ux, uy, maxCos) tmp = single(1.0) + (ux * (maxCos + single(-1.0))); end
\begin{array}{l}
\\
1 + ux \cdot \left(maxCos + -1\right)
\end{array}
Initial program 99.9%
sub-negN/A
associate-+l+N/A
+-lowering-+.f32N/A
neg-mul-1N/A
*-commutativeN/A
distribute-rgt-outN/A
*-lowering-*.f32N/A
+-commutativeN/A
+-lowering-+.f32100.0%
Simplified100.0%
(FPCore (ux uy maxCos) :precision binary32 (- 1.0 ux))
float code(float ux, float uy, float maxCos) {
return 1.0f - ux;
}
real(4) function code(ux, uy, maxcos)
real(4), intent (in) :: ux
real(4), intent (in) :: uy
real(4), intent (in) :: maxcos
code = 1.0e0 - ux
end function
function code(ux, uy, maxCos) return Float32(Float32(1.0) - ux) end
function tmp = code(ux, uy, maxCos) tmp = single(1.0) - ux; end
\begin{array}{l}
\\
1 - ux
\end{array}
Initial program 99.9%
sub-negN/A
associate-+l+N/A
+-lowering-+.f32N/A
neg-mul-1N/A
*-commutativeN/A
distribute-rgt-outN/A
*-lowering-*.f32N/A
+-commutativeN/A
+-lowering-+.f32100.0%
Simplified100.0%
Taylor expanded in maxCos around 0
mul-1-negN/A
unsub-negN/A
--lowering--.f3297.9%
Simplified97.9%
(FPCore (ux uy maxCos) :precision binary32 1.0)
float code(float ux, float uy, float maxCos) {
return 1.0f;
}
real(4) function code(ux, uy, maxcos)
real(4), intent (in) :: ux
real(4), intent (in) :: uy
real(4), intent (in) :: maxcos
code = 1.0e0
end function
function code(ux, uy, maxCos) return Float32(1.0) end
function tmp = code(ux, uy, maxCos) tmp = single(1.0); end
\begin{array}{l}
\\
1
\end{array}
Initial program 99.9%
sub-negN/A
associate-+l+N/A
+-lowering-+.f32N/A
neg-mul-1N/A
*-commutativeN/A
distribute-rgt-outN/A
*-lowering-*.f32N/A
+-commutativeN/A
+-lowering-+.f32100.0%
Simplified100.0%
Taylor expanded in ux around 0
Simplified71.4%
herbie shell --seed 2024149
(FPCore (ux uy maxCos)
:name "UniformSampleCone, z"
:precision binary32
:pre (and (and (and (<= 2.328306437e-10 ux) (<= ux 1.0)) (and (<= 2.328306437e-10 uy) (<= uy 1.0))) (and (<= 0.0 maxCos) (<= maxCos 1.0)))
(+ (- 1.0 ux) (* ux maxCos)))