
(FPCore (x s) :precision binary32 (let* ((t_0 (exp (/ (- (fabs x)) s))) (t_1 (+ 1.0 t_0))) (/ t_0 (* (* s t_1) t_1))))
float code(float x, float s) {
float t_0 = expf((-fabsf(x) / s));
float t_1 = 1.0f + t_0;
return t_0 / ((s * t_1) * t_1);
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
real(4) :: t_0
real(4) :: t_1
t_0 = exp((-abs(x) / s))
t_1 = 1.0e0 + t_0
code = t_0 / ((s * t_1) * t_1)
end function
function code(x, s) t_0 = exp(Float32(Float32(-abs(x)) / s)) t_1 = Float32(Float32(1.0) + t_0) return Float32(t_0 / Float32(Float32(s * t_1) * t_1)) end
function tmp = code(x, s) t_0 = exp((-abs(x) / s)); t_1 = single(1.0) + t_0; tmp = t_0 / ((s * t_1) * t_1); end
\begin{array}{l}
\\
\begin{array}{l}
t_0 := e^{\frac{-\left|x\right|}{s}}\\
t_1 := 1 + t_0\\
\frac{t_0}{\left(s \cdot t_1\right) \cdot t_1}
\end{array}
\end{array}
Sampling outcomes in binary32 precision:
Herbie found 8 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x s) :precision binary32 (let* ((t_0 (exp (/ (- (fabs x)) s))) (t_1 (+ 1.0 t_0))) (/ t_0 (* (* s t_1) t_1))))
float code(float x, float s) {
float t_0 = expf((-fabsf(x) / s));
float t_1 = 1.0f + t_0;
return t_0 / ((s * t_1) * t_1);
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
real(4) :: t_0
real(4) :: t_1
t_0 = exp((-abs(x) / s))
t_1 = 1.0e0 + t_0
code = t_0 / ((s * t_1) * t_1)
end function
function code(x, s) t_0 = exp(Float32(Float32(-abs(x)) / s)) t_1 = Float32(Float32(1.0) + t_0) return Float32(t_0 / Float32(Float32(s * t_1) * t_1)) end
function tmp = code(x, s) t_0 = exp((-abs(x) / s)); t_1 = single(1.0) + t_0; tmp = t_0 / ((s * t_1) * t_1); end
\begin{array}{l}
\\
\begin{array}{l}
t_0 := e^{\frac{-\left|x\right|}{s}}\\
t_1 := 1 + t_0\\
\frac{t_0}{\left(s \cdot t_1\right) \cdot t_1}
\end{array}
\end{array}
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ 1.0 (* (+ 1.0 (exp (/ (- x_m) s))) (+ s (expm1 (log1p (* s (exp (/ x_m s)))))))))
x_m = fabs(x);
float code(float x_m, float s) {
return 1.0f / ((1.0f + expf((-x_m / s))) * (s + expm1f(log1pf((s * expf((x_m / s)))))));
}
x_m = abs(x) function code(x_m, s) return Float32(Float32(1.0) / Float32(Float32(Float32(1.0) + exp(Float32(Float32(-x_m) / s))) * Float32(s + expm1(log1p(Float32(s * exp(Float32(x_m / s)))))))) end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{1}{\left(1 + e^{\frac{-x_m}{s}}\right) \cdot \left(s + \mathsf{expm1}\left(\mathsf{log1p}\left(s \cdot e^{\frac{x_m}{s}}\right)\right)\right)}
\end{array}
Initial program 99.4%
Simplified99.5%
fma-udef99.5%
frac-2neg99.5%
frac-2neg99.5%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt65.4%
Applied egg-rr65.4%
expm1-log1p-u65.4%
Applied egg-rr65.4%
distribute-frac-neg65.4%
rec-exp65.3%
div-inv65.3%
exp-prod62.5%
add-sqr-sqrt62.5%
sqrt-unprod62.5%
sqr-neg62.5%
sqrt-unprod-0.0%
add-sqr-sqrt89.5%
exp-prod96.1%
div-inv96.1%
add-sqr-sqrt-0.0%
sqrt-unprod63.6%
sqr-neg63.6%
sqrt-unprod65.3%
add-sqr-sqrt65.3%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt99.5%
Applied egg-rr99.5%
rec-exp99.5%
distribute-neg-frac99.5%
Simplified99.5%
Final simplification99.5%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ 1.0 (* (+ 1.0 (exp (/ (- x_m) s))) (+ s (* s (exp (/ x_m s)))))))
x_m = fabs(x);
float code(float x_m, float s) {
return 1.0f / ((1.0f + expf((-x_m / s))) * (s + (s * expf((x_m / s)))));
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
code = 1.0e0 / ((1.0e0 + exp((-x_m / s))) * (s + (s * exp((x_m / s)))))
end function
x_m = abs(x) function code(x_m, s) return Float32(Float32(1.0) / Float32(Float32(Float32(1.0) + exp(Float32(Float32(-x_m) / s))) * Float32(s + Float32(s * exp(Float32(x_m / s)))))) end
x_m = abs(x); function tmp = code(x_m, s) tmp = single(1.0) / ((single(1.0) + exp((-x_m / s))) * (s + (s * exp((x_m / s))))); end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{1}{\left(1 + e^{\frac{-x_m}{s}}\right) \cdot \left(s + s \cdot e^{\frac{x_m}{s}}\right)}
\end{array}
Initial program 99.4%
Simplified99.5%
fma-udef99.5%
frac-2neg99.5%
frac-2neg99.5%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt65.4%
Applied egg-rr65.4%
distribute-frac-neg65.4%
rec-exp65.3%
div-inv65.3%
exp-prod62.5%
add-sqr-sqrt62.5%
sqrt-unprod62.5%
sqr-neg62.5%
sqrt-unprod-0.0%
add-sqr-sqrt89.5%
exp-prod96.1%
div-inv96.1%
add-sqr-sqrt-0.0%
sqrt-unprod63.6%
sqr-neg63.6%
sqrt-unprod65.3%
add-sqr-sqrt65.3%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt99.5%
Applied egg-rr99.5%
rec-exp99.5%
distribute-neg-frac99.5%
Simplified99.5%
Final simplification99.5%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ 1.0 (* (+ s (* s (exp (/ x_m s)))) 2.0)))
x_m = fabs(x);
float code(float x_m, float s) {
return 1.0f / ((s + (s * expf((x_m / s)))) * 2.0f);
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
code = 1.0e0 / ((s + (s * exp((x_m / s)))) * 2.0e0)
end function
x_m = abs(x) function code(x_m, s) return Float32(Float32(1.0) / Float32(Float32(s + Float32(s * exp(Float32(x_m / s)))) * Float32(2.0))) end
x_m = abs(x); function tmp = code(x_m, s) tmp = single(1.0) / ((s + (s * exp((x_m / s)))) * single(2.0)); end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{1}{\left(s + s \cdot e^{\frac{x_m}{s}}\right) \cdot 2}
\end{array}
Initial program 99.4%
Simplified99.5%
fma-udef99.5%
frac-2neg99.5%
frac-2neg99.5%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt65.4%
Applied egg-rr65.4%
Taylor expanded in s around inf 62.3%
Final simplification62.3%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ (exp (/ (- x_m) s)) (* s 4.0)))
x_m = fabs(x);
float code(float x_m, float s) {
return expf((-x_m / s)) / (s * 4.0f);
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
code = exp((-x_m / s)) / (s * 4.0e0)
end function
x_m = abs(x) function code(x_m, s) return Float32(exp(Float32(Float32(-x_m) / s)) / Float32(s * Float32(4.0))) end
x_m = abs(x); function tmp = code(x_m, s) tmp = exp((-x_m / s)) / (s * single(4.0)); end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{e^{\frac{-x_m}{s}}}{s \cdot 4}
\end{array}
Initial program 99.4%
associate-*l*99.5%
Simplified99.5%
Taylor expanded in s around inf 94.7%
distribute-frac-neg65.4%
rec-exp65.3%
div-inv65.3%
exp-prod62.5%
add-sqr-sqrt62.5%
sqrt-unprod62.5%
sqr-neg62.5%
sqrt-unprod-0.0%
add-sqr-sqrt89.5%
exp-prod96.1%
div-inv96.1%
add-sqr-sqrt-0.0%
sqrt-unprod63.6%
sqr-neg63.6%
sqrt-unprod65.3%
add-sqr-sqrt65.3%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt99.5%
Applied egg-rr61.5%
rec-exp99.5%
distribute-neg-frac99.5%
Simplified61.5%
Final simplification61.5%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ (/ 0.25 (exp (/ x_m s))) s))
x_m = fabs(x);
float code(float x_m, float s) {
return (0.25f / expf((x_m / s))) / s;
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
code = (0.25e0 / exp((x_m / s))) / s
end function
x_m = abs(x) function code(x_m, s) return Float32(Float32(Float32(0.25) / exp(Float32(x_m / s))) / s) end
x_m = abs(x); function tmp = code(x_m, s) tmp = (single(0.25) / exp((x_m / s))) / s; end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{\frac{0.25}{e^{\frac{x_m}{s}}}}{s}
\end{array}
Initial program 99.4%
associate-*l*99.5%
Simplified99.5%
Taylor expanded in s around inf 94.7%
distribute-frac-neg65.4%
rec-exp65.3%
div-inv65.3%
exp-prod62.5%
add-sqr-sqrt62.5%
sqrt-unprod62.5%
sqr-neg62.5%
sqrt-unprod-0.0%
add-sqr-sqrt89.5%
exp-prod96.1%
div-inv96.1%
add-sqr-sqrt-0.0%
sqrt-unprod63.6%
sqr-neg63.6%
sqrt-unprod65.3%
add-sqr-sqrt65.3%
add-sqr-sqrt55.8%
fabs-sqr55.8%
add-sqr-sqrt99.5%
Applied egg-rr61.5%
rec-exp99.5%
distribute-neg-frac99.5%
Simplified61.5%
Taylor expanded in x around inf 61.5%
associate-*r/61.5%
mul-1-neg61.5%
rec-exp61.5%
associate-*r/61.5%
metadata-eval61.5%
Simplified61.5%
Final simplification61.5%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (if (<= x_m 1.999999987845058e-8) (/ 0.25 s) (* (/ s x_m) (/ 1.0 x_m))))
x_m = fabs(x);
float code(float x_m, float s) {
float tmp;
if (x_m <= 1.999999987845058e-8f) {
tmp = 0.25f / s;
} else {
tmp = (s / x_m) * (1.0f / x_m);
}
return tmp;
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
real(4) :: tmp
if (x_m <= 1.999999987845058e-8) then
tmp = 0.25e0 / s
else
tmp = (s / x_m) * (1.0e0 / x_m)
end if
code = tmp
end function
x_m = abs(x) function code(x_m, s) tmp = Float32(0.0) if (x_m <= Float32(1.999999987845058e-8)) tmp = Float32(Float32(0.25) / s); else tmp = Float32(Float32(s / x_m) * Float32(Float32(1.0) / x_m)); end return tmp end
x_m = abs(x); function tmp_2 = code(x_m, s) tmp = single(0.0); if (x_m <= single(1.999999987845058e-8)) tmp = single(0.25) / s; else tmp = (s / x_m) * (single(1.0) / x_m); end tmp_2 = tmp; end
\begin{array}{l}
x_m = \left|x\right|
\\
\begin{array}{l}
\mathbf{if}\;x_m \leq 1.999999987845058 \cdot 10^{-8}:\\
\;\;\;\;\frac{0.25}{s}\\
\mathbf{else}:\\
\;\;\;\;\frac{s}{x_m} \cdot \frac{1}{x_m}\\
\end{array}
\end{array}
if x < 1.99999999e-8Initial program 99.2%
associate-*l*99.3%
Simplified99.3%
Taylor expanded in s around inf 35.5%
if 1.99999999e-8 < x Initial program 100.0%
Simplified100.0%
Taylor expanded in s around -inf 24.1%
+-commutative24.1%
associate-+r+24.1%
mul-1-neg24.1%
distribute-lft1-in57.4%
metadata-eval57.4%
associate-*r/57.4%
mul-1-neg57.4%
remove-double-neg57.4%
associate-+r+57.4%
Simplified61.1%
Taylor expanded in x around inf 58.4%
*-un-lft-identity58.4%
unpow258.4%
times-frac58.4%
Applied egg-rr58.4%
Final simplification42.7%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ 1.0 (+ (* s 4.0) (/ x_m (/ s x_m)))))
x_m = fabs(x);
float code(float x_m, float s) {
return 1.0f / ((s * 4.0f) + (x_m / (s / x_m)));
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
code = 1.0e0 / ((s * 4.0e0) + (x_m / (s / x_m)))
end function
x_m = abs(x) function code(x_m, s) return Float32(Float32(1.0) / Float32(Float32(s * Float32(4.0)) + Float32(x_m / Float32(s / x_m)))) end
x_m = abs(x); function tmp = code(x_m, s) tmp = single(1.0) / ((s * single(4.0)) + (x_m / (s / x_m))); end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{1}{s \cdot 4 + \frac{x_m}{\frac{s}{x_m}}}
\end{array}
Initial program 99.4%
Simplified99.5%
Taylor expanded in s around -inf 37.4%
+-commutative37.4%
associate-+r+37.4%
mul-1-neg37.4%
distribute-lft1-in62.8%
metadata-eval62.8%
associate-*r/62.8%
mul-1-neg62.8%
remove-double-neg62.8%
associate-+r+62.8%
Simplified63.9%
add-sqr-sqrt63.9%
fma-def63.9%
sqrt-div63.9%
sqrt-prod34.0%
add-sqr-sqrt63.9%
sqrt-div63.9%
sqrt-prod34.4%
add-sqr-sqrt64.5%
mul0-rgt64.5%
+-lft-identity64.5%
Applied egg-rr64.5%
fma-udef64.5%
unpow264.5%
Simplified64.5%
unpow264.5%
frac-2neg64.5%
clear-num64.5%
frac-2neg64.5%
add-sqr-sqrt34.4%
sqrt-prod63.9%
unpow263.9%
sqrt-div63.9%
frac-times63.9%
*-un-lft-identity63.9%
sqrt-div63.9%
unpow263.9%
sqrt-prod34.4%
add-sqr-sqrt64.5%
Applied egg-rr64.5%
associate-*l/64.5%
rem-square-sqrt64.5%
Simplified64.5%
Final simplification64.5%
x_m = (fabs.f32 x) (FPCore (x_m s) :precision binary32 (/ 0.25 s))
x_m = fabs(x);
float code(float x_m, float s) {
return 0.25f / s;
}
x_m = abs(x)
real(4) function code(x_m, s)
real(4), intent (in) :: x_m
real(4), intent (in) :: s
code = 0.25e0 / s
end function
x_m = abs(x) function code(x_m, s) return Float32(Float32(0.25) / s) end
x_m = abs(x); function tmp = code(x_m, s) tmp = single(0.25) / s; end
\begin{array}{l}
x_m = \left|x\right|
\\
\frac{0.25}{s}
\end{array}
Initial program 99.4%
associate-*l*99.5%
Simplified99.5%
Taylor expanded in s around inf 25.9%
Final simplification25.9%
herbie shell --seed 2024019
(FPCore (x s)
:name "Logistic distribution"
:precision binary32
:pre (and (<= 0.0 s) (<= s 1.0651631))
(/ (exp (/ (- (fabs x)) s)) (* (* s (+ 1.0 (exp (/ (- (fabs x)) s)))) (+ 1.0 (exp (/ (- (fabs x)) s))))))