Exact match of math if and only if: 1. numerical equal: both can convert to float and are equal 2. symbolic equal: both can convert to sympy expression and are equal
(
prediction: Union[bool, float, str],
reference: Union[float, str],
include_percentage: bool = True,
tolerance: float = 1e-4,
timeout: float = 10.0,
pi: float = math.pi
)
| 162 | return string |
| 163 | |
| 164 | def math_equal( |
| 165 | prediction: Union[bool, float, str], |
| 166 | reference: Union[float, str], |
| 167 | include_percentage: bool = True, |
| 168 | tolerance: float = 1e-4, |
| 169 | timeout: float = 10.0, |
| 170 | pi: float = math.pi |
| 171 | ) -> bool: |
| 172 | """ |
| 173 | Exact match of math if and only if: |
| 174 | 1. numerical equal: both can convert to float and are equal |
| 175 | 2. symbolic equal: both can convert to sympy expression and are equal |
| 176 | """ |
| 177 | |
| 178 | prediction = normalize(prediction, pi) |
| 179 | reference = normalize(reference, pi) |
| 180 | |
| 181 | if isinstance(prediction, str) and len(prediction) > 1000: # handling weird corner-cases |
| 182 | prediction = prediction[:1000] |
| 183 | |
| 184 | # 0. string comparison |
| 185 | if isinstance(prediction, str) and isinstance(reference, str): |
| 186 | if prediction.strip().lower() == reference.strip().lower(): |
| 187 | return True |
| 188 | if prediction.replace(" ", "") == reference.replace(" ", ""): |
| 189 | return True |
| 190 | |
| 191 | try: # 1. numerical equal |
| 192 | if is_digit(prediction)[0] and is_digit(reference)[0]: |
| 193 | prediction = is_digit(prediction)[1] |
| 194 | reference = is_digit(reference)[1] |
| 195 | # number questions |
| 196 | if include_percentage: |
| 197 | gt_result = [reference / 100, reference, reference * 100] |
| 198 | else: |
| 199 | gt_result = [reference] |
| 200 | for item in gt_result: |
| 201 | try: |
| 202 | if isclose(item, prediction, rel_tol=tolerance): |
| 203 | return True |
| 204 | except Exception: |
| 205 | continue |
| 206 | return False |
| 207 | except Exception: |
| 208 | pass |
| 209 | |
| 210 | if not prediction and prediction not in [0, False]: |
| 211 | return False |
| 212 | |
| 213 | # 2. symbolic equal |
| 214 | reference = str(reference).strip() |
| 215 | prediction = str(prediction).strip() |
| 216 | |
| 217 | ## deal with [], (), {} |
| 218 | prediction = format_intervals(prediction) |
| 219 | |
| 220 | pred_str, ref_str = prediction, reference |
| 221 | if (prediction.startswith("[") and prediction.endswith("]") and not reference.startswith("(")) or ( |
no test coverage detected