Two Integrals
January 11, 2011
Our functions are straight forward translations of the mathematical formulas, summing the infinite series until the individual terms are less than the desired tolerance:
(define (exp-integral x)
(let* ((gamma 0.5772156649015328606065))
(let loop ((k 1) (fact 1) (z x) (sum (+ gamma (log x))))
(let ((term (/ z k fact)))
(if (< term 1e-17) sum
(loop (+ k 1) (* fact (+ k 1)) (* z x) (+ sum term)))))))
(define (log-integral x)
(let* ((gamma 0.5772156649015328606065)
(logx (log x)) (sum (+ gamma (log logx))))
(let loop ((k 1) (fact 1) (logx^k logx) (sum sum))
(let* ((term (/ logx^k fact k)) (sum (+ sum term))
(newk (+ k 1)) (newfact (* fact newk)))
(if (< term 1e-17) sum
(loop newk newfact (* logx^k logx) sum))))))
(define (offset-log-integral x)
(- (log-integral x) 1.04516378011749278))
Note that we lose some precision when x is large; the proper value of Li(1021) is 21127269486616126182, but we compute 21127269486616100864. We computed Li(1021) = 21127269486616129536 using adaptive quadrature in a previous exercise.
You may be curious why we are interested in a function that approximates the prime counting function when we gave an exact version of the function in the previous exercise. The reason is that calculating the logarithmic integral is much faster than enumerating and counting the primes, as we did, and can be done for larger values of x. And by the way, use of the logarithmic integral as an approximation for the prime counting function was discovered by Carl Gauss as a fourteen-year-old boy!
You can run the program at http://programmingpraxis.codepad.org/9hg2s20m.
[…] today’s Programming Praxis exercise, our task is to write functions to calculate the exponential and […]
My Haskell solution (see http://bonsaicode.wordpress.com/2011/01/11/programming-praxis-two-integrals/ for a version with comments):
My Python solution. This blog and my free time studies are drawing me more and
more towards Scheme and Haskell, but since there are two great solutions in
those languages already I felt I should offer a solution in a different
language. I’ve moved towards the newer “format” instead of the older printf
style string formatting.
this is the best blog on the whole internet. thank you!
Why 1e-17 is chosen as the stopping point in all of your code?