Skip to content

Conversation

@pantosh
Copy link
Contributor

@pantosh pantosh commented Aug 25, 2022

Fixes #1924.

Changes proposed in this pull request:

All Math.Abs(value) < double.Epsilon checks replaced with <= since 0 < double.Epsilon cannot be trusted to evaluate true on all architectures.

@VisualMelon
Copy link
Contributor

Azure failure can be ignored

@VisualMelon
Copy link
Contributor

I'll leave this for the moment to let the other maintainers take a look, but if there are no objections I'll merged it after a few days.

@pantosh
Copy link
Contributor Author

pantosh commented Aug 25, 2022

I tried to minimize the double.Epsilon changes to those that would surely fail on archs where 0 < double.Epsilon is false, however it should be considered to remove all usages of double.Epsilon. See the discussion in #1924.

The largest breaking risk is in the HistogramSeries where it looks like double.Epsilon is used as some non-zero marker for min/max. That is risky on its own and should be changed, since it may evaluate to zero.

@VisualMelon
Copy link
Contributor

For Historgram series, we probably need to detect the log(0) conditions explicitly and deal with it. Notes in #1886

@Jonarw
Copy link
Member

Jonarw commented Aug 28, 2022

Thanks for highlighting this issue! This is something I absolutely was not aware of.
Considering that there are seemingly no guarantees regarding double.Epsilon, I'd be inclined to eliminate all its usages across the code base. In most cases it should be fine to just do <= 0, right? Except for the HistogramSeries, which we would have to consider separately, this shouldn't really break anything, right? And even if it does break something, at least it would break consistently, which I think would be better than breaking sometimes.

@VisualMelon
Copy link
Contributor

I'd agree with @Jonarw that <= 0 would be the most direct translation, and looking again it's less likely to create confusion down the line.

(note: rebasing should stop azure whinging)

@pantosh
Copy link
Contributor Author

pantosh commented Aug 29, 2022

The changes in this PR were the most conservative I could make, i.e. replacing < epsilon with <= epsilon.
There are a handful of other epsilon usages that I didn't touch, because of the risk of double.Epsilon having some semantically meaning as a non-zero marker (i.e. in histogram).

In conclusion, double.Epsilon is not a safe constant to use. For predicates that check if two calculations are mathematically the same "within floating point rounding error", some other epsilon must be used, i.e. 1e-50. Obviously this has its own problem, if the user happens to use data at that scale. Floats are not always easy to work with in a general purpose library.

@VisualMelon
Copy link
Contributor

VisualMelon commented Aug 29, 2022

I think what @Jonarw and I are saying is that substituting <= 0 for < double.Epsilon will always produce the same behaviour as when epsilon is the smallest positive representable value (per the docs and my previous understanding), and I think it will be less likely to confuse matters in future: <= epsilon looks - as you point out - like a conscious (but failed) attempt to cleanly handle edge cases and won't be consistent across platforms.

I think the only truly problematic instance in the codebase is histogram (i.e. where just fixing it in this PR and forgetting about it won't cut it): in the other cases, there is no obvious epsilon to use, and picking one would just provide borderline-wrong behaviour for borderline data, so reducing them to <= 0 and losing the mention of Epsilon (which could serve as a marker) is absolutely fine. If issues do emerge then we can address those directly down the line, and I think ensuring the same behaviour (as expected and across platforms) and keeping the code simple is the right way to go here.

@VisualMelon
Copy link
Contributor

VisualMelon commented Aug 29, 2022

(all that said, consistency probably isn't a big deal (not something we can solve), given the platforms will be inherently inconsistent anyway, and in the specific case of epsilon comparison, <= 0 and <= epsilon will be the same, if we ignore all the other subnormals)

@VisualMelon
Copy link
Contributor

@pantosh sorry about my indecisiveness on this; if you can change the instances of <= epsilon to <= 0, then I'll get this quickly merged.

As an aside, I had a bash at the histogram issue at some point but wasn't happy with it; will have another go once this and some of the modernisation PRs have gone through.

@VisualMelon
Copy link
Contributor

@pantosh are you happy to make the change described by @Jonarw and myself above? (that is, change <= epsilon to <= 0).

If you don't have time, let me know, and I'll pick it up.

@VisualMelon VisualMelon mentioned this pull request May 14, 2023
@VisualMelon
Copy link
Contributor

@pantosh Work merged in #1997 : thanks for reporting this and suggesting the fix; wanted to get on with the merge to made the final changes discussed in a separate branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 < double.Epsilon checks return false

3 participants