From 8dea6b8a55d6865d68fba6dbe627a264e26ff188 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Tue, 13 Feb 2024 10:25:36 +0100 Subject: [PATCH] verif: Add `check_result` function to check for errors and compute error --- util/sim/data_utils.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/util/sim/data_utils.py b/util/sim/data_utils.py index a6b1350ad2..c8a77af4d1 100644 --- a/util/sim/data_utils.py +++ b/util/sim/data_utils.py @@ -211,3 +211,29 @@ def from_buffer(byte_array, ctype='uint32_t'): value *= -1 array.append(value) return array + + +def check_result(expected, actual, atol=None, rtol=None): + """Check if the actual result is within the expected range. + + Args: + expected: The expected result. + actual: The actual result. + atol: Absolute tolerance. The maximum absolute difference between + the expected and actual result. Mutually exclusive with `rtol`. + rtol: Relative tolerance. The maximum relative difference between + the expected and actual result. Mutually exclusive with `atol`. + """ + if atol is not None and rtol is not None: + raise ValueError('atol and rtol are mutually exclusive.') + if atol is not None: + fail = np.allclose(expected, actual, atol=atol, equal_nan=False) + error = np.abs(expected - actual) + elif rtol is not None: + fail = np.allclose(expected, actual, rtol=rtol, equal_nan=False) + scale = np.maximum(np.abs(expected), np.abs(actual)) + scale[scale == 0] = 1 # Avoid division by zero, use absolute tolerance instead + error = np.abs(expected - actual) / scale + else: + raise ValueError('Either atol or rtol must be specified.') + return fail, error