modify tolerance policy

This commit is contained in:
KOKO\Mimi
2026-08-18 02:29:26 +09:00
parent 123a1b6ccc
commit 624ea4872c
36 changed files with 1909 additions and 672 deletions
@@ -458,11 +458,11 @@ const fesa::test::Mitc4RowDecision* FindRow(
const fesa::test::Mitc4ComponentMetrics* FindMetric(
const fesa::test::Mitc4ComparisonReport& report,
const std::string& component) {
const std::string& family_identity) {
const auto found =
std::find_if(report.metrics.begin(), report.metrics.end(),
[&](const fesa::test::Mitc4ComponentMetrics& metric) {
return metric.component == component;
return metric.family_identity == family_identity;
});
return found == report.metrics.end() ? nullptr : &*found;
}
@@ -496,6 +496,9 @@ TEST(Mitc4ReferenceComparison,
EXPECT_EQ(report.rows[0U].component, "U1");
EXPECT_EQ(report.rows[5U].component, "UR3");
EXPECT_EQ(report.rows[6U].source_node_label, 2);
ASSERT_EQ(report.metrics.size(), 2U);
EXPECT_EQ(report.metrics[0U].row_count, 6U);
EXPECT_EQ(report.metrics[1U].row_count, 6U);
EXPECT_TRUE(std::all_of(report.rows.begin(), report.rows.end(),
[](const fesa::test::Mitc4RowDecision& row) {
return row.case_id == "shell-contract" &&
@@ -588,7 +591,7 @@ TEST(Mitc4ReferenceComparison, RejectsInvalidInventoryBeforeNumericComparison) {
// MITC4-REF-003
TEST(Mitc4ReferenceComparison,
AppliesFixedAbsoluteToleranceWithoutScaleClampOrRowDenominator) {
SharesTranslationScaleAcrossUComponentsAndUsesNearZeroBranches) {
ContractFixture fixture{"tolerance"};
auto reference = DefaultRows();
reference[0U].values[0U] = 0.0;
@@ -597,10 +600,10 @@ TEST(Mitc4ReferenceComparison,
reference[1U].values[1U] = 0.0;
WriteCsv(fixture.Csv(), reference);
auto fesa_values = reference;
fesa_values[0U].values[0U] = 0.9999e-5;
fesa_values[1U].values[0U] += 1.0001e-5;
fesa_values[0U].values[1U] = 0.9999e-5;
fesa_values[1U].values[1U] = 1.0001e-5;
fesa_values[0U].values[0U] = 0.999 * 8.0e-2;
fesa_values[1U].values[0U] += 1.001e-1;
fesa_values[0U].values[1U] = 0.999 * 8.0e-2;
fesa_values[1U].values[1U] = 1.001 * 8.0e-2;
WriteHdf5(fixture.Results(), fixture.Input(), fesa_values);
auto result =
@@ -616,25 +619,21 @@ TEST(Mitc4ReferenceComparison,
ASSERT_NE(u1_scaled, nullptr);
ASSERT_NE(u2_near, nullptr);
ASSERT_NE(u2_over, nullptr);
EXPECT_DOUBLE_EQ(u1_zero->tolerance, 1.0e-5);
EXPECT_DOUBLE_EQ(u1_zero->tolerance, 8.0e-2);
EXPECT_TRUE(u1_zero->within_tolerance);
EXPECT_NEAR(u1_zero->normalized_error, 0.9999, 1.0e-12);
EXPECT_FALSE(u1_zero->relative_error_applicable);
EXPECT_FALSE(u1_scaled->within_tolerance);
EXPECT_NEAR(u1_scaled->normalized_error, 1.0001, 2.0e-11);
EXPECT_DOUBLE_EQ(u2_near->tolerance, 1.0e-5);
EXPECT_NEAR(u1_scaled->normalized_error, 0.05005, 1.0e-12);
EXPECT_DOUBLE_EQ(u2_near->tolerance, 8.0e-2);
EXPECT_TRUE(u2_near->within_tolerance);
EXPECT_NEAR(u2_near->normalized_error, 0.9999, 1.0e-12);
EXPECT_FALSE(u2_near->relative_error_applicable);
EXPECT_FALSE(u2_over->within_tolerance);
EXPECT_NEAR(u2_over->normalized_error, 1.0001, 1.0e-12);
for (const auto& row : report.rows) {
EXPECT_DOUBLE_EQ(row.tolerance, 1.0e-5);
}
for (const auto& metric : report.metrics) {
EXPECT_DOUBLE_EQ(metric.tolerance, 1.0e-5);
}
const auto* u1_metric = FindMetric(report, "U1");
ASSERT_NE(u1_metric, nullptr);
EXPECT_DOUBLE_EQ(u1_metric->reference_scale, 2.0);
EXPECT_DOUBLE_EQ(u2_over->tolerance, 8.0e-2);
const auto* translation = FindMetric(report, "displacement-translation");
ASSERT_NE(translation, nullptr);
EXPECT_DOUBLE_EQ(translation->reference_scale, 8.0);
EXPECT_EQ(translation->components,
(std::vector<std::string>{"U1", "U2", "U3"}));
}
// MITC4-REF-004
@@ -650,8 +649,9 @@ TEST(Mitc4ReferenceComparison,
ASSERT_TRUE(result.HasValue());
const auto& report = result.Value();
EXPECT_TRUE(report.passed);
ASSERT_EQ(report.warnings.size(), 1U);
ASSERT_EQ(report.warnings.size(), 2U);
EXPECT_EQ(report.warnings[0U].code, "rotation-reference-exceedance");
EXPECT_EQ(report.warnings[1U].code, "rotation-reference-rms-exceedance");
const auto* row = FindRow(report, 1, "UR1");
ASSERT_NE(row, nullptr);
EXPECT_FALSE(row->blocking);
@@ -663,6 +663,47 @@ TEST(Mitc4ReferenceComparison,
EXPECT_NE(report.warnings[0U].message.find("UR1"), std::string::npos);
}
TEST(Mitc4ReferenceComparison,
RotationRmsExceedanceWarnsWhenEveryRotationRowPasses) {
ContractFixture fixture{"rotation-rms"};
auto fesa_values = DefaultRows();
fesa_values[1U].values[3U] = 0.1049;
fesa_values[1U].values[4U] = -0.2098;
fesa_values[1U].values[5U] = 0.3147;
WriteHdf5(fixture.Results(), fixture.Input(), fesa_values);
auto result =
fesa::test::Mitc4ReferenceComparison::Compare(fixture.ReferenceCase());
ASSERT_TRUE(result.HasValue());
const auto& report = result.Value();
EXPECT_TRUE(report.passed);
ASSERT_EQ(report.warnings.size(), 1U);
EXPECT_EQ(report.warnings[0U].code, "rotation-reference-rms-exceedance");
EXPECT_TRUE(std::all_of(report.rows.begin(), report.rows.end(),
[](const fesa::test::Mitc4RowDecision& row) {
return row.within_tolerance;
}));
}
TEST(Mitc4ReferenceComparison,
RotationRowAndRmsExceedancesProduceSeparateWarnings) {
ContractFixture fixture{"rotation-row-and-rms"};
auto fesa_values = DefaultRows();
fesa_values[0U].values[3U] = 1.0;
WriteHdf5(fixture.Results(), fixture.Input(), fesa_values);
auto result =
fesa::test::Mitc4ReferenceComparison::Compare(fixture.ReferenceCase());
ASSERT_TRUE(result.HasValue());
const auto& report = result.Value();
EXPECT_TRUE(report.passed);
ASSERT_EQ(report.warnings.size(), 2U);
EXPECT_EQ(report.warnings[0U].code, "rotation-reference-exceedance");
EXPECT_EQ(report.warnings[1U].code, "rotation-reference-rms-exceedance");
EXPECT_LT(report.warnings[0U].row, report.rows.size());
EXPECT_LT(report.warnings[1U].row, report.rows.size());
}
// MITC4-REF-005
TEST(Mitc4ReferenceComparison,
ReportsMetricsVectorsWorstRowAndJsonDeterministically) {
@@ -678,7 +719,7 @@ TEST(Mitc4ReferenceComparison,
ASSERT_TRUE(result.HasValue());
const auto& report = result.Value();
ASSERT_TRUE(report.passed);
ASSERT_EQ(report.metrics.size(), 6U);
ASSERT_EQ(report.metrics.size(), 2U);
ASSERT_EQ(report.vector_metrics.size(), 2U);
EXPECT_NEAR(report.vector_metrics[0U].displacement_norm_error,
std::sqrt(0.3125) * 1.0e-9, 1.0e-21);
@@ -687,10 +728,10 @@ TEST(Mitc4ReferenceComparison,
EXPECT_EQ(report.rows[report.worst_row].component, "UR1");
for (const auto& metric : report.metrics) {
EXPECT_TRUE(std::isfinite(metric.reference_scale));
EXPECT_TRUE(std::isfinite(metric.near_zero_band));
EXPECT_TRUE(std::isfinite(metric.maximum_absolute_error));
EXPECT_TRUE(std::isfinite(metric.maximum_normalized_error));
EXPECT_TRUE(std::isfinite(metric.rms_error));
EXPECT_TRUE(std::isfinite(metric.vector_norm_error));
EXPECT_TRUE(std::isfinite(metric.relative_rms));
EXPECT_FALSE(metric.components.empty());
EXPECT_LT(metric.worst_row, report.rows.size());
}
@@ -704,8 +745,10 @@ TEST(Mitc4ReferenceComparison,
.IsOk());
const std::string first = ReadBytes(json_a);
EXPECT_EQ(first, ReadBytes(json_b));
for (const char* key : {"\"rows\"", "\"metrics\"", "\"vector_metrics\"",
"\"warnings\"", "\"worst_row\"", "\"passed\""}) {
for (const char* key :
{"\"rows\"", "\"metrics\"", "\"vector_metrics\"", "\"warnings\"",
"\"family_identity\"", "\"near_zero_band\"", "\"relative_rms\"",
"\"row_count\"", "\"worst_row\"", "\"passed\""}) {
EXPECT_NE(first.find(key), std::string::npos) << key;
}
}