(FPCore (x y) :precision binary64 (log (/ (exp (+ x y)) (+ (exp x) (exp y)))))
double code(double x, double y) { return log((exp((x + y)) / (exp(x) + exp(y)))); }
real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = log((exp((x + y)) / (exp(x) + exp(y)))) end function
public static double code(double x, double y) { return Math.log((Math.exp((x + y)) / (Math.exp(x) + Math.exp(y)))); }
def code(x, y): return math.log((math.exp((x + y)) / (math.exp(x) + math.exp(y))))
function code(x, y) return log(Float64(exp(Float64(x + y)) / Float64(exp(x) + exp(y)))) end
function tmp = code(x, y) tmp = log((exp((x + y)) / (exp(x) + exp(y)))); end
code[x_, y_] := N[Log[N[(N[Exp[N[(x + y), $MachinePrecision]], $MachinePrecision] / N[(N[Exp[x], $MachinePrecision] + N[Exp[y], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \log \left(\frac{e^{x + y}}{e^{x} + e^{y}}\right) \end{array}
Sampling outcomes in binary64 precision:
Herbie found 10 alternatives:
Alternative | Accuracy | Speedup |
---|
(FPCore (x y) :precision binary64 (log (/ (exp (+ x y)) (+ (exp x) (exp y)))))
double code(double x, double y) { return log((exp((x + y)) / (exp(x) + exp(y)))); }
real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = log((exp((x + y)) / (exp(x) + exp(y)))) end function
public static double code(double x, double y) { return Math.log((Math.exp((x + y)) / (Math.exp(x) + Math.exp(y)))); }
def code(x, y): return math.log((math.exp((x + y)) / (math.exp(x) + math.exp(y))))
function code(x, y) return log(Float64(exp(Float64(x + y)) / Float64(exp(x) + exp(y)))) end
function tmp = code(x, y) tmp = log((exp((x + y)) / (exp(x) + exp(y)))); end
code[x_, y_] := N[Log[N[(N[Exp[N[(x + y), $MachinePrecision]], $MachinePrecision] / N[(N[Exp[x], $MachinePrecision] + N[Exp[y], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} \\ \log \left(\frac{e^{x + y}}{e^{x} + e^{y}}\right) \end{array}
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (if (<= (/ (exp (+ x y)) (+ (exp x) (exp y))) 0.49999999999999994) (- x (log1p (exp x))) (- y (log1p (exp y)))))
assert(x < y); double code(double x, double y) { double tmp; if ((exp((x + y)) / (exp(x) + exp(y))) <= 0.49999999999999994) { tmp = x - log1p(exp(x)); } else { tmp = y - log1p(exp(y)); } return tmp; }
assert x < y; public static double code(double x, double y) { double tmp; if ((Math.exp((x + y)) / (Math.exp(x) + Math.exp(y))) <= 0.49999999999999994) { tmp = x - Math.log1p(Math.exp(x)); } else { tmp = y - Math.log1p(Math.exp(y)); } return tmp; }
[x, y] = sort([x, y]) def code(x, y): tmp = 0 if (math.exp((x + y)) / (math.exp(x) + math.exp(y))) <= 0.49999999999999994: tmp = x - math.log1p(math.exp(x)) else: tmp = y - math.log1p(math.exp(y)) return tmp
x, y = sort([x, y]) function code(x, y) tmp = 0.0 if (Float64(exp(Float64(x + y)) / Float64(exp(x) + exp(y))) <= 0.49999999999999994) tmp = Float64(x - log1p(exp(x))); else tmp = Float64(y - log1p(exp(y))); end return tmp end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := If[LessEqual[N[(N[Exp[N[(x + y), $MachinePrecision]], $MachinePrecision] / N[(N[Exp[x], $MachinePrecision] + N[Exp[y], $MachinePrecision]), $MachinePrecision]), $MachinePrecision], 0.49999999999999994], N[(x - N[Log[1 + N[Exp[x], $MachinePrecision]], $MachinePrecision]), $MachinePrecision], N[(y - N[Log[1 + N[Exp[y], $MachinePrecision]], $MachinePrecision]), $MachinePrecision]]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \begin{array}{l} \mathbf{if}\;\frac{e^{x + y}}{e^{x} + e^{y}} \leq 0.49999999999999994:\\ \;\;\;\;x - \mathsf{log1p}\left(e^{x}\right)\\ \mathbf{else}:\\ \;\;\;\;y - \mathsf{log1p}\left(e^{y}\right)\\ \end{array} \end{array}
if (/.f64 (exp.f64 (+.f64 x y)) (+.f64 (exp.f64 x) (exp.f64 y))) < 0.499999999999999944
Initial program 99.3%
lift-log.f64
N/A
lift-/.f64
N/A
frac-2neg
N/A
neg-mul-1
N/A
associate-/r*
N/A
log-div
N/A
lower--.f64
N/A
lower-log.f64
N/A
lower-/.f64
N/A
lower-neg.f64
N/A
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
N/A
lower-log.f64
99.4
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
99.4
Applied rewrites99.4%
Taylor expanded in y around 0
lower--.f64
N/A
lower-log1p.f64
N/A
lower-exp.f64
59.4
Applied rewrites59.4%
if 0.499999999999999944 < (/.f64 (exp.f64 (+.f64 x y)) (+.f64 (exp.f64 x) (exp.f64 y)))
Initial program 100.0%
lift-log.f64
N/A
lift-/.f64
N/A
frac-2neg
N/A
neg-mul-1
N/A
associate-/r*
N/A
log-div
N/A
lower--.f64
N/A
lower-log.f64
N/A
lower-/.f64
N/A
lower-neg.f64
N/A
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
N/A
lower-log.f64
100.0
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
100.0
Applied rewrites100.0%
Taylor expanded in x around 0
lower--.f64
N/A
lower-log1p.f64
N/A
lower-exp.f64
98.8
Applied rewrites98.8%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (log (* (pow (+ (exp y) (exp x)) -1.0) (exp (+ y x)))))
assert(x < y); double code(double x, double y) { return log((pow((exp(y) + exp(x)), -1.0) * exp((y + x)))); }
NOTE: x and y should be sorted in increasing order before calling this function. real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = log((((exp(y) + exp(x)) ** (-1.0d0)) * exp((y + x)))) end function
assert x < y; public static double code(double x, double y) { return Math.log((Math.pow((Math.exp(y) + Math.exp(x)), -1.0) * Math.exp((y + x)))); }
[x, y] = sort([x, y]) def code(x, y): return math.log((math.pow((math.exp(y) + math.exp(x)), -1.0) * math.exp((y + x))))
x, y = sort([x, y]) function code(x, y) return log(Float64((Float64(exp(y) + exp(x)) ^ -1.0) * exp(Float64(y + x)))) end
x, y = num2cell(sort([x, y])){:} function tmp = code(x, y) tmp = log((((exp(y) + exp(x)) ^ -1.0) * exp((y + x)))); end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[Log[N[(N[Power[N[(N[Exp[y], $MachinePrecision] + N[Exp[x], $MachinePrecision]), $MachinePrecision], -1.0], $MachinePrecision] * N[Exp[N[(y + x), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \log \left({\left(e^{y} + e^{x}\right)}^{-1} \cdot e^{y + x}\right) \end{array}
Initial program 99.9%
lift-/.f64
N/A
clear-num
N/A
frac-2neg
N/A
associate-/r/
N/A
lower-*.f64
N/A
neg-mul-1
N/A
associate-/r*
N/A
metadata-eval
N/A
lower-/.f64
N/A
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
N/A
lower-neg.f64
99.9
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
99.9
Applied rewrites99.9%
Final simplification99.9%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (- (log (/ (+ (exp x) (exp y)) (exp (+ x y))))))
assert(x < y); double code(double x, double y) { return -log(((exp(x) + exp(y)) / exp((x + y)))); }
NOTE: x and y should be sorted in increasing order before calling this function. real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = -log(((exp(x) + exp(y)) / exp((x + y)))) end function
assert x < y; public static double code(double x, double y) { return -Math.log(((Math.exp(x) + Math.exp(y)) / Math.exp((x + y)))); }
[x, y] = sort([x, y]) def code(x, y): return -math.log(((math.exp(x) + math.exp(y)) / math.exp((x + y))))
x, y = sort([x, y]) function code(x, y) return Float64(-log(Float64(Float64(exp(x) + exp(y)) / exp(Float64(x + y))))) end
x, y = num2cell(sort([x, y])){:} function tmp = code(x, y) tmp = -log(((exp(x) + exp(y)) / exp((x + y)))); end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := (-N[Log[N[(N[(N[Exp[x], $MachinePrecision] + N[Exp[y], $MachinePrecision]), $MachinePrecision] / N[Exp[N[(x + y), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]], $MachinePrecision])
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ -\log \left(\frac{e^{x} + e^{y}}{e^{x + y}}\right) \end{array}
Initial program 99.9%
lift-log.f64
N/A
lift-/.f64
N/A
frac-2neg
N/A
neg-mul-1
N/A
associate-/r*
N/A
log-div
N/A
lower--.f64
N/A
lower-log.f64
N/A
lower-/.f64
N/A
lower-neg.f64
N/A
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
N/A
lower-log.f64
99.9
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
99.9
Applied rewrites99.9%
lift--.f64
N/A
lift-log.f64
N/A
lift-/.f64
N/A
lift-neg.f64
N/A
metadata-eval
N/A
frac-2neg
N/A
/-rgt-identity
N/A
lift-log.f64
N/A
diff-log
N/A
lift-exp.f64
N/A
lift-+.f64
N/A
+-commutative
N/A
lift-+.f64
N/A
+-commutative
N/A
lift-exp.f64
N/A
lift-exp.f64
N/A
clear-num
N/A
Applied rewrites99.9%
Final simplification99.9%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (log (/ (exp (+ x y)) (+ (exp x) (exp y)))))
assert(x < y); double code(double x, double y) { return log((exp((x + y)) / (exp(x) + exp(y)))); }
NOTE: x and y should be sorted in increasing order before calling this function. real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = log((exp((x + y)) / (exp(x) + exp(y)))) end function
assert x < y; public static double code(double x, double y) { return Math.log((Math.exp((x + y)) / (Math.exp(x) + Math.exp(y)))); }
[x, y] = sort([x, y]) def code(x, y): return math.log((math.exp((x + y)) / (math.exp(x) + math.exp(y))))
x, y = sort([x, y]) function code(x, y) return log(Float64(exp(Float64(x + y)) / Float64(exp(x) + exp(y)))) end
x, y = num2cell(sort([x, y])){:} function tmp = code(x, y) tmp = log((exp((x + y)) / (exp(x) + exp(y)))); end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[Log[N[(N[Exp[N[(x + y), $MachinePrecision]], $MachinePrecision] / N[(N[Exp[x], $MachinePrecision] + N[Exp[y], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \log \left(\frac{e^{x + y}}{e^{x} + e^{y}}\right) \end{array}
Initial program 99.9%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (- (+ y x) (log (+ (exp y) (exp x)))))
assert(x < y); double code(double x, double y) { return (y + x) - log((exp(y) + exp(x))); }
NOTE: x and y should be sorted in increasing order before calling this function. real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = (y + x) - log((exp(y) + exp(x))) end function
assert x < y; public static double code(double x, double y) { return (y + x) - Math.log((Math.exp(y) + Math.exp(x))); }
[x, y] = sort([x, y]) def code(x, y): return (y + x) - math.log((math.exp(y) + math.exp(x)))
x, y = sort([x, y]) function code(x, y) return Float64(Float64(y + x) - log(Float64(exp(y) + exp(x)))) end
x, y = num2cell(sort([x, y])){:} function tmp = code(x, y) tmp = (y + x) - log((exp(y) + exp(x))); end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[(N[(y + x), $MachinePrecision] - N[Log[N[(N[Exp[y], $MachinePrecision] + N[Exp[x], $MachinePrecision]), $MachinePrecision]], $MachinePrecision]), $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \left(y + x\right) - \log \left(e^{y} + e^{x}\right) \end{array}
Initial program 99.9%
lift-log.f64
N/A
lift-/.f64
N/A
log-div
N/A
lower--.f64
N/A
lift-exp.f64
N/A
rem-log-exp
N/A
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
N/A
lower-log.f64
99.9
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
99.9
Applied rewrites99.9%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (if (<= x -1.1e-16) (- x (log1p (exp x))) (log (fma (fma (fma 0.0020833333333333333 (* y y) -0.020833333333333332) (* y y) 0.25) y 0.5))))
assert(x < y); double code(double x, double y) { double tmp; if (x <= -1.1e-16) { tmp = x - log1p(exp(x)); } else { tmp = log(fma(fma(fma(0.0020833333333333333, (y * y), -0.020833333333333332), (y * y), 0.25), y, 0.5)); } return tmp; }
x, y = sort([x, y]) function code(x, y) tmp = 0.0 if (x <= -1.1e-16) tmp = Float64(x - log1p(exp(x))); else tmp = log(fma(fma(fma(0.0020833333333333333, Float64(y * y), -0.020833333333333332), Float64(y * y), 0.25), y, 0.5)); end return tmp end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := If[LessEqual[x, -1.1e-16], N[(x - N[Log[1 + N[Exp[x], $MachinePrecision]], $MachinePrecision]), $MachinePrecision], N[Log[N[(N[(N[(0.0020833333333333333 * N[(y * y), $MachinePrecision] + -0.020833333333333332), $MachinePrecision] * N[(y * y), $MachinePrecision] + 0.25), $MachinePrecision] * y + 0.5), $MachinePrecision]], $MachinePrecision]]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \begin{array}{l} \mathbf{if}\;x \leq -1.1 \cdot 10^{-16}:\\ \;\;\;\;x - \mathsf{log1p}\left(e^{x}\right)\\ \mathbf{else}:\\ \;\;\;\;\log \left(\mathsf{fma}\left(\mathsf{fma}\left(\mathsf{fma}\left(0.0020833333333333333, y \cdot y, -0.020833333333333332\right), y \cdot y, 0.25\right), y, 0.5\right)\right)\\ \end{array} \end{array}
if x < -1.1e-16
Initial program 99.2%
lift-log.f64
N/A
lift-/.f64
N/A
frac-2neg
N/A
neg-mul-1
N/A
associate-/r*
N/A
log-div
N/A
lower--.f64
N/A
lower-log.f64
N/A
lower-/.f64
N/A
lower-neg.f64
N/A
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
N/A
lower-log.f64
99.2
lift-+.f64
N/A
+-commutative
N/A
lower-+.f64
99.2
Applied rewrites99.2%
Taylor expanded in y around 0
lower--.f64
N/A
lower-log1p.f64
N/A
lower-exp.f64
100.0
Applied rewrites100.0%
if -1.1e-16 < x
Initial program 99.9%
Taylor expanded in x around 0
lower-/.f64
N/A
lower-exp.f64
N/A
lower-+.f64
N/A
lower-exp.f64
98.8
Applied rewrites98.8%
Taylor expanded in y around 0
Applied rewrites97.8%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (log (fma (fma (fma 0.0020833333333333333 (* y y) -0.020833333333333332) (* y y) 0.25) y 0.5)))
assert(x < y); double code(double x, double y) { return log(fma(fma(fma(0.0020833333333333333, (y * y), -0.020833333333333332), (y * y), 0.25), y, 0.5)); }
x, y = sort([x, y]) function code(x, y) return log(fma(fma(fma(0.0020833333333333333, Float64(y * y), -0.020833333333333332), Float64(y * y), 0.25), y, 0.5)) end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[Log[N[(N[(N[(0.0020833333333333333 * N[(y * y), $MachinePrecision] + -0.020833333333333332), $MachinePrecision] * N[(y * y), $MachinePrecision] + 0.25), $MachinePrecision] * y + 0.5), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \log \left(\mathsf{fma}\left(\mathsf{fma}\left(\mathsf{fma}\left(0.0020833333333333333, y \cdot y, -0.020833333333333332\right), y \cdot y, 0.25\right), y, 0.5\right)\right) \end{array}
Initial program 99.9%
Taylor expanded in x around 0
lower-/.f64
N/A
lower-exp.f64
N/A
lower-+.f64
N/A
lower-exp.f64
98.2
Applied rewrites98.2%
Taylor expanded in y around 0
Applied rewrites97.3%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (log (fma (fma -0.020833333333333332 (* y y) 0.25) y 0.5)))
assert(x < y); double code(double x, double y) { return log(fma(fma(-0.020833333333333332, (y * y), 0.25), y, 0.5)); }
x, y = sort([x, y]) function code(x, y) return log(fma(fma(-0.020833333333333332, Float64(y * y), 0.25), y, 0.5)) end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[Log[N[(N[(-0.020833333333333332 * N[(y * y), $MachinePrecision] + 0.25), $MachinePrecision] * y + 0.5), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \log \left(\mathsf{fma}\left(\mathsf{fma}\left(-0.020833333333333332, y \cdot y, 0.25\right), y, 0.5\right)\right) \end{array}
Initial program 99.9%
Taylor expanded in x around 0
lower-/.f64
N/A
lower-exp.f64
N/A
lower-+.f64
N/A
lower-exp.f64
98.2
Applied rewrites98.2%
Taylor expanded in y around 0
Applied rewrites96.8%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (log (fma 0.25 y 0.5)))
assert(x < y); double code(double x, double y) { return log(fma(0.25, y, 0.5)); }
x, y = sort([x, y]) function code(x, y) return log(fma(0.25, y, 0.5)) end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[Log[N[(0.25 * y + 0.5), $MachinePrecision]], $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \log \left(\mathsf{fma}\left(0.25, y, 0.5\right)\right) \end{array}
Initial program 99.9%
Taylor expanded in x around 0
lower-/.f64
N/A
lower-exp.f64
N/A
lower-+.f64
N/A
lower-exp.f64
98.2
Applied rewrites98.2%
Taylor expanded in y around 0
Applied rewrites96.3%
NOTE: x and y should be sorted in increasing order before calling this function. (FPCore (x y) :precision binary64 (log 0.5))
assert(x < y); double code(double x, double y) { return log(0.5); }
NOTE: x and y should be sorted in increasing order before calling this function. real(8) function code(x, y) real(8), intent (in) :: x real(8), intent (in) :: y code = log(0.5d0) end function
assert x < y; public static double code(double x, double y) { return Math.log(0.5); }
[x, y] = sort([x, y]) def code(x, y): return math.log(0.5)
x, y = sort([x, y]) function code(x, y) return log(0.5) end
x, y = num2cell(sort([x, y])){:} function tmp = code(x, y) tmp = log(0.5); end
NOTE: x and y should be sorted in increasing order before calling this function. code[x_, y_] := N[Log[0.5], $MachinePrecision]
\begin{array}{l} [x, y] = \mathsf{sort}([x, y])\\ \\ \log 0.5 \end{array}
Initial program 99.9%
Taylor expanded in x around 0
lower-/.f64
N/A
lower-exp.f64
N/A
lower-+.f64
N/A
lower-exp.f64
98.2
Applied rewrites98.2%
Taylor expanded in y around 0
Applied rewrites93.7%
herbie shell --seed 1
(FPCore (x y)
:name "log(exp(x+y)/(exp(x)+exp(y)))"
:precision binary64
:pre (and (and (<= -2.0 x) (<= x 2.0)) (and (<= -2.0 y) (<= y 2.0)))
(log (/ (exp (+ x y)) (+ (exp x) (exp y)))))