chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] Using epsilon in test egg


From: Matt Gushee
Subject: [Chicken-users] Using epsilon in test egg
Date: Sat, 26 Jul 2014 18:42:27 -0600

Hi, folks--

I am working on an application that does a lot of floating-point
calculations, and I'm having trouble with the test suite. The program
is based on the imlib2 egg, and it does some fairly simple image
processing for web applications, so the numbers in question are RGBA
color values. Internally I am handling all the numbers as floats in
the range 0-1, because the blending and compositing formulas are much
more straightforward that way compared to using integers 0-255.

So I have a number of functions that produce lists of numbers like these:

  '(0.323 0.788834 0.12 0.4)
  '(0 0 0 1.0)
  '(0.6666666667 0.4 0.562 0.0)

And given the above, a moderate degree of imprecision in the results
is perfectly acceptable - I haven't yet confirmed this with actual
images, but I'm thinking as much as 0.5% variance should work fine
(basically, as long as the colors in the generated images look as
expected to a casual observer, the result should be acceptable). So of
course I want the test results to reflect this.

I am using the following procedure to compare number lists:

  (define (list= l1 l2)
  (and (= (length l1) (length l2))
       (let loop ((l1* l1) (l2* l2))
         (cond
           ((null? l1*) #t)
           ((= (car l1*) (car l2*)) (loop (cdr l1*) (cdr l2*)))
           (else #f)))))

And for the tests that use this predicate, I set

  (current-test-epsilon 0.005)

[or 0.002 or 0.001 - it doesn't seem to make any difference]

But I'm finding that certain tests still fail unexpectedly, e.g.

 2.03.10: (parse-color "167,215,51" #f) => '(0.655 0.843 0.200 1.0)  [ FAIL]
          expected (0.655 0.843 0.2 1.0)
          but got (0.654901960784314   0.843137254901961 0.2 1.0)

But:

  (/ 0.654901960784314 0.655) => 0.999850321808113
  (/ 0.843137254901961 0.843) => 1.0001628172028

So it would appear that the epsilon value does not apply to these tests.

I can certainly define a custom equality predicate that will do what I
need, but this is bugging me. I guess I don't really understand how
epsilon is supposed to work. The test egg documentation says that
applies to 'inexact comparisons', but I can't find a definition of
'inexact comparison'. I have also read that '=' may be unreliable for
inexact numbers, but I don't know what else to use. Perhaps 'fp=' from
the Chicken library? Then I would have to ensure that all numbers are
expressed as floats, whereas currently my code has a number of cases
where 1 and 0 are expressed as integers.

So ... do I understand the problem correctly? Any recommendations?

Matt Gushee



reply via email to

[Prev in Thread] Current Thread [Next in Thread]