Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better floating point handling #245

Open
sampotter opened this issue Dec 15, 2020 · 2 comments
Open

Better floating point handling #245

sampotter opened this issue Dec 15, 2020 · 2 comments
Milestone

Comments

@sampotter
Copy link

Hello! First, thanks for the great unit testing library. I really enjoy seeing all my tests compile instantly and having such a pleasant library to work with.

I'd like to suggest some enhancements to the floating point asserts. I'm aware of issue #147. A pretty reasonable way to deal with the issue with zero pointed out in that issue is to use a relative and absolute tolerance together. Consider what happens here:

rtol = 1e-10 # Relative tolerance
x = 0
y = 1e-12
abs(x - y)/max(abs(x), abs(y)) < rtol # False!

Okay... Let's define an absolute tolerance:

atol = 1e-10 # Absolute tolerance
abs(x - y) < rtol*max(abs(x), abs(y)) + atol # True!

When developing numerical code, these are the kinds of tests I like to use. It'd be very helpful if this was baked into Cgreen.

It is also a little unconventional (when developing numerical code) to think about tolerances in terms of significant figures. Tolerances will just be specified using scientific notation; e.g., double machine epsilon ≈ 2.2e-16. It would be nice to be able to specify tolerances this way.

Altogether, I'd like to be able to write the following code:

double_relative_tolerance_is(1e-15);
double_absolute_tolerance_is(2.5e-14);
...
assert_that_double(x, is_nearly_double(y));

Does this sound reasonable?

Thanks again for Cgreen!

@thoni56
Copy link
Contributor

thoni56 commented Dec 15, 2020

Thanks for your suggestion! It sounds very reasonable to me. I'm not at all into numeric software so I have limited experience with what would be natural for them (you).

My immediate thought is how to combine the two tolerance models. I think we could need help to figure that out.

You might already have figured out that the essential code is in the functions doubles_are_equal()

bool doubles_are_equal(double tried, double expected) {

and accuracy() a couple of lines below.

I suppose the basics would be to have your double_relative_tolerance() and double_absolute_tolerance() set a flag to know that the tolerance should be calculated using "scientific" rather than "digits". And the accuracy() function would do that calculation differently in the two cases.

And of course we would need to figure out what we want to do when someone calls both ...tolerance_is() and significant_digits...().

A PR would be appreciated.

@sampotter
Copy link
Author

Thanks for the quick response. I threw together a PR with a rough draft implementation. I tested this out with a library I'm working on, and it works more or less as I'd like.

I responded in more detail to some of your comments in my PR.

@thoni56 thoni56 added this to the 1.4.0 milestone Dec 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants