Add frozen polynomial positivity probes and tighten certificate diagnostics

This commit is contained in:
2026-09-17 09:31:31 -04:00
parent dfba40b1f5
commit 97204a3253
3 changed files with 213 additions and 2 deletions

View File

@@ -135,6 +135,11 @@ export namespace mean_field::solver {
EnthalpyAdmissibilityOptions options = {}) const {
enthalpy_detail::ValidateOptions(options);
auto coefficients = Transform(nodalValues);
double rootLower = std::numeric_limits<double>::infinity(), rootUpper = -rootLower;
for (const auto &coefficient : coefficients) {
rootLower = std::min(rootLower,coefficient.lo);
rootUpper = std::max(rootUpper,coefficient.hi);
}
struct Cell { std::vector<Interval> coefficients; int depth; std::array<double,3> lo, hi; };
std::vector<Cell> pending;
pending.push_back({std::move(coefficients), 0, {0,0,0}, {1,1,1}});
@@ -164,8 +169,8 @@ export namespace mean_field::solver {
}
if (cell.coefficients[index].hi < 0.0) {
report.status = PolynomialSignStatus::negative;
report.lowerBound = lower;
report.upperBound = upper;
report.lowerBound = rootLower;
report.upperBound = rootUpper;
for (int axis = 0; axis < Dimension; ++axis)
report.witnessReferencePoint[axis] = (corner & (1<<axis)) ? cell.hi[axis] : cell.lo[axis];
return report;
@@ -433,6 +438,14 @@ export namespace mean_field::solver {
if (report.anchor.status != PolynomialSignStatus::certified_nonnegative || !ZeroTrace(anchor)) {
report.status = EnthalpyDirectionRepairStatus::invalid_anchor; return report;
}
bool finiteDirection = true;
for (int i = 0; i < direction.Size(); ++i)
finiteDirection = finiteDirection && std::isfinite(direction(i));
if (enthalpy_detail::CollectiveMaximum(finiteDirection ? 0 : 1,m_space->GetComm())) {
report.status = EnthalpyDirectionRepairStatus::invalid_direction;
report.candidate.status = PolynomialSignStatus::non_finite;
return report;
}
mfem::Vector candidate(base); candidate += direction;
for (int row : m_zeroTrace) candidate(row) = 0.0;
report.candidate = Check(candidate);