
(FPCore (n) :precision binary64 (- (- (* (+ n 1.0) (log (+ n 1.0))) (* n (log n))) 1.0))
double code(double n) {
return (((n + 1.0) * log((n + 1.0))) - (n * log(n))) - 1.0;
}
real(8) function code(n)
real(8), intent (in) :: n
code = (((n + 1.0d0) * log((n + 1.0d0))) - (n * log(n))) - 1.0d0
end function
public static double code(double n) {
return (((n + 1.0) * Math.log((n + 1.0))) - (n * Math.log(n))) - 1.0;
}
def code(n): return (((n + 1.0) * math.log((n + 1.0))) - (n * math.log(n))) - 1.0
function code(n) return Float64(Float64(Float64(Float64(n + 1.0) * log(Float64(n + 1.0))) - Float64(n * log(n))) - 1.0) end
function tmp = code(n) tmp = (((n + 1.0) * log((n + 1.0))) - (n * log(n))) - 1.0; end
code[n_] := N[(N[(N[(N[(n + 1.0), $MachinePrecision] * N[Log[N[(n + 1.0), $MachinePrecision]], $MachinePrecision]), $MachinePrecision] - N[(n * N[Log[n], $MachinePrecision]), $MachinePrecision]), $MachinePrecision] - 1.0), $MachinePrecision]
\begin{array}{l}
\\
\left(\left(n + 1\right) \cdot \log \left(n + 1\right) - n \cdot \log n\right) - 1
\end{array}
Sampling outcomes in binary64 precision:
Herbie found 4 alternatives:
| Alternative | Accuracy | Speedup |
|---|
(FPCore (n) :precision binary64 (- (- (* (+ n 1.0) (log (+ n 1.0))) (* n (log n))) 1.0))
double code(double n) {
return (((n + 1.0) * log((n + 1.0))) - (n * log(n))) - 1.0;
}
real(8) function code(n)
real(8), intent (in) :: n
code = (((n + 1.0d0) * log((n + 1.0d0))) - (n * log(n))) - 1.0d0
end function
public static double code(double n) {
return (((n + 1.0) * Math.log((n + 1.0))) - (n * Math.log(n))) - 1.0;
}
def code(n): return (((n + 1.0) * math.log((n + 1.0))) - (n * math.log(n))) - 1.0
function code(n) return Float64(Float64(Float64(Float64(n + 1.0) * log(Float64(n + 1.0))) - Float64(n * log(n))) - 1.0) end
function tmp = code(n) tmp = (((n + 1.0) * log((n + 1.0))) - (n * log(n))) - 1.0; end
code[n_] := N[(N[(N[(N[(n + 1.0), $MachinePrecision] * N[Log[N[(n + 1.0), $MachinePrecision]], $MachinePrecision]), $MachinePrecision] - N[(n * N[Log[n], $MachinePrecision]), $MachinePrecision]), $MachinePrecision] - 1.0), $MachinePrecision]
\begin{array}{l}
\\
\left(\left(n + 1\right) \cdot \log \left(n + 1\right) - n \cdot \log n\right) - 1
\end{array}
(FPCore (n) :precision binary64 (log n))
double code(double n) {
return log(n);
}
real(8) function code(n)
real(8), intent (in) :: n
code = log(n)
end function
public static double code(double n) {
return Math.log(n);
}
def code(n): return math.log(n)
function code(n) return log(n) end
function tmp = code(n) tmp = log(n); end
code[n_] := N[Log[n], $MachinePrecision]
\begin{array}{l}
\\
\log n
\end{array}
Initial program 1.6%
sub-negN/A
+-commutativeN/A
sub-negN/A
+-commutativeN/A
associate-+r+N/A
unsub-negN/A
associate-+l-N/A
--lowering--.f64N/A
metadata-evalN/A
sub-negN/A
+-lowering-+.f64N/A
*-lowering-*.f64N/A
log-lowering-log.f64N/A
*-commutativeN/A
distribute-rgt-neg-inN/A
*-lowering-*.f64N/A
Simplified1.6%
Taylor expanded in n around inf
Simplified99.9%
Taylor expanded in n around 0
log-lowering-log.f64100.0%
Simplified100.0%
(FPCore (n) :precision binary64 (* (/ 0.25 n) (* (/ 1.0 n) (/ n 0.5))))
double code(double n) {
return (0.25 / n) * ((1.0 / n) * (n / 0.5));
}
real(8) function code(n)
real(8), intent (in) :: n
code = (0.25d0 / n) * ((1.0d0 / n) * (n / 0.5d0))
end function
public static double code(double n) {
return (0.25 / n) * ((1.0 / n) * (n / 0.5));
}
def code(n): return (0.25 / n) * ((1.0 / n) * (n / 0.5))
function code(n) return Float64(Float64(0.25 / n) * Float64(Float64(1.0 / n) * Float64(n / 0.5))) end
function tmp = code(n) tmp = (0.25 / n) * ((1.0 / n) * (n / 0.5)); end
code[n_] := N[(N[(0.25 / n), $MachinePrecision] * N[(N[(1.0 / n), $MachinePrecision] * N[(n / 0.5), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\frac{0.25}{n} \cdot \left(\frac{1}{n} \cdot \frac{n}{0.5}\right)
\end{array}
Initial program 1.6%
sub-negN/A
+-commutativeN/A
sub-negN/A
+-commutativeN/A
associate-+r+N/A
unsub-negN/A
associate-+l-N/A
--lowering--.f64N/A
metadata-evalN/A
sub-negN/A
+-lowering-+.f64N/A
*-lowering-*.f64N/A
log-lowering-log.f64N/A
*-commutativeN/A
distribute-rgt-neg-inN/A
*-lowering-*.f64N/A
Simplified1.6%
Taylor expanded in n around inf
associate-+r+N/A
distribute-rgt1-inN/A
metadata-evalN/A
mul0-lftN/A
+-lft-identityN/A
*-lowering-*.f64N/A
sub-negN/A
+-lowering-+.f64N/A
Simplified99.9%
Taylor expanded in n around 0
/-lowering-/.f644.9%
Simplified4.9%
frac-2negN/A
neg-sub0N/A
flip--N/A
+-lft-identityN/A
associate-/r/N/A
*-lowering-*.f64N/A
/-lowering-/.f64N/A
metadata-evalN/A
metadata-evalN/A
+-lft-identityN/A
+-commutativeN/A
distribute-rgt-outN/A
+-lft-identityN/A
metadata-evalN/A
--lowering--.f64N/A
metadata-evalN/A
+-lft-identityN/A
distribute-rgt-outN/A
+-commutativeN/A
+-lft-identityN/A
*-lowering-*.f644.5%
Applied egg-rr4.5%
Applied egg-rr4.9%
(FPCore (n) :precision binary64 (/ 0.5 n))
double code(double n) {
return 0.5 / n;
}
real(8) function code(n)
real(8), intent (in) :: n
code = 0.5d0 / n
end function
public static double code(double n) {
return 0.5 / n;
}
def code(n): return 0.5 / n
function code(n) return Float64(0.5 / n) end
function tmp = code(n) tmp = 0.5 / n; end
code[n_] := N[(0.5 / n), $MachinePrecision]
\begin{array}{l}
\\
\frac{0.5}{n}
\end{array}
Initial program 1.6%
sub-negN/A
+-commutativeN/A
sub-negN/A
+-commutativeN/A
associate-+r+N/A
unsub-negN/A
associate-+l-N/A
--lowering--.f64N/A
metadata-evalN/A
sub-negN/A
+-lowering-+.f64N/A
*-lowering-*.f64N/A
log-lowering-log.f64N/A
*-commutativeN/A
distribute-rgt-neg-inN/A
*-lowering-*.f64N/A
Simplified1.6%
Taylor expanded in n around inf
associate-+r+N/A
distribute-rgt1-inN/A
metadata-evalN/A
mul0-lftN/A
+-lft-identityN/A
*-lowering-*.f64N/A
sub-negN/A
+-lowering-+.f64N/A
Simplified99.9%
Taylor expanded in n around 0
/-lowering-/.f644.9%
Simplified4.9%
(FPCore (n) :precision binary64 0.0)
double code(double n) {
return 0.0;
}
real(8) function code(n)
real(8), intent (in) :: n
code = 0.0d0
end function
public static double code(double n) {
return 0.0;
}
def code(n): return 0.0
function code(n) return 0.0 end
function tmp = code(n) tmp = 0.0; end
code[n_] := 0.0
\begin{array}{l}
\\
0
\end{array}
Initial program 1.6%
sub-negN/A
+-commutativeN/A
sub-negN/A
+-commutativeN/A
associate-+r+N/A
unsub-negN/A
associate-+l-N/A
--lowering--.f64N/A
metadata-evalN/A
sub-negN/A
+-lowering-+.f64N/A
*-lowering-*.f64N/A
log-lowering-log.f64N/A
*-commutativeN/A
distribute-rgt-neg-inN/A
*-lowering-*.f64N/A
Simplified1.6%
Taylor expanded in n around inf
associate-*r*N/A
distribute-rgt1-inN/A
metadata-evalN/A
mul0-lftN/A
mul0-rgt3.1%
Simplified3.1%
(FPCore (n) :precision binary64 (- (log (+ n 1.0)) (- (/ 1.0 (* 2.0 n)) (- (/ 1.0 (* 3.0 (* n n))) (/ 4.0 (pow n 3.0))))))
double code(double n) {
return log((n + 1.0)) - ((1.0 / (2.0 * n)) - ((1.0 / (3.0 * (n * n))) - (4.0 / pow(n, 3.0))));
}
real(8) function code(n)
real(8), intent (in) :: n
code = log((n + 1.0d0)) - ((1.0d0 / (2.0d0 * n)) - ((1.0d0 / (3.0d0 * (n * n))) - (4.0d0 / (n ** 3.0d0))))
end function
public static double code(double n) {
return Math.log((n + 1.0)) - ((1.0 / (2.0 * n)) - ((1.0 / (3.0 * (n * n))) - (4.0 / Math.pow(n, 3.0))));
}
def code(n): return math.log((n + 1.0)) - ((1.0 / (2.0 * n)) - ((1.0 / (3.0 * (n * n))) - (4.0 / math.pow(n, 3.0))))
function code(n) return Float64(log(Float64(n + 1.0)) - Float64(Float64(1.0 / Float64(2.0 * n)) - Float64(Float64(1.0 / Float64(3.0 * Float64(n * n))) - Float64(4.0 / (n ^ 3.0))))) end
function tmp = code(n) tmp = log((n + 1.0)) - ((1.0 / (2.0 * n)) - ((1.0 / (3.0 * (n * n))) - (4.0 / (n ^ 3.0)))); end
code[n_] := N[(N[Log[N[(n + 1.0), $MachinePrecision]], $MachinePrecision] - N[(N[(1.0 / N[(2.0 * n), $MachinePrecision]), $MachinePrecision] - N[(N[(1.0 / N[(3.0 * N[(n * n), $MachinePrecision]), $MachinePrecision]), $MachinePrecision] - N[(4.0 / N[Power[n, 3.0], $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]), $MachinePrecision]
\begin{array}{l}
\\
\log \left(n + 1\right) - \left(\frac{1}{2 \cdot n} - \left(\frac{1}{3 \cdot \left(n \cdot n\right)} - \frac{4}{{n}^{3}}\right)\right)
\end{array}
herbie shell --seed 2024161
(FPCore (n)
:name "logs (example 3.8)"
:precision binary64
:pre (> n 6.8e+15)
:alt
(! :herbie-platform default (- (log (+ n 1)) (- (/ 1 (* 2 n)) (- (/ 1 (* 3 (* n n))) (/ 4 (pow n 3))))))
(- (- (* (+ n 1.0) (log (+ n 1.0))) (* n (log n))) 1.0))