-
Notifications
You must be signed in to change notification settings - Fork 60
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
Implement approx eq trait #51
Conversation
Nice! Now, I haven't studied that trait yet, so I don't know all the details about it, but shouldn't those constants really come from the float type? I mean, different types have different precision, and so on. |
To-Do
DesignImplemented the approx trait separately for the hue types using angle difference and separate default epsilon and ulps for the angles. The hue based colors will use the angle defaults for angles and regular defaults for floats. One possible issue with this is that manually providing epsilon will not work as expected
Another alternative is to only check non hues as default as hues must be manually checked
Option one seems simpler and that is currently implemented. Not sure if this needs to be documented somewhere. |
This does not work:
errors with approxeq not implemented for T |
I must say that alternative 2 seems very fishy, and may become a really bad surprise. Here I come with my questions again, but are the differences really necessary? Does the different scales really matter that much?
Because you need to write |
Actually thats what I had used, but it errors with
|
Did you write |
I am not sure. I am ok with having a single precision. I was looking at it from the tests point of view, where the data was not really precise, but that should not drive the design of the library. We need to figure out the right defaults too. Currently set to
|
No, it's better to fix the tests or test with a lower precision.
Those will depend on the precision if the float type, so I would suggest that we try to reuse them. We can just delegate all the relevant methods to |
Any ideas on how to cast epsilon as T
|
You could require |
This works
So we don't manually set the precision then, only override it when necessary. |
Yes, I think that's more robust, since it will be adapted to the float type. It's also not the end of the world if it would turn out to be a problem. |
We have an issue with the angles comparison. We are comparing to zero. https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/. Look at the infernal zero section. |
Based on the link we can multiply the epsilon by 180. For ulps not clear if multiplying by 180 is right.
|
Floats are clearly a piece of junk, sometimes. I'm not sure what we can do to make it better, since we have to touch the values in some way. Maybe check
I guess that's alright, but I don't know about ULPs, either. They are a bit different... |
😲 |
Sorry, wrong button... 😨 |
Basicaly what the link is saying is don't use ulps_eq for angles. only use rel_eq. Some numbers in the link. 180 * float is a good default. It is slightly larger than 1 ulps at 180.0 180 ulps at 0.0 is still very small, should we just multiply ulps also by 180 to be safe? |
Might as well do that, as long as it doesn't end up being too big. |
I've made a small change This is an error
So i have added 180 and compared to 180.
The end result should be the same, some loss of presicison for values close to zero. Do you see any issues with this? |
58dac57
to
a0e68ea
Compare
Should be good to go!! |
Oh, nice! I'll take a look.
I know too little about these things... The other alternative is to add the |
T::default_max_ulps() | ||
} | ||
fn relative_eq(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool { | ||
$( T::relative_eq(&self.$element, &other.$element, epsilon, max_relative) )&&+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to change this to self.$element.relative_eq(&other.$element, epsilon, max_relative)
? That would let us have only one macro for implementation, instead of special casing hue based types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
These tests don't pass with either method. add 180 or multiply epsilon by 180
Let me look into this further. |
This passes. Forgot f32 tag
I am not sure about multiplting ulps by 180, but we can leave it for now. |
These things are still pretty much Terra incognita for me, but I think it looks fine, overall. Thank you! @homu r+ |
📌 Commit 3b952b3 has been approved by |
⚡ Test exempted - status |
Implement approx eq trait - Implements approx eq trait for all the colors from the approx crate. - Removed the assert_approx_equal macro and replaced all comparisons with the assert_relative_eq macro from the approx crate - The equality macros in the integration tests were also replaced with the assert_relative_eq macro For hue comparison, the recommendation is use 180 * epsilon as the epsilon and do not compare by ulps. This will cause a loss of precision for numbers close to zero, but for angle differences it is still reasonably small. Check https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ for more information.
Oh, we forgot to refer to #50, but it's ok. |
Add missing ApproxEq implementations #51 didn't implement `ApproxEq` for `Alpha` and `Color`, so this PR adds those implementations.
For hue comparison, the recommendation is use 180 * epsilon as the epsilon and do not compare by ulps. This will cause a loss of precision for numbers close to zero, but for angle differences it is still reasonably small.
Check https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ for more information.