Skip to content

Fix inverted is_all_nan / is_any_nan / is_all_infinite / is_any_infinite - #1614

Merged
akern40 merged 2 commits into
rust-ndarray:masterfrom
youdie006:fix/1612-is-all-nan-inverted
Oct 18, 2026
Merged

akern40 merged 2 commits into
rust-ndarray:masterfrom
youdie006:fix/1612-is-all-nan-inverted

Conversation

@youdie006

Copy link
Copy Markdown
Contributor

Fixes #1612.

Root cause

The boolean_ops! macro in src/numeric/impl_float_maths.rs had an inverted $all predicate: Zip::from(self).all(|&elt| !elt.$func()) tests "all elements are NOT NaN", the opposite of the documented "true if all elements are NaN". $any was defined as !self.$all(), so the double negation made is_any_* appear correct while is_all_* returned true for an all-finite array.

Fix

Both predicates are corrected together (fixing only $all would break the is_any_* methods that currently ride on the double negation):

  • $all -> Zip::from(self).all(|&elt| elt.$func())
  • $any -> Zip::from(self).any(|&elt| elt.$func())

This fixes is_all_nan, is_any_nan, is_all_infinite, and is_any_infinite in one change. Empty-array semantics are preserved (all -> true, any -> false).

@dbranford correctly identified the $all flip and raised the is_any question in the issue thread; this PR applies both corrections and adds regression coverage.

Tests

New tests/nan_all_repro.rs covers both the NaN and infinite families with f64: all-finite (is_all_* and is_any_* false), all-nan/all-inf (is_all_* and is_any_* true), and mixed (is_all_* false, is_any_* true).

Red-green verified: with the fix reverted, the first assertion (!all_finite.is_all_nan()) panics; with the fix, both tests pass. cargo fmt (nightly, per repo rustfmt.toml), cargo clippy (no new warnings), and the existing tests/numeric.rs suite all pass.


AI-assisted: this change was prepared with the help of an AI coding assistant and reviewed by me before submission.

The boolean_ops! macro in src/numeric/impl_float_maths.rs had an inverted $all
predicate: Zip::from(self).all(|&elt| !elt.$func()) tests "all elements are NOT
NaN", the opposite of the documented "true if all elements are NaN". $any was
defined as !self.$all(), so the double negation made is_any_* appear correct
while is_all_* returned true for an all-finite array.

Correct both predicates together (fixing only $all would break the is_any_*
methods that ride on the double negation):
  $all -> Zip::from(self).all(|&elt| elt.$func())
  $any -> Zip::from(self).any(|&elt| elt.$func())

Empty-array semantics are preserved (all -> true, any -> false).

Fixes rust-ndarray#1612
@akern40
akern40 force-pushed the fix/1612-is-all-nan-inverted branch from af6ca1e to b9903ea Compare October 18, 2026 23:07
@akern40
akern40 enabled auto-merge (squash) October 18, 2026 23:36
@akern40
akern40 disabled auto-merge October 18, 2026 23:36
@akern40
akern40 enabled auto-merge (squash) October 18, 2026 23:37
@akern40

akern40 commented Oct 18, 2026

Copy link
Copy Markdown
Collaborator

@youdie006 thank you for your contribution! Sorry for the delay, life got busy but I'm trying to get back to the repo now

@akern40
akern40 merged commit b0f9657 into rust-ndarray:master Oct 18, 2026
15 checks passed
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.

.is_all_nan() returns true for an all-finite array

2 participants