
(FPCore (x s) :precision binary32 (/ 1.0 (+ 1.0 (exp (/ (- x) s)))))
float code(float x, float s) {
return 1.0f / (1.0f + expf((-x / s)));
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
code = 1.0e0 / (1.0e0 + exp((-x / s)))
end function
function code(x, s) return Float32(Float32(1.0) / Float32(Float32(1.0) + exp(Float32(Float32(-x) / s)))) end
function tmp = code(x, s) tmp = single(1.0) / (single(1.0) + exp((-x / s))); end
\begin{array}{l}
\\
\frac{1}{1 + e^{\frac{-x}{s}}}
\end{array}
Sampling outcomes in binary32 precision:
Herbie found 12 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (x s) :precision binary32 (/ 1.0 (+ 1.0 (exp (/ (- x) s)))))
float code(float x, float s) {
return 1.0f / (1.0f + expf((-x / s)));
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
code = 1.0e0 / (1.0e0 + exp((-x / s)))
end function
function code(x, s) return Float32(Float32(1.0) / Float32(Float32(1.0) + exp(Float32(Float32(-x) / s)))) end
function tmp = code(x, s) tmp = single(1.0) / (single(1.0) + exp((-x / s))); end
\begin{array}{l}
\\
\frac{1}{1 + e^{\frac{-x}{s}}}
\end{array}
(FPCore (x s) :precision binary32 (exp (- (log1p (exp (/ (- x) s))))))
float code(float x, float s) {
return expf(-log1pf(expf((-x / s))));
}
function code(x, s) return exp(Float32(-log1p(exp(Float32(Float32(-x) / s))))) end
\begin{array}{l}
\\
e^{-\mathsf{log1p}\left(e^{\frac{-x}{s}}\right)}
\end{array}
Initial program 99.7%
lift-neg.f32N/A
lift-/.f32N/A
lift-exp.f32N/A
lift-+.f32N/A
inv-powN/A
pow-to-expN/A
*-commutativeN/A
log-powN/A
inv-powN/A
lift-/.f32N/A
lower-exp.f32N/A
lift-/.f32N/A
log-recN/A
lower-neg.f32N/A
lift-+.f32N/A
lower-log1p.f3299.8
Applied rewrites99.8%
(FPCore (x s) :precision binary32 (/ 1.0 (fma (exp (/ (* x 1.5) (* s -2.0))) (exp (- (* 0.25 (/ x s)))) 1.0)))
float code(float x, float s) {
return 1.0f / fmaf(expf(((x * 1.5f) / (s * -2.0f))), expf(-(0.25f * (x / s))), 1.0f);
}
function code(x, s) return Float32(Float32(1.0) / fma(exp(Float32(Float32(x * Float32(1.5)) / Float32(s * Float32(-2.0)))), exp(Float32(-Float32(Float32(0.25) * Float32(x / s)))), Float32(1.0))) end
\begin{array}{l}
\\
\frac{1}{\mathsf{fma}\left(e^{\frac{x \cdot 1.5}{s \cdot -2}}, e^{-0.25 \cdot \frac{x}{s}}, 1\right)}
\end{array}
Initial program 99.7%
lift-neg.f32N/A
lift-/.f32N/A
*-lft-identityN/A
exp-prodN/A
lower-pow.f32N/A
exp-1-eN/A
lower-E.f3299.7
Applied rewrites99.7%
lift-E.f32N/A
lift-neg.f32N/A
lift-/.f32N/A
lift-pow.f32N/A
+-commutativeN/A
lift-pow.f32N/A
sqr-powN/A
pow-prod-downN/A
lift-E.f32N/A
add-sqr-sqrtN/A
associate-*r*N/A
unpow-prod-downN/A
lower-fma.f32N/A
Applied rewrites99.7%
Applied rewrites99.7%
Final simplification99.7%
(FPCore (x s) :precision binary32 (/ 1.0 (+ 1.0 (pow E (/ (- x) s)))))
float code(float x, float s) {
return 1.0f / (1.0f + powf(((float) M_E), (-x / s)));
}
function code(x, s) return Float32(Float32(1.0) / Float32(Float32(1.0) + (Float32(exp(1)) ^ Float32(Float32(-x) / s)))) end
function tmp = code(x, s) tmp = single(1.0) / (single(1.0) + (single(2.71828182845904523536) ^ (-x / s))); end
\begin{array}{l}
\\
\frac{1}{1 + {e}^{\left(\frac{-x}{s}\right)}}
\end{array}
Initial program 99.7%
lift-neg.f32N/A
lift-/.f32N/A
*-lft-identityN/A
exp-prodN/A
lower-pow.f32N/A
exp-1-eN/A
lower-E.f3299.7
Applied rewrites99.7%
(FPCore (x s) :precision binary32 (/ 1.0 (+ (exp (/ (- x) s)) 1.0)))
float code(float x, float s) {
return 1.0f / (expf((-x / s)) + 1.0f);
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
code = 1.0e0 / (exp((-x / s)) + 1.0e0)
end function
function code(x, s) return Float32(Float32(1.0) / Float32(exp(Float32(Float32(-x) / s)) + Float32(1.0))) end
function tmp = code(x, s) tmp = single(1.0) / (exp((-x / s)) + single(1.0)); end
\begin{array}{l}
\\
\frac{1}{e^{\frac{-x}{s}} + 1}
\end{array}
Initial program 99.7%
Final simplification99.7%
(FPCore (x s)
:precision binary32
(if (<= (/ (- x) s) -2.0)
0.5
(/
1.0
(+
1.0
(fma
x
(fma
(/ 1.0 s)
(/ (fma (/ x s) -0.16666666666666666 0.5) (/ s x))
(/ -1.0 s))
1.0)))))
float code(float x, float s) {
float tmp;
if ((-x / s) <= -2.0f) {
tmp = 0.5f;
} else {
tmp = 1.0f / (1.0f + fmaf(x, fmaf((1.0f / s), (fmaf((x / s), -0.16666666666666666f, 0.5f) / (s / x)), (-1.0f / s)), 1.0f));
}
return tmp;
}
function code(x, s) tmp = Float32(0.0) if (Float32(Float32(-x) / s) <= Float32(-2.0)) tmp = Float32(0.5); else tmp = Float32(Float32(1.0) / Float32(Float32(1.0) + fma(x, fma(Float32(Float32(1.0) / s), Float32(fma(Float32(x / s), Float32(-0.16666666666666666), Float32(0.5)) / Float32(s / x)), Float32(Float32(-1.0) / s)), Float32(1.0)))); end return tmp end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;\frac{-x}{s} \leq -2:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{1 + \mathsf{fma}\left(x, \mathsf{fma}\left(\frac{1}{s}, \frac{\mathsf{fma}\left(\frac{x}{s}, -0.16666666666666666, 0.5\right)}{\frac{s}{x}}, \frac{-1}{s}\right), 1\right)}\\
\end{array}
\end{array}
if (/.f32 (neg.f32 x) s) < -2Initial program 99.9%
Taylor expanded in x around 0
Applied rewrites28.1%
if -2 < (/.f32 (neg.f32 x) s) Initial program 99.6%
Taylor expanded in x around 0
+-commutativeN/A
lower-fma.f32N/A
Applied rewrites86.0%
lift-*.f32N/A
lift-/.f32N/A
lift-/.f32N/A
lift-fma.f32N/A
lift-/.f32N/A
lift-/.f32N/A
clear-numN/A
associate-*l/N/A
lift-*.f32N/A
associate-/l*N/A
times-fracN/A
lower-fma.f32N/A
lower-/.f32N/A
lower-/.f32N/A
lift-fma.f32N/A
*-commutativeN/A
lower-fma.f32N/A
lower-/.f3290.0
Applied rewrites90.0%
(FPCore (x s)
:precision binary32
(if (<= (/ (- x) s) -2.0)
0.5
(/
1.0
(+
1.0
(fma
x
(fma (/ (fma (/ x s) -0.16666666666666666 0.5) s) (/ x s) (/ -1.0 s))
1.0)))))
float code(float x, float s) {
float tmp;
if ((-x / s) <= -2.0f) {
tmp = 0.5f;
} else {
tmp = 1.0f / (1.0f + fmaf(x, fmaf((fmaf((x / s), -0.16666666666666666f, 0.5f) / s), (x / s), (-1.0f / s)), 1.0f));
}
return tmp;
}
function code(x, s) tmp = Float32(0.0) if (Float32(Float32(-x) / s) <= Float32(-2.0)) tmp = Float32(0.5); else tmp = Float32(Float32(1.0) / Float32(Float32(1.0) + fma(x, fma(Float32(fma(Float32(x / s), Float32(-0.16666666666666666), Float32(0.5)) / s), Float32(x / s), Float32(Float32(-1.0) / s)), Float32(1.0)))); end return tmp end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;\frac{-x}{s} \leq -2:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{1 + \mathsf{fma}\left(x, \mathsf{fma}\left(\frac{\mathsf{fma}\left(\frac{x}{s}, -0.16666666666666666, 0.5\right)}{s}, \frac{x}{s}, \frac{-1}{s}\right), 1\right)}\\
\end{array}
\end{array}
if (/.f32 (neg.f32 x) s) < -2Initial program 99.9%
Taylor expanded in x around 0
Applied rewrites28.1%
if -2 < (/.f32 (neg.f32 x) s) Initial program 99.6%
Taylor expanded in x around 0
+-commutativeN/A
lower-fma.f32N/A
Applied rewrites86.0%
lift-*.f32N/A
lift-/.f32N/A
lift-/.f32N/A
lift-fma.f32N/A
lift-/.f32N/A
*-commutativeN/A
lift-/.f32N/A
associate-*r/N/A
lift-*.f32N/A
times-fracN/A
lift-/.f32N/A
lower-fma.f32N/A
lower-/.f3290.0
lift-fma.f32N/A
*-commutativeN/A
lower-fma.f3290.0
Applied rewrites90.0%
(FPCore (x s)
:precision binary32
(if (<= (- x) 1.0000000195414814e-24)
0.5
(/
1.0
(+
1.0
(fma
x
(/
(fma x (* x -0.16666666666666666) (* s (fma 0.5 x (- s))))
(* s (* s s)))
1.0)))))
float code(float x, float s) {
float tmp;
if (-x <= 1.0000000195414814e-24f) {
tmp = 0.5f;
} else {
tmp = 1.0f / (1.0f + fmaf(x, (fmaf(x, (x * -0.16666666666666666f), (s * fmaf(0.5f, x, -s))) / (s * (s * s))), 1.0f));
}
return tmp;
}
function code(x, s) tmp = Float32(0.0) if (Float32(-x) <= Float32(1.0000000195414814e-24)) tmp = Float32(0.5); else tmp = Float32(Float32(1.0) / Float32(Float32(1.0) + fma(x, Float32(fma(x, Float32(x * Float32(-0.16666666666666666)), Float32(s * fma(Float32(0.5), x, Float32(-s)))) / Float32(s * Float32(s * s))), Float32(1.0)))); end return tmp end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;-x \leq 1.0000000195414814 \cdot 10^{-24}:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{1 + \mathsf{fma}\left(x, \frac{\mathsf{fma}\left(x, x \cdot -0.16666666666666666, s \cdot \mathsf{fma}\left(0.5, x, -s\right)\right)}{s \cdot \left(s \cdot s\right)}, 1\right)}\\
\end{array}
\end{array}
if (neg.f32 x) < 1.00000002e-24Initial program 99.8%
Taylor expanded in x around 0
Applied rewrites47.4%
if 1.00000002e-24 < (neg.f32 x) Initial program 99.5%
Taylor expanded in x around 0
+-commutativeN/A
lower-fma.f32N/A
Applied rewrites87.4%
Taylor expanded in s around 0
lower-/.f32N/A
*-commutativeN/A
unpow2N/A
associate-*r*N/A
metadata-evalN/A
distribute-rgt-outN/A
lower-fma.f32N/A
distribute-rgt-outN/A
metadata-evalN/A
lower-*.f32N/A
lower-*.f32N/A
+-commutativeN/A
lower-fma.f32N/A
mul-1-negN/A
lower-neg.f32N/A
cube-multN/A
unpow2N/A
lower-*.f32N/A
unpow2N/A
lower-*.f3290.9
Applied rewrites90.9%
(FPCore (x s)
:precision binary32
(if (<= (/ (- x) s) 50.0)
0.5
(/
1.0
(+ 1.0 (fma x (* x (* x (/ -0.16666666666666666 (* s (* s s))))) 1.0)))))
float code(float x, float s) {
float tmp;
if ((-x / s) <= 50.0f) {
tmp = 0.5f;
} else {
tmp = 1.0f / (1.0f + fmaf(x, (x * (x * (-0.16666666666666666f / (s * (s * s))))), 1.0f));
}
return tmp;
}
function code(x, s) tmp = Float32(0.0) if (Float32(Float32(-x) / s) <= Float32(50.0)) tmp = Float32(0.5); else tmp = Float32(Float32(1.0) / Float32(Float32(1.0) + fma(x, Float32(x * Float32(x * Float32(Float32(-0.16666666666666666) / Float32(s * Float32(s * s))))), Float32(1.0)))); end return tmp end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;\frac{-x}{s} \leq 50:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{1 + \mathsf{fma}\left(x, x \cdot \left(x \cdot \frac{-0.16666666666666666}{s \cdot \left(s \cdot s\right)}\right), 1\right)}\\
\end{array}
\end{array}
if (/.f32 (neg.f32 x) s) < 50Initial program 99.7%
Taylor expanded in x around 0
Applied rewrites50.6%
if 50 < (/.f32 (neg.f32 x) s) Initial program 99.7%
Taylor expanded in x around 0
+-commutativeN/A
lower-fma.f32N/A
Applied rewrites88.9%
Taylor expanded in x around inf
*-commutativeN/A
unpow2N/A
associate-/l*N/A
associate-*r*N/A
*-commutativeN/A
lower-*.f32N/A
associate-*r/N/A
*-commutativeN/A
associate-/l*N/A
metadata-evalN/A
distribute-neg-fracN/A
metadata-evalN/A
associate-*r/N/A
lower-*.f32N/A
associate-*r/N/A
metadata-evalN/A
distribute-neg-fracN/A
metadata-evalN/A
lower-/.f32N/A
cube-multN/A
unpow2N/A
lower-*.f32N/A
unpow2N/A
lower-*.f3294.0
Applied rewrites94.0%
(FPCore (x s) :precision binary32 (if (<= (/ (- x) s) 50.0) 0.5 (/ 1.0 (* x (* x (/ 0.5 (* s s)))))))
float code(float x, float s) {
float tmp;
if ((-x / s) <= 50.0f) {
tmp = 0.5f;
} else {
tmp = 1.0f / (x * (x * (0.5f / (s * s))));
}
return tmp;
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
real(4) :: tmp
if ((-x / s) <= 50.0e0) then
tmp = 0.5e0
else
tmp = 1.0e0 / (x * (x * (0.5e0 / (s * s))))
end if
code = tmp
end function
function code(x, s) tmp = Float32(0.0) if (Float32(Float32(-x) / s) <= Float32(50.0)) tmp = Float32(0.5); else tmp = Float32(Float32(1.0) / Float32(x * Float32(x * Float32(Float32(0.5) / Float32(s * s))))); end return tmp end
function tmp_2 = code(x, s) tmp = single(0.0); if ((-x / s) <= single(50.0)) tmp = single(0.5); else tmp = single(1.0) / (x * (x * (single(0.5) / (s * s)))); end tmp_2 = tmp; end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;\frac{-x}{s} \leq 50:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{x \cdot \left(x \cdot \frac{0.5}{s \cdot s}\right)}\\
\end{array}
\end{array}
if (/.f32 (neg.f32 x) s) < 50Initial program 99.7%
Taylor expanded in x around 0
Applied rewrites50.6%
if 50 < (/.f32 (neg.f32 x) s) Initial program 99.7%
Taylor expanded in x around 0
+-commutativeN/A
sub-negN/A
distribute-lft-inN/A
associate-*r*N/A
*-commutativeN/A
associate-/l*N/A
unpow2N/A
times-fracN/A
distribute-neg-fracN/A
metadata-evalN/A
associate-/l*N/A
*-commutativeN/A
associate-*r/N/A
distribute-rgt-outN/A
lower-fma.f32N/A
Applied rewrites76.0%
Taylor expanded in x around inf
associate-*r/N/A
lower-/.f32N/A
lower-*.f3276.0
Applied rewrites76.0%
Taylor expanded in x around inf
associate-*r/N/A
associate-*l/N/A
metadata-evalN/A
associate-*r/N/A
unpow2N/A
associate-*r*N/A
lower-*.f32N/A
lower-*.f32N/A
associate-*r/N/A
metadata-evalN/A
lower-/.f32N/A
unpow2N/A
lower-*.f3287.9
Applied rewrites87.9%
Final simplification63.6%
(FPCore (x s) :precision binary32 (if (<= (/ (- x) s) 2.0) 0.5 (/ (* s (* s 2.0)) (* x x))))
float code(float x, float s) {
float tmp;
if ((-x / s) <= 2.0f) {
tmp = 0.5f;
} else {
tmp = (s * (s * 2.0f)) / (x * x);
}
return tmp;
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
real(4) :: tmp
if ((-x / s) <= 2.0e0) then
tmp = 0.5e0
else
tmp = (s * (s * 2.0e0)) / (x * x)
end if
code = tmp
end function
function code(x, s) tmp = Float32(0.0) if (Float32(Float32(-x) / s) <= Float32(2.0)) tmp = Float32(0.5); else tmp = Float32(Float32(s * Float32(s * Float32(2.0))) / Float32(x * x)); end return tmp end
function tmp_2 = code(x, s) tmp = single(0.0); if ((-x / s) <= single(2.0)) tmp = single(0.5); else tmp = (s * (s * single(2.0))) / (x * x); end tmp_2 = tmp; end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;\frac{-x}{s} \leq 2:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{s \cdot \left(s \cdot 2\right)}{x \cdot x}\\
\end{array}
\end{array}
if (/.f32 (neg.f32 x) s) < 2Initial program 99.8%
Taylor expanded in x around 0
Applied rewrites51.2%
if 2 < (/.f32 (neg.f32 x) s) Initial program 99.5%
Taylor expanded in x around 0
+-commutativeN/A
sub-negN/A
distribute-lft-inN/A
associate-*r*N/A
*-commutativeN/A
associate-/l*N/A
unpow2N/A
times-fracN/A
distribute-neg-fracN/A
metadata-evalN/A
associate-/l*N/A
*-commutativeN/A
associate-*r/N/A
distribute-rgt-outN/A
lower-fma.f32N/A
Applied rewrites74.2%
Taylor expanded in x around inf
associate-*r/N/A
lower-/.f32N/A
unpow2N/A
associate-*r*N/A
*-commutativeN/A
lower-*.f32N/A
*-commutativeN/A
lower-*.f32N/A
unpow2N/A
lower-*.f3282.3
Applied rewrites82.3%
(FPCore (x s) :precision binary32 (if (<= (/ (- x) s) -2.0) 0.5 (/ 1.0 (- 2.0 (/ x s)))))
float code(float x, float s) {
float tmp;
if ((-x / s) <= -2.0f) {
tmp = 0.5f;
} else {
tmp = 1.0f / (2.0f - (x / s));
}
return tmp;
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
real(4) :: tmp
if ((-x / s) <= (-2.0e0)) then
tmp = 0.5e0
else
tmp = 1.0e0 / (2.0e0 - (x / s))
end if
code = tmp
end function
function code(x, s) tmp = Float32(0.0) if (Float32(Float32(-x) / s) <= Float32(-2.0)) tmp = Float32(0.5); else tmp = Float32(Float32(1.0) / Float32(Float32(2.0) - Float32(x / s))); end return tmp end
function tmp_2 = code(x, s) tmp = single(0.0); if ((-x / s) <= single(-2.0)) tmp = single(0.5); else tmp = single(1.0) / (single(2.0) - (x / s)); end tmp_2 = tmp; end
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;\frac{-x}{s} \leq -2:\\
\;\;\;\;0.5\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{2 - \frac{x}{s}}\\
\end{array}
\end{array}
if (/.f32 (neg.f32 x) s) < -2Initial program 99.9%
Taylor expanded in x around 0
Applied rewrites28.1%
if -2 < (/.f32 (neg.f32 x) s) Initial program 99.6%
Taylor expanded in x around 0
mul-1-negN/A
unsub-negN/A
lower--.f32N/A
lower-/.f3265.0
Applied rewrites65.0%
(FPCore (x s) :precision binary32 0.5)
float code(float x, float s) {
return 0.5f;
}
real(4) function code(x, s)
real(4), intent (in) :: x
real(4), intent (in) :: s
code = 0.5e0
end function
function code(x, s) return Float32(0.5) end
function tmp = code(x, s) tmp = single(0.5); end
\begin{array}{l}
\\
0.5
\end{array}
Initial program 99.7%
Taylor expanded in x around 0
Applied rewrites35.2%
herbie shell --seed 2024220
(FPCore (x s)
:name "Logistic function"
:precision binary32
:pre (and (<= 0.0 s) (<= s 1.0651631))
(/ 1.0 (+ 1.0 (exp (/ (- x) s)))))