存档求解器回归基线与当前改动

纳管 AMESim 对齐基线、发布锁、回归测试及当前物理门禁调整。

更新日志仅记录已完成成果,并注明当前 HEAD 尚待真实 production 复跑与远端 workflow 验证。
This commit is contained in:
lujingze committed 2026-08-18 15:20:42 +00:00
1 parent 53f8601fec
commit a8c733883c
32 files changed
+47241 -108

No files matched your search

@@ -23,6 +23,8 @@ class TestMqlComparisonMetric:
max_abs_error: float
mean_abs_error: float
max_rel_error: float
undefined_rel_error_count: int
near_zero_baseline_count: int
final_abs_error: float
@@ -44,6 +46,10 @@ class TestMqlComparisonResult:
def max_rel_error(self) -> float:
return max((metric.max_rel_error for metric in self.metrics), default=0.0)
@property
def undefined_rel_error_count(self) -> int:
return sum(metric.undefined_rel_error_count for metric in self.metrics)
class TestMqlComparisonError(ValueError):
"""Raised when Python and AMESim series cannot be aligned."""
@@ -57,6 +63,16 @@ def compare_test_mql_series(
data_paths: tuple[str, ...] | list[str] | None = None,
relative_floor: float = 1.0e-12,
) -> TestMqlComparisonResult:
"""Compare current values directly with AMESim simulation values.
``relative_floor`` only identifies near-zero baselines for reporting. It is
never substituted into the relative-error denominator. An exact zero
AMESim baseline has undefined relative error and is counted separately;
absolute error remains available for judgement.
"""
if relative_floor < 0.0:
raise TestMqlComparisonError("relative_floor cannot be negative.")
_validate_time_axis(python_times)
selected_paths = _select_data_paths(python_series_by_data_path, amesim_results, data_paths)
metrics = []
@@ -70,11 +86,18 @@ def compare_test_mql_series(
amesim_values = amesim_results.series(data_path)
abs_errors = []
rel_errors = []
undefined_rel_error_count = 0
near_zero_baseline_count = 0
for time_value, python_value in zip(python_times, python_values):
amesim_value = interpolate_series_value(amesim_results.times, amesim_values, time_value)
abs_error = abs(python_value - amesim_value)
abs_errors.append(abs_error)
rel_errors.append(abs_error / max(abs(amesim_value), relative_floor))
if abs(amesim_value) <= relative_floor:
near_zero_baseline_count += 1
if amesim_value == 0.0:
undefined_rel_error_count += 1
else:
rel_errors.append(abs_error / abs(amesim_value))
final_amesim_value = interpolate_series_value(
amesim_results.times,
amesim_values,
@@ -87,6 +110,8 @@ def compare_test_mql_series(
max_abs_error=max(abs_errors, default=0.0),
mean_abs_error=sum(abs_errors) / max(len(abs_errors), 1),
max_rel_error=max(rel_errors, default=0.0),
undefined_rel_error_count=undefined_rel_error_count,
near_zero_baseline_count=near_zero_baseline_count,
final_abs_error=abs(python_values[-1] - final_amesim_value),
)
)
@@ -153,8 +178,19 @@ def write_test_mql_comparison_csv(
float(time_value),
)
abs_error = abs(python_value - amesim_value)
rel_error = abs_error / max(abs(amesim_value), 1.0e-12)
row.extend([python_value, amesim_value, abs_error, rel_error])
rel_error = (
None
if amesim_value == 0.0
else abs_error / abs(amesim_value)
)
row.extend(
[
python_value,
amesim_value,
abs_error,
"" if rel_error is None else rel_error,
]
)
writer.writerow(row)
summary_lines = [
@@ -163,6 +199,7 @@ def write_test_mql_comparison_csv(
f"max_abs_error={metric.max_abs_error:.12g}, "
f"mean_abs_error={metric.mean_abs_error:.12g}, "
f"max_rel_error={metric.max_rel_error:.12%}, "
f"undefined_rel_error_count={metric.undefined_rel_error_count}, "
f"final_abs_error={metric.final_abs_error:.12g}"
)
for metric in comparison.metrics