in src/lighteval/metrics/utils/math_comparison.py [0:0]
def sympy_numeric_eq(a: Basic | MatrixBase, b: Basic | MatrixBase, precision: int):
"""Compare two sympy expressions numerically with given precision.
Args:
a: First sympy expression
b: Second sympy expression
precision: Number of decimal places to compare
Returns:
True if expressions are numerically equal within precision, False otherwise
"""
# Only do this when one of the two is a float, in other cases use symbolic equality as this could lead to false positives
# E.g we want 1/3 == 0.333333 to work
if isinstance(a, (MatrixBase, MatrixExpr)) and isinstance(b, (MatrixBase, MatrixExpr)):
a = safe_sympy_doit(a)
b = safe_sympy_doit(b)
# If we have matrices and one of them is only made of floats, we can use the same logic as above
if isinstance(a, (MatrixBase)) and isinstance(b, (MatrixBase)) and a.shape == b.shape:
return all(sympy_numeric_eq(a_elem, b_elem, precision) for a_elem, b_elem in zip(a.flat(), b.flat()))
# Ensure this also works for percentage numbers so that 0.333333% = 0.33333333333 with precision 4
elif is_atomic_or_pct_atomic(a, Number) or is_atomic_or_pct_atomic(b, Number):
# If one of them is a float or a negative atomic number, we can try to use precision
if is_atomic_or_pct_atomic(a, Float) or is_atomic_or_pct_atomic(b, Float):
a = safe_sympy_doit(a)
b = safe_sympy_doit(b)
# Now if both are numbers, we can use precision
if isinstance(a, (Number)) and isinstance(b, (Number)):
return a.round(precision) == b.round(precision)
else:
return safe_sympy_doit(a) == safe_sympy_doit(b)
else:
try:
return (a - b).evalf(chop=True) == 0 # type: ignore
except TimeoutError:
raise
except Exception: # noqa: E722
pass
return False