Skip to main content
v2026.11,986 entries · CC-BY 4.0

NumPy allclose: Floating-Point Tolerance Guide

Use numpy allclose to compare floating-point arrays with relative and absolute tolerances. Master equation asymmetry, NaN handling, and float32 precision.

Written and maintained by CASRAI Editorial Board

Published

On this page

What it is used for in research

In computational research and scientific computing, numerical simulations routinely generate arrays containing floating-point numbers. Because standard hardware represents floating-point values according to the IEEE 754 binary specification, operations such as matrix inversion, numerical integration, differential equation solving, and iterative optimization introduce minute rounding errors. Consequently, evaluating equality between floating-point arrays using standard equality operators (such as == or numpy.array_equal) fails in empirical settings where mathematically identical quantities differ at the limits of machine precision.

The numpy allclose function (numpy.allclose()) provides a robust mechanism to evaluate whether two numeric arrays are element-wise equal within specified absolute and relative error tolerances. Instead of requiring exact bitwise identity, allclose tests whether the difference between corresponding elements remains within an acceptable computational margin. This verification step is vital for ensuring computational reproducibility standards across varying operating systems, compiler optimizations, and hardware architectures.

Mathematically, numpy.allclose(a, b, rtol=1e-05, atol=1e-08) evaluates the following condition across all paired elements in arrays a and b:

absolute(a - b) ≤ (atol + rtol × absolute(b))

When this inequality holds for every element, the function returns a single scalar boolean True; if even one element exceeds the allowable tolerance boundary, it returns False. Researchers use this capability across data pipelines, comparing simulated trajectories against experimental benchmarks, validating solution vectors in linear systems alongside calculating array and matrix norms with numpy.linalg.norm, and verifying transformations alongside NumPy array broadcasting mechanics and rules.

Install or access (official source only)

The numpy.allclose function is a core component of the official NumPy package. It requires Python 3.9 or higher and can be installed through the standard official package indexes without commercial licensing fees.

To install NumPy using the official Python Package Index (PyPI) or Conda channels, run the appropriate command in your terminal:

# Install from the official Python Package Index (PyPI)
pip install numpy

# Alternatively, install via conda-forge in an active Conda or Mamba environment
conda install -c conda-forge numpy

To verify the installation and confirm that NumPy is ready for numerical analysis in your Python environment, execute the following commands in an interactive session:

import numpy as np

# Verify installed NumPy version and callable allclose function
print(np.__version__)
print(callable(np.allclose))

Step-by-step task

The following numbered steps demonstrate how to apply numpy.allclose to scientific arrays, configure tolerances for single versus double precision, manage non-finite values, and prevent common comparison pitfalls.

1. Compare Floating-Point Arrays Using Default Tolerances

Begin by importing NumPy and constructing two arrays derived from separate computational steps that should theoretically match. Under default settings, numpy.allclose applies a relative tolerance (rtol) of 1e-05 and an absolute tolerance (atol) of 1e-08:

import numpy as np

# Simulate an analytical reference array and an experimental outcome
theoretical = np.array([0.1, 0.2, 0.3, 0.4], dtype=np.float64)
experimental = np.array([0.10000002, 0.19999999, 0.30000001, 0.39999998], dtype=np.float64)

# Test approximate equality
is_match = np.allclose(experimental, theoretical)
print("Arrays match within default tolerance:", is_match)  # True

2. Tune Absolute and Relative Tolerances for Precision Requirements

When working with single-precision floating-point data (float32), default tolerances can cause false negatives because machine epsilon for 32-bit floats is approximately 1.19e-07, which is larger than the default atol=1e-08. Adjust both rtol and atol to align with the precision characteristics of your dataset:

# Float32 measurements common in neural network weights and GPU simulations
ref_f32 = np.array([1.234567, 2.345678, 3.456789], dtype=np.float32)
test_f32 = ref_f32 + np.float32(1e-6)

# Default comparison fails due to strict atol
print("Default tolerance check:", np.allclose(test_f32, ref_f32))  # False

# Custom tolerances calibrated for single precision
eps_f32 = np.finfo(np.float32).eps
calibrated_match = np.allclose(test_f32, ref_f32, rtol=1e-4, atol=1e-5)
print("Calibrated tolerance check:", calibrated_match)  # True

3. Handle Missing Observations and Infinite Values

By default, numpy.allclose adheres to IEEE 754 rules where NaN != NaN, meaning any array containing a NaN will return False. When comparing scientific datasets containing intentional missing markers, pass equal_nan=True to treat identical NaN positions as matching, as detailed in our guide on detecting and handling NaN values in NumPy:

# Observational dataset with missing sensor records
sensor_run_a = np.array([24.5, np.nan, 26.1, np.inf])
sensor_run_b = np.array([24.500001, np.nan, 26.099999, np.inf])

# Default evaluates NaN comparison to False
print("Strict NaN check:", np.allclose(sensor_run_a, sensor_run_b))  # False

# Permissive comparison treating matching NaNs and signed Infs as equal
print("Equal NaN check:", np.allclose(sensor_run_a, sensor_run_b, equal_nan=True))  # True

4. Guard Against Silent Broadcasting Mismatches

Because numpy.allclose follows NumPy broadcasting rules, a row vector of shape (1, 3) will be compared against a matrix of shape (3, 3) without raising a shape error. In rigorous scientific verification, always check that input shapes match before evaluating numerical closeness:

vector = np.array([1.0, 2.0, 3.0])
matrix = np.array([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]])

# Silent broadcasting evaluates to True despite structural difference
print("Broadcasting check:", np.allclose(vector, matrix))  # True

# Recommended structural verification guard
def verified_allclose(a, b, **kwargs):
    if np.shape(a) != np.shape(b):
        raise ValueError(f"Array shapes do not match: {np.shape(a)} vs {np.shape(b)}")
    return np.allclose(a, b, **kwargs)

# Guard prevents dimensional mismatches in automated validation
try:
    verified_allclose(vector, matrix)
except ValueError as err:
    print("Caught shape discrepancy:", err)

5. Integrate Closeness Checks into Automated Research Test Suites

In research software development, incorporate tolerance assertions within unit tests and property testing frameworks to prevent regressions, expanding upon property-based testing for scientific code:

import unittest

class TestNumericalSimulation(unittest.TestCase):
    def test_conservation_of_energy(self):
        initial_energy = 100.0
        final_energy_states = np.array([99.999999, 100.000001, 100.000000])
        # Assert element-wise closeness within acceptable simulation drift
        self.assertTrue(
            np.allclose(final_energy_states, initial_energy, atol=1e-5),
            msg="Simulation energy drifted beyond acceptable tolerance threshold."
        )

if __name__ == "__main__":
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

Output and how to read it

The output of numpy.allclose is always a single Python standard boolean value: True or False.

  • True: Every corresponding element pair (a_i, b_i) satisfies the inequality |a_i - b_i| ≤ atol + rtol × |b_i|. All non-finite values (Inf, -Inf) match in sign and position, and any NaN values match in position with equal_nan=True enabled.
  • False: At least one element pair violates the tolerance inequality, a shape incompatibility prevents broadcasting, or non-finite values (such as an unhandled NaN) exist in either array.

When numpy.allclose returns False, it does not display which elements failed or the magnitude of their deviations. To diagnose the exact location and severity of differences, pair numpy.allclose with numpy.isclose and diagnostic array metrics:

# Diagnosing tolerance violations
baseline = np.array([10.0, 20.0, 30.0, 40.0])
observed = np.array([10.00001, 20.00002, 30.00500, 40.00001])

# Check overall closeness
status = np.allclose(observed, baseline, atol=1e-4)
print("Overall status:", status)  # False

# Identify diverging coordinates with isclose
divergent_mask = ~np.isclose(observed, baseline, atol=1e-4)
print("Failing indices:", np.where(divergent_mask)[0])
print("Failing baseline values:", baseline[divergent_mask])
print("Failing observed values:", observed[divergent_mask])

# Calculate maximum absolute and relative discrepancies
abs_diff = np.abs(observed - baseline)
rel_diff = abs_diff / np.abs(baseline)
print("Max absolute error:", np.max(abs_diff))
print("Max relative error:", np.max(rel_diff))

Troubleshooting

The following issues represent the most frequent sources of confusion and unexpected outcomes when applying numpy.allclose in research pipelines:

1. Mathematical Asymmetry Across Arguments

The governing equation |a - b| ≤ atol + rtol × |b| scales the relative tolerance using the magnitude of b, not a. Consequently, numpy.allclose(a, b) does not always yield the same result as numpy.allclose(b, a). This asymmetry becomes apparent when comparing values near zero or when comparing numbers of differing orders of magnitude:

# Demonstration of argument asymmetry
a = 1e-8
b = 1e-7

print(np.allclose(a, b, rtol=0.1, atol=0.0))  # True: |1e-8 - 1e-7| = 9e-8  False
# But if b is larger, rtol * |b| provides a wider acceptance window
a_val = np.array([1.0])
b_val = np.array([1.1])
print("Forward:", np.allclose(a_val, b_val, rtol=0.095, atol=0.0))  # False: 0.1 <= 0.095 * 1.0 is False
print("Reverse:", np.allclose(b_val, a_val, rtol=0.095, atol=0.0))  # False

To avoid directional bias, consistently treat b as the validated ground-truth reference array and a as the newly computed test array, or use a symmetric tolerance function if mutual agreement is required.

2. False Failures on Single-Precision (float32) Arrays

Because the default atol=1e-08 was calibrated for double-precision (float64), running numpy.allclose on 32-bit floats frequently fails because the precision limit of float32 is approximately 1.19e-07. For float32 data, explicitly set atol=1e-5 and rtol=1e-4.

3. Mismatched Array Shapes Passing Silently

If two arrays have different shapes that are nonetheless broadcast-compatible (for example, comparing a 1D vector of length 5 against a 2D array of shape (5, 5)), allclose performs broadcasting and evaluates closeness across the expanded dimensions. If structural equivalence is required, verify that a.shape == b.shape prior to invoking allclose.

4. Unexpected False Results Due to Unflagged NaNs

When an experimental dataset contains missing observations represented by np.nan, allclose evaluates to False even if the NaN markers occur in identical positions. If matching missing data points should be regarded as valid, set equal_nan=True.

Free alternatives (table)

The table below summarizes free, open-source functions and testing tools available in Python and standard libraries for numerical array and scalar comparison.

Function / Tool Library / Ecosystem Return Type Tolerance Parameters NaN Handling Primary Research Use Case
numpy.allclose NumPy Scalar bool rtol, atol equal_nan=False (configurable) Validation gate across entire arrays in analytical pipelines
numpy.isclose NumPy Boolean array rtol, atol equal_nan=False (configurable) Pinpointing specific diverging elements across multidimensional arrays
numpy.array_equal NumPy Scalar bool None (exact bitwise) equal_nan=False (configurable) Strict discrete and integer array equality checks without tolerance
numpy.array_equiv NumPy Scalar bool None (exact bitwise) Exact comparison Testing exact equality with automatic shape broadcasting
numpy.testing.assert_allclose NumPy (testing module) None (raises AssertionError) rtol, atol equal_nan=True by default Automated unit testing with descriptive error reporting on failure
math.isclose Python standard library Scalar bool rel_tol, abs_tol NaN != NaN Single scalar float comparisons without external library dependencies

FAQ

What is the difference between numpy allclose and numpy isclose?

numpy.allclose returns a single scalar boolean (True or False) summarizing whether all elements in the compared arrays fall within the specified tolerances. In contrast, numpy.isclose returns a boolean array of the same shape indicating element-by-element satisfaction of the tolerance condition. In practice, numpy.allclose(a, b) is logically equivalent to numpy.all(numpy.isclose(a, b)).

Why is numpy allclose not symmetric?

The closeness condition is evaluated as |a - b| ≤ atol + rtol × |b|. Because the relative tolerance rtol is multiplied specifically by the magnitude of b, switching the positions of a and b alters the allowable tolerance threshold whenever |a| ≠ |b|. In scientific analysis, b should consistently represent the authoritative reference or baseline standard.

What are the default tolerance values in numpy allclose?

The default relative tolerance (rtol) is 1e-05 (0.001%), and the default absolute tolerance (atol) is 1e-08. These defaults are designed for double-precision 64-bit floating-point arithmetic.

How should I compare single-precision (float32) arrays with numpy allclose?

For 32-bit floating-point arrays, machine epsilon is approximately 1.19e-07. Because the default absolute tolerance of 1e-08 is smaller than machine epsilon, you should widen the tolerances to rtol=1e-04 and atol=1e-05 to avoid spurious comparison failures caused by standard single-precision rounding.

How does numpy allclose treat NaN and infinite values?

By default, numpy.allclose treats NaN as unequal to any value, including another NaN (returning False). Passing equal_nan=True causes paired NaN values at identical indices to evaluate as equal. Infinite values (np.inf and -np.inf) evaluate as equal only when they share the exact same sign and position in both arrays.

Sources

  • NumPy Developers. (2026). numpy.allclose. NumPy v2.2 Reference Documentation. URL: https://numpy.org/doc/stable/reference/generated/numpy.allclose.html (read 2026-11-10).
  • NumPy Developers. (2026). numpy.isclose. NumPy v2.2 Reference Documentation. URL: https://numpy.org/doc/stable/reference/generated/numpy.isclose.html (read 2026-11-10).
  • Python Software Foundation. (2026). Floating Point Arithmetic: Issues and Limitations. Python 3.12 Documentation. URL: https://docs.python.org/3/tutorial/floatingpoint.html (read 2026-11-10).
  • Python Software Foundation. (2026). PEP 485 – A Function for testing approximate equality. Python Enhancement Proposals. URL: https://peps.python.org/pep-0485/ (read 2026-11-10).

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about NumPy allclose: Floating-Point Tolerance Guide

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →