(module ramanujan-pi mzscheme (require (lib "40.ss" "srfi") (lib "contract.ss")) ;; From the wikipedia article: ;; ;; (http://en.wikipedia.org/wiki/Srinivasa_Ramanujan) ;; ;; 1/pi = (2*sqrt(2) / 9801)* sum[(4k)!(1103 + 26390k) / (k!)^4*396^(4k)] (define (stream-sum term) (stream-delay (let loop ([k 0] [acc 0]) (let ([next-term (term k)]) (stream-cons (+ acc next-term) (loop (add1 k) (+ acc next-term))))))) ;; stream-invert: stream -> stream (define (stream-invert a-stream) (stream-map (lambda (x) (/ 1 x)) a-stream)) ;; stream-scale: stream number -> stream (define (stream-scale a-stream n) (stream-map (lambda (x) (* n x)) a-stream)) ;; factorial: number -> number (define (factorial x) (let loop ([x x] [acc 1]) (cond [(= x 0) acc] [else (loop (sub1 x) (* x acc))]))) ;; make-pi-stream: -> stream (define (make-pi-stream) (stream-invert (stream-scale (stream-sum (lambda (k) (/ (* (factorial (* 4 k)) (+ 1103 (* 26390 k))) (* (expt (factorial k) 4) (expt 396 (* 4 k)))))) (/ (* 2 (sqrt 2)) 9801)))) (provide/contract [make-pi-stream (-> stream?)]))