
(FPCore (a b) :precision binary64 (/ (exp a) (+ (exp a) (exp b))))
double code(double a, double b) {
return exp(a) / (exp(a) + exp(b));
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = exp(a) / (exp(a) + exp(b))
end function
public static double code(double a, double b) {
return Math.exp(a) / (Math.exp(a) + Math.exp(b));
}
def code(a, b): return math.exp(a) / (math.exp(a) + math.exp(b))
function code(a, b) return Float64(exp(a) / Float64(exp(a) + exp(b))) end
function tmp = code(a, b) tmp = exp(a) / (exp(a) + exp(b)); end
code[a_, b_] := N[(N[Exp[a], $MachinePrecision] / N[(N[Exp[a], $MachinePrecision] + N[Exp[b], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{e^{a}}{e^{a} + e^{b}}
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 8 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (a b) :precision binary64 (/ (exp a) (+ (exp a) (exp b))))
double code(double a, double b) {
return exp(a) / (exp(a) + exp(b));
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = exp(a) / (exp(a) + exp(b))
end function
public static double code(double a, double b) {
return Math.exp(a) / (Math.exp(a) + Math.exp(b));
}
def code(a, b): return math.exp(a) / (math.exp(a) + math.exp(b))
function code(a, b) return Float64(exp(a) / Float64(exp(a) + exp(b))) end
function tmp = code(a, b) tmp = exp(a) / (exp(a) + exp(b)); end
code[a_, b_] := N[(N[Exp[a], $MachinePrecision] / N[(N[Exp[a], $MachinePrecision] + N[Exp[b], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{e^{a}}{e^{a} + e^{b}}
\end{array}
(FPCore (a b) :precision binary64 (/ (exp a) (+ (exp a) (exp b))))
double code(double a, double b) {
return exp(a) / (exp(a) + exp(b));
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = exp(a) / (exp(a) + exp(b))
end function
public static double code(double a, double b) {
return Math.exp(a) / (Math.exp(a) + Math.exp(b));
}
def code(a, b): return math.exp(a) / (math.exp(a) + math.exp(b))
function code(a, b) return Float64(exp(a) / Float64(exp(a) + exp(b))) end
function tmp = code(a, b) tmp = exp(a) / (exp(a) + exp(b)); end
code[a_, b_] := N[(N[Exp[a], $MachinePrecision] / N[(N[Exp[a], $MachinePrecision] + N[Exp[b], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{e^{a}}{e^{a} + e^{b}}
\end{array}
Initial program 100.0%
Final simplification100.0%
(FPCore (a b) :precision binary64 (if (<= (exp a) 0.999999999998) (/ (exp a) (+ (exp a) 1.0)) (/ 1.0 (+ (exp b) 1.0))))
double code(double a, double b) {
double tmp;
if (exp(a) <= 0.999999999998) {
tmp = exp(a) / (exp(a) + 1.0);
} else {
tmp = 1.0 / (exp(b) + 1.0);
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if (exp(a) <= 0.999999999998d0) then
tmp = exp(a) / (exp(a) + 1.0d0)
else
tmp = 1.0d0 / (exp(b) + 1.0d0)
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if (Math.exp(a) <= 0.999999999998) {
tmp = Math.exp(a) / (Math.exp(a) + 1.0);
} else {
tmp = 1.0 / (Math.exp(b) + 1.0);
}
return tmp;
}
def code(a, b): tmp = 0 if math.exp(a) <= 0.999999999998: tmp = math.exp(a) / (math.exp(a) + 1.0) else: tmp = 1.0 / (math.exp(b) + 1.0) return tmp
function code(a, b) tmp = 0.0 if (exp(a) <= 0.999999999998) tmp = Float64(exp(a) / Float64(exp(a) + 1.0)); else tmp = Float64(1.0 / Float64(exp(b) + 1.0)); end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if (exp(a) <= 0.999999999998) tmp = exp(a) / (exp(a) + 1.0); else tmp = 1.0 / (exp(b) + 1.0); end tmp_2 = tmp; end
code[a_, b_] := If[LessEqual[N[Exp[a], $MachinePrecision], 0.999999999998], N[(N[Exp[a], $MachinePrecision] / N[(N[Exp[a], $MachinePrecision] + 1.0), $MachinePrecision]), $MachinePrecision], N[(1.0 / N[(N[Exp[b], $MachinePrecision] + 1.0), $MachinePrecision]), $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;e^{a} \leq 0.999999999998:\\
\;\;\;\;\frac{e^{a}}{e^{a} + 1}\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{e^{b} + 1}\\
\end{array}
\end{array}
if (exp.f64 a) < 0.99999999999800004Initial program 100.0%
Taylor expanded in b around 0 98.8%
if 0.99999999999800004 < (exp.f64 a) Initial program 100.0%
Taylor expanded in a around 0 99.6%
Final simplification99.4%
(FPCore (a b)
:precision binary64
(if (<= a -480.0)
(/ (exp a) a)
(if (or (<= a -2.1e-300) (not (<= a 3.6e-286)))
(+ 0.5 (* a (+ 0.25 (* a 0.125))))
(* -0.020833333333333332 (pow a 3.0)))))
double code(double a, double b) {
double tmp;
if (a <= -480.0) {
tmp = exp(a) / a;
} else if ((a <= -2.1e-300) || !(a <= 3.6e-286)) {
tmp = 0.5 + (a * (0.25 + (a * 0.125)));
} else {
tmp = -0.020833333333333332 * pow(a, 3.0);
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if (a <= (-480.0d0)) then
tmp = exp(a) / a
else if ((a <= (-2.1d-300)) .or. (.not. (a <= 3.6d-286))) then
tmp = 0.5d0 + (a * (0.25d0 + (a * 0.125d0)))
else
tmp = (-0.020833333333333332d0) * (a ** 3.0d0)
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if (a <= -480.0) {
tmp = Math.exp(a) / a;
} else if ((a <= -2.1e-300) || !(a <= 3.6e-286)) {
tmp = 0.5 + (a * (0.25 + (a * 0.125)));
} else {
tmp = -0.020833333333333332 * Math.pow(a, 3.0);
}
return tmp;
}
def code(a, b): tmp = 0 if a <= -480.0: tmp = math.exp(a) / a elif (a <= -2.1e-300) or not (a <= 3.6e-286): tmp = 0.5 + (a * (0.25 + (a * 0.125))) else: tmp = -0.020833333333333332 * math.pow(a, 3.0) return tmp
function code(a, b) tmp = 0.0 if (a <= -480.0) tmp = Float64(exp(a) / a); elseif ((a <= -2.1e-300) || !(a <= 3.6e-286)) tmp = Float64(0.5 + Float64(a * Float64(0.25 + Float64(a * 0.125)))); else tmp = Float64(-0.020833333333333332 * (a ^ 3.0)); end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if (a <= -480.0) tmp = exp(a) / a; elseif ((a <= -2.1e-300) || ~((a <= 3.6e-286))) tmp = 0.5 + (a * (0.25 + (a * 0.125))); else tmp = -0.020833333333333332 * (a ^ 3.0); end tmp_2 = tmp; end
code[a_, b_] := If[LessEqual[a, -480.0], N[(N[Exp[a], $MachinePrecision] / a), $MachinePrecision], If[Or[LessEqual[a, -2.1e-300], N[Not[LessEqual[a, 3.6e-286]], $MachinePrecision]], N[(0.5 + N[(a * N[(0.25 + N[(a * 0.125), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision], N[(-0.020833333333333332 * N[Power[a, 3.0], $MachinePrecision]), $MachinePrecision]]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq -480:\\
\;\;\;\;\frac{e^{a}}{a}\\
\mathbf{elif}\;a \leq -2.1 \cdot 10^{-300} \lor \neg \left(a \leq 3.6 \cdot 10^{-286}\right):\\
\;\;\;\;0.5 + a \cdot \left(0.25 + a \cdot 0.125\right)\\
\mathbf{else}:\\
\;\;\;\;-0.020833333333333332 \cdot {a}^{3}\\
\end{array}
\end{array}
if a < -480Initial program 100.0%
Taylor expanded in b around 0 100.0%
Taylor expanded in a around 0 100.0%
+-commutative100.0%
Simplified100.0%
Taylor expanded in a around inf 100.0%
if -480 < a < -2.10000000000000004e-300 or 3.60000000000000013e-286 < a Initial program 100.0%
Taylor expanded in b around 0 59.8%
Taylor expanded in a around 0 59.2%
+-commutative59.2%
Simplified59.2%
Taylor expanded in a around 0 59.3%
+-commutative59.3%
unpow259.3%
associate-*r*59.3%
distribute-rgt-out59.3%
Simplified59.3%
if -2.10000000000000004e-300 < a < 3.60000000000000013e-286Initial program 100.0%
Taylor expanded in b around 0 27.9%
Taylor expanded in a around 0 27.9%
Taylor expanded in a around inf 62.7%
Final simplification69.5%
(FPCore (a b) :precision binary64 (if (<= a -2.9e+24) (/ (exp a) a) (/ 1.0 (+ (exp b) 1.0))))
double code(double a, double b) {
double tmp;
if (a <= -2.9e+24) {
tmp = exp(a) / a;
} else {
tmp = 1.0 / (exp(b) + 1.0);
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if (a <= (-2.9d+24)) then
tmp = exp(a) / a
else
tmp = 1.0d0 / (exp(b) + 1.0d0)
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if (a <= -2.9e+24) {
tmp = Math.exp(a) / a;
} else {
tmp = 1.0 / (Math.exp(b) + 1.0);
}
return tmp;
}
def code(a, b): tmp = 0 if a <= -2.9e+24: tmp = math.exp(a) / a else: tmp = 1.0 / (math.exp(b) + 1.0) return tmp
function code(a, b) tmp = 0.0 if (a <= -2.9e+24) tmp = Float64(exp(a) / a); else tmp = Float64(1.0 / Float64(exp(b) + 1.0)); end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if (a <= -2.9e+24) tmp = exp(a) / a; else tmp = 1.0 / (exp(b) + 1.0); end tmp_2 = tmp; end
code[a_, b_] := If[LessEqual[a, -2.9e+24], N[(N[Exp[a], $MachinePrecision] / a), $MachinePrecision], N[(1.0 / N[(N[Exp[b], $MachinePrecision] + 1.0), $MachinePrecision]), $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq -2.9 \cdot 10^{+24}:\\
\;\;\;\;\frac{e^{a}}{a}\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{e^{b} + 1}\\
\end{array}
\end{array}
if a < -2.89999999999999979e24Initial program 100.0%
Taylor expanded in b around 0 100.0%
Taylor expanded in a around 0 100.0%
+-commutative100.0%
Simplified100.0%
Taylor expanded in a around inf 100.0%
if -2.89999999999999979e24 < a Initial program 100.0%
Taylor expanded in a around 0 98.6%
Final simplification98.9%
(FPCore (a b) :precision binary64 (if (<= a -3.55e-12) (/ (exp a) (+ a 2.0)) (/ 1.0 (+ (exp b) 1.0))))
double code(double a, double b) {
double tmp;
if (a <= -3.55e-12) {
tmp = exp(a) / (a + 2.0);
} else {
tmp = 1.0 / (exp(b) + 1.0);
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if (a <= (-3.55d-12)) then
tmp = exp(a) / (a + 2.0d0)
else
tmp = 1.0d0 / (exp(b) + 1.0d0)
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if (a <= -3.55e-12) {
tmp = Math.exp(a) / (a + 2.0);
} else {
tmp = 1.0 / (Math.exp(b) + 1.0);
}
return tmp;
}
def code(a, b): tmp = 0 if a <= -3.55e-12: tmp = math.exp(a) / (a + 2.0) else: tmp = 1.0 / (math.exp(b) + 1.0) return tmp
function code(a, b) tmp = 0.0 if (a <= -3.55e-12) tmp = Float64(exp(a) / Float64(a + 2.0)); else tmp = Float64(1.0 / Float64(exp(b) + 1.0)); end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if (a <= -3.55e-12) tmp = exp(a) / (a + 2.0); else tmp = 1.0 / (exp(b) + 1.0); end tmp_2 = tmp; end
code[a_, b_] := If[LessEqual[a, -3.55e-12], N[(N[Exp[a], $MachinePrecision] / N[(a + 2.0), $MachinePrecision]), $MachinePrecision], N[(1.0 / N[(N[Exp[b], $MachinePrecision] + 1.0), $MachinePrecision]), $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq -3.55 \cdot 10^{-12}:\\
\;\;\;\;\frac{e^{a}}{a + 2}\\
\mathbf{else}:\\
\;\;\;\;\frac{1}{e^{b} + 1}\\
\end{array}
\end{array}
if a < -3.55e-12Initial program 100.0%
Taylor expanded in b around 0 98.8%
Taylor expanded in a around 0 97.2%
+-commutative97.2%
Simplified97.2%
if -3.55e-12 < a Initial program 100.0%
Taylor expanded in a around 0 99.6%
Final simplification98.9%
(FPCore (a b) :precision binary64 (if (<= a -420.0) (/ (exp a) a) (+ 0.5 (* a (+ 0.25 (* a 0.125))))))
double code(double a, double b) {
double tmp;
if (a <= -420.0) {
tmp = exp(a) / a;
} else {
tmp = 0.5 + (a * (0.25 + (a * 0.125)));
}
return tmp;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
real(8) :: tmp
if (a <= (-420.0d0)) then
tmp = exp(a) / a
else
tmp = 0.5d0 + (a * (0.25d0 + (a * 0.125d0)))
end if
code = tmp
end function
public static double code(double a, double b) {
double tmp;
if (a <= -420.0) {
tmp = Math.exp(a) / a;
} else {
tmp = 0.5 + (a * (0.25 + (a * 0.125)));
}
return tmp;
}
def code(a, b): tmp = 0 if a <= -420.0: tmp = math.exp(a) / a else: tmp = 0.5 + (a * (0.25 + (a * 0.125))) return tmp
function code(a, b) tmp = 0.0 if (a <= -420.0) tmp = Float64(exp(a) / a); else tmp = Float64(0.5 + Float64(a * Float64(0.25 + Float64(a * 0.125)))); end return tmp end
function tmp_2 = code(a, b) tmp = 0.0; if (a <= -420.0) tmp = exp(a) / a; else tmp = 0.5 + (a * (0.25 + (a * 0.125))); end tmp_2 = tmp; end
code[a_, b_] := If[LessEqual[a, -420.0], N[(N[Exp[a], $MachinePrecision] / a), $MachinePrecision], N[(0.5 + N[(a * N[(0.25 + N[(a * 0.125), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]]
\begin{array}{l}
\\
\begin{array}{l}
\mathbf{if}\;a \leq -420:\\
\;\;\;\;\frac{e^{a}}{a}\\
\mathbf{else}:\\
\;\;\;\;0.5 + a \cdot \left(0.25 + a \cdot 0.125\right)\\
\end{array}
\end{array}
if a < -420Initial program 100.0%
Taylor expanded in b around 0 100.0%
Taylor expanded in a around 0 100.0%
+-commutative100.0%
Simplified100.0%
Taylor expanded in a around inf 100.0%
if -420 < a Initial program 100.0%
Taylor expanded in b around 0 57.6%
Taylor expanded in a around 0 57.1%
+-commutative57.1%
Simplified57.1%
Taylor expanded in a around 0 57.1%
+-commutative57.1%
unpow257.1%
associate-*r*57.1%
distribute-rgt-out57.1%
Simplified57.1%
Final simplification67.7%
(FPCore (a b) :precision binary64 (+ 0.5 (* a 0.25)))
double code(double a, double b) {
return 0.5 + (a * 0.25);
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = 0.5d0 + (a * 0.25d0)
end function
public static double code(double a, double b) {
return 0.5 + (a * 0.25);
}
def code(a, b): return 0.5 + (a * 0.25)
function code(a, b) return Float64(0.5 + Float64(a * 0.25)) end
function tmp = code(a, b) tmp = 0.5 + (a * 0.25); end
code[a_, b_] := N[(0.5 + N[(a * 0.25), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
0.5 + a \cdot 0.25
\end{array}
Initial program 100.0%
Taylor expanded in b around 0 68.0%
Taylor expanded in a around 0 43.6%
*-commutative43.6%
Simplified43.6%
Final simplification43.6%
(FPCore (a b) :precision binary64 0.5)
double code(double a, double b) {
return 0.5;
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = 0.5d0
end function
public static double code(double a, double b) {
return 0.5;
}
def code(a, b): return 0.5
function code(a, b) return 0.5 end
function tmp = code(a, b) tmp = 0.5; end
code[a_, b_] := 0.5
\begin{array}{l}
\\
0.5
\end{array}
Initial program 100.0%
Taylor expanded in a around 0 81.9%
Taylor expanded in b around 0 43.2%
Final simplification43.2%
(FPCore (a b) :precision binary64 (/ 1.0 (+ 1.0 (exp (- b a)))))
double code(double a, double b) {
return 1.0 / (1.0 + exp((b - a)));
}
real(8) function code(a, b)
real(8), intent (in) :: a
real(8), intent (in) :: b
code = 1.0d0 / (1.0d0 + exp((b - a)))
end function
public static double code(double a, double b) {
return 1.0 / (1.0 + Math.exp((b - a)));
}
def code(a, b): return 1.0 / (1.0 + math.exp((b - a)))
function code(a, b) return Float64(1.0 / Float64(1.0 + exp(Float64(b - a)))) end
function tmp = code(a, b) tmp = 1.0 / (1.0 + exp((b - a))); end
code[a_, b_] := N[(1.0 / N[(1.0 + N[Exp[N[(b - a), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{1}{1 + e^{b - a}}
\end{array}
herbie shell --seed 2023330
(FPCore (a b)
:name "Quotient of sum of exps"
:precision binary64
:herbie-target
(/ 1.0 (+ 1.0 (exp (- b a))))
(/ (exp a) (+ (exp a) (exp b))))