2
assert tlf.z >= tlb.z, (tlf.z,trf.z)
AssertionError: (0.5, 0.5)

As can be seen, I'm suffering from precision problems. How can I rephrase the assert so it does pass for close enough values (how big should the fudge-factor be?) and then fix the rhs should it actually be smaller than the lhs so that it becomes strictly equal?

4
  • How big should the tolerance be? As big as it needs to be, and no bigger. Commented Mar 31, 2011 at 21:19
  • ho ho and this can be determined how? I was going to get at 0.000001 for 32-bit Commented Mar 31, 2011 at 21:20
  • 2
    Well, only you can answer this. Only you know where the imprecision comes from. So, just as big as you need, and no bigger. Commented Mar 31, 2011 at 21:23
  • For what it's worth, for such tests, I try to make my tolerances proportional to the magnitude of the values being compared. Commented Mar 31, 2011 at 21:31

2 Answers 2

3

Try this:

EPSILON = 10 ** -12
assert tlf.z >= tlb.z - EPSILON, (tlf.z,trf.z)
tlf.z = max(tlf.z,tlb.z)

Essentially, you have to define the tolerance you're willing to have for "greater than or equal", and account for it.

What value to pick for EPSILON is a difficult question. It depends on the source of your error, and the number of calculations between that source and the comparison. If there are few calculations, a smaller value for EPSILON is a good bet. I would try the example, and adjust if you still find problems.

Sign up to request clarification or add additional context in comments.

1 Comment

I think that should be assert tlf.z >= tlb.z - EPSILON. Suppose the two values really are equal; the "+ EPSILON" will make the assertion fail.
3

I don't think the answer given by willm1 is correct.
Let me explain.

The following expression:
tlf.z >= tlb.z - EPSILON
is equivalent to:
(tlf.z > tlb.z - EPSILON) or (tlf.z == tlb.z - EPSILON)

If tlf.z > tlb.z is true, even by a difference smaller than EPSILON, then tlf.z > tlb.z - EPSILON will also be true. No matter what the value of EPSILON. Instead, the correct form is:
tlf.z > tlb.z + EPSILON
As for the second expression, tlf.z == tlb.z - EPSILON, it will only be evaluated as true if tlf.z and tlb.z differ exactly by EPSILON, which is not what we want. Instead, we want the difference between them to be less than EPSILON:
abs(tlf.z - tlb.z) <= EPSILON

Concluding, tlf.z >= tlb.z - EPSILON should be written as:
(tlf.z > tlb.z + EPSILON) || (abs(tlf.z - tlb.z) <= EPSILON)

Update:
I was looking at some code, and all of a sudden I noticed that (tlf.z > tlb.z + EPSILON) || (abs(tlf.z - tlb.z) <= EPSILON) is actually equivalent to tlf.z >= tlb.z - EPSILON.
When we're looking for the similarity, abs(tlf.z - tlb.z) <= EPSILON, we want tlb.z to be in the following gray area:

When we're looking for tlf.z > tlb.z + EPSILON:

Hence, we're really looking for:

Which is the same as tlf.z + EPSILON >= tlb.z (equivalent to tlf.z >= tlb.z - EPSILON).
In that case, willm1 was actually right. Sorry :)

4 Comments

nicely answered. In my own code I ended up doing math.fabs(tlf.z-tlb.z) < 0.000001
Thank you. In that case you're checking for similarity only.
quite right, I wrote that forgetting the original question; for >= I'd just subtract half the fudge factor from the rhs
Was looking at the code that I have and I found out that the conditions I wrote are actually equivalent to the one from willm1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.