(define (monte-carlo trials experiment) (define (iter trials-remaining trials-passed) (cond ((= trials-remaining 0) (/ trials-passed trials)) ((experiment) (iter (- trials-remaining 1) (+ trials-passed 1))) (else (iter (- trials-remaining 1) trials-passed)))) (iter trials 0)) (define (random-in-range low high) (let ((range (- high low))) (+ low (random range))))
The solution is:
(define (P x y) (< (+ (expt (- x 5) 2) (expt (- y 7) 2)) (expt 3 2))) (define (estimate-integral P x1 x2 y1 y2 trials) (define (experiment) (P (random-in-range x1 x2) (random-in-range y1 y2))) (monte-carlo trials experiment))
(estimate-integral P 2.0 8.0 4.0 10.0 100)
Then we can estimate pi with the fact that a circle area is (pi * r²).
Hence pi ≅ (Monte Carlo results * rectangle area) / r²
(define pi-approx (/ (* (estimate-integral P 2.0 8.0 4.0 10.0 10000) 36) 9.0)) pi-approx
Which gave 3.1336 during my test.
This function has to be tested under MIT Scheme, neither gambit-scheme or SISC implements (random) - actually (random) is not part of R5RS nor SRFI.
NB: using 2.0 instead of 2 in estimate-integral is primordial. If you pass two integers to (random-in-range low high), it will return another integer strictly inferior to your 'high' value — and this completely screws the Monte-Carlo method (it then estimates pi to ~3.00).
<< Previous exercise (3.4) | Index | Next exercise (3.6) >>