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 NaN handling for fastMin and fastMax #559

Merged
merged 1 commit into from
Oct 15, 2023

Conversation

peterstace
Copy link
Owner

Description

The fastMin and fastMax functions previously didn't taken NaN into account, so returned inaccurate results when NaNs were passed in, biasing NaN to be returned only if it were the first argument.

This change makes the behaviour of the functions symmetrical, returning NaN if either argument (or both) are NaN.

Benchmarks have been added to show that indeed the fast variants are significantly faster than their standard variants.

$ go test -run=XXX -bench='Fast|Math' ./geom
goos: linux
goarch: arm64
pkg: github.com/peterstace/simplefeatures/geom
BenchmarkFastMin-2      712878825                1.574 ns/op
BenchmarkFastMax-2      1000000000               1.101 ns/op
BenchmarkMathMin-2      149962322                7.861 ns/op
BenchmarkMathMax-2      152543700                7.866 ns/op
PASS

The motivation behind this change is to remove the error from Envelope constructors, and perform validation separately as its own method (similar to the recent changes from geometries). Since the envelope only stores the min and max points, I'd like any NaNs to "infect" the envelope so that they're caught by validation rather than silently being dropped.

Check List

Have you:

  • Added unit tests? Yes.

  • Add cmprefimpl tests? (if appropriate?) N/A

  • Updated release notes? (if appropriate?) N/A

Related Issue

  • N/A

The `fastMin` and `fastMax` functions previously didn't taken NaN into
account, so returned inaccurate results when NaNs were passed in,
biasing NaN to be returned only if it were the first argument.

This change makes the behaviour of the functions symmetrical, returning
NaN if _either_ argument (or both) are NaN.

Benchmarks have been added to show that indeed the fast variants are
significantly faster than their standard variants.

```
$ go test -run=XXX -bench='Fast|Math' ./geom
goos: linux
goarch: arm64
pkg: github.com/peterstace/simplefeatures/geom
BenchmarkFastMin-2      712878825                1.574 ns/op
BenchmarkFastMax-2      1000000000               1.101 ns/op
BenchmarkMathMin-2      149962322                7.861 ns/op
BenchmarkMathMax-2      152543700                7.866 ns/op
PASS
```

The motivation behind this change is to remove the error from Envelope
constructors, and perform validation separately as its own method
(similar to the recent changes from geometries). Since the envelope only
stores the min and max points, I'd like any NaNs to "infect" the
envelope so that they're caught by validation rather than silently being
dropped.
@peterstace peterstace self-assigned this Oct 5, 2023
@@ -69,15 +70,15 @@ func sequenceToXYs(seq Sequence) []XY {

// fastMin is a faster but not functionally identical version of math.Min.
func fastMin(a, b float64) float64 {
if a < b {
if math.IsNaN(a) || a < b {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks to also be consistent behaviour with the built-in min (and max) funcs offered in Go 1.21.

Do we need to handle +-Inf as well?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, once I upgrade to go 1.21, we might not need these anymore. Probably not going to upgrade though until Go 1.23 comes out, in order to not force users to upgrade early.

It doesn't need to handle infinity explicitly, since it's handled implicitly by the a < b check. All of the cases involving infinity "just work" 😁.

Base automatically changed from use_sequence_envelope_instead_of_extend to master October 15, 2023 18:26
@peterstace
Copy link
Owner Author

Thanks for reviewing @albertteoh 🙇

@peterstace peterstace merged commit d466a92 into master Oct 15, 2023
1 check passed
@peterstace peterstace deleted the better_nan_handling_in_fastmin_and_fastmax branch October 15, 2023 18:26
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.

None yet

2 participants