Files
Raptor/validation/tests/test_output_comparison.py
T
NiccoloN a77edafcbf
Validate Operations / validate-operations (push) Has been cancelled
even better more structured throughput scheduling
plot adjustments
validation adjustments
2026-10-27 17:46:46 +01:00

76 lines
2.8 KiB
Python

from pathlib import Path
import sys
import numpy as np
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from raptor_validation.output_comparison import compare_output_arrays
def test_absolute_floor_does_not_accept_lost_small_output():
result = compare_output_arrays(np.zeros(2), np.array([1e-4, -2e-4]), atol=1e-3, rtol=1e-4)
assert result.pointwise_passed
assert result.relative_l2_error == pytest.approx(1)
assert not result.passed
@pytest.mark.parametrize("scale", [1e-200, 1e-4, 1, 1e200])
def test_small_relative_roundoff_is_independent_of_scale(scale):
expected = np.array([1, -2, 3], dtype=np.float64) * scale
result = compare_output_arrays(expected * (1 + 1e-6), expected, atol=1e-3, rtol=1e-4)
assert result.passed
assert result.relative_l2_error == pytest.approx(1e-6)
def test_norm_agreement_cannot_hide_an_incorrect_small_element():
result = compare_output_arrays([1e6, .01], [1e6, 0.0], atol=1e-3, rtol=1e-4)
assert result.relative_l2_error < 1e-4
assert not result.pointwise_passed
assert not result.passed
@pytest.mark.parametrize("actual,expected", [([np.inf], [1.0]), ([1.0], [np.inf]),
([np.inf], [np.inf]), ([np.nan], [np.nan])])
def test_nonfinite_outputs_never_pass(actual, expected):
assert not compare_output_arrays(actual, expected, atol=1e-3, rtol=1e-4).passed
@pytest.mark.parametrize("actual,expected", [([1.0], [[1.0]]), ([1.0], [])])
def test_broadcasting_cannot_hide_output_shape_errors(actual, expected):
with pytest.raises(ValueError, match="shapes differ"):
compare_output_arrays(actual, expected, atol=1e-3, rtol=1e-4)
def test_zero_reference_retains_absolute_check():
result = compare_output_arrays([1e-6], [0.0], atol=1e-3, rtol=1e-4)
assert result.passed and result.relative_l2_error is None
assert not compare_output_arrays([.01], [0.0], atol=1e-3, rtol=1e-4).passed
def test_zero_relative_tolerance_requests_absolute_only_check():
result = compare_output_arrays([0.0], [1e-4], atol=1e-3, rtol=0)
assert result.passed
def test_integer_outputs_require_exact_agreement_without_float_rounding():
expected = np.array([2**53], np.int64)
result = compare_output_arrays(expected + 1, expected, atol=1e-3, rtol=1e-4)
assert not result.passed and result.max_abs_diff == 1
def test_empty_outputs_match():
assert compare_output_arrays([], [], atol=1e-3, rtol=1e-4).passed
@pytest.mark.parametrize("atol,rtol", [(-1, 0), (0, -1), (np.inf, 0), (0, np.nan)])
def test_invalid_tolerances_are_rejected(atol, rtol):
with pytest.raises(ValueError, match="tolerances"):
compare_output_arrays([0.0], [0.0], atol=atol, rtol=rtol)
def test_complex_outputs_are_not_silently_cast_to_real():
with pytest.raises(ValueError, match="real numeric"):
compare_output_arrays([1 + 2j], [1 + 0j], atol=1e-3, rtol=1e-4)