I was doing exercise 3.5 on SICP book.
A Monte Carlo implementation in Racket generates the following code:
(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))))
; questão propriamente dita
(define (estimate-integral predicate x1 x2 y1 y2 trials)
(*(* (- x1 x2) (- y1 y2))
(monte-carlo trials predicate)))
(define (circulo?)
(>= 1 (+ (square (random-in-range -1 1))
(square (random-in-range -2 1)))))
(define (estimate-pi)
(estimate-integral circulo? -1.0 1 -2 1 100000))
; Fiquei brincando com os os parametros do retangulo, desde que o circulo continue dentro dele
(define square
(lambda (x) (* x x)))
The code is right. However, I decided to insert some unit tests.
Hence, I imported the library rackunit and used the following test:
(require rackunit)
(check-equal? (estimate-pi) 3.00906)
This is obviously a problem and the tests will always fail since the output is dynamic due to a random function.
What should I do in this case?
There's a built-in check for this - the preferred solution:
(check-= (estimate-pi) 3.1416 1e-4 "Incorrect value for pi")
The previous check verifies that the result falls within an acceptable tolerance value (also known as epsilon), and it's equivalent to this:
(check-true (<= (abs (- (estimate-pi) 3.1416)) 1e-4))
The 1e-4
part is the tolerance in scientific notation, it means that if the difference between the actual value and the expected value is less than 0.0001
, then we accept the result as correct. Of course, you can tweak the tolerance value to suit your needs - the smaller the number, the higher the required precision. Also, it's useful to know that if check-=
didn't exist, we could define our own check, like this:
(define-binary-check (check-in-tolerance actual expected tolerance)
(<= (abs (- actual expected)) tolerance))
(check-in-tolerance (estimate-pi) 3.1416 1e-4)