You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part A (rapid infeasibility detection): shipped. Landed in 8a711f3 ("feat(conv): rapid infeasibility detection in the main loop") and widened by 84a8ef1 ("Widen locally-infeasible detection to inner-failure exits"). On by default (infeas_stationarity_tol = 1e-8, infeas_max_streak = 5); regression test at crates/pounce-restoration/tests/infeas_detection_benefit.rs. Design note status header: dev-notes/research/penalty-ipm-infeasibility-detection.md §3.
Strategy #5 has two separable halves. The note recommends shipping the detection half first — it is small, low-risk, and high value on its own.
Part A — rapid infeasibility detection (SHIPPED)
A cheap per-iteration test that recognizes convergence to a stationary point of the infeasibility measure with ‖c(x)‖ bounded away from zero, and exits immediately with LocalInfeasibility instead of grinding to max_iter or thrashing restoration.
held for N consecutive iterations (e.g. N = 5) — a streak counter.
Jᵀc is already computable from curr_jac_* / curr_c / curr_d_minus_s in ipopt_cq.rs — no new linear solve, a few inner products per iteration.
As shipped:IpoptCalculatedQuantities::curr_infeasibility_stationarity (ipopt_cq.rs:767), ConvergenceStatus::LocallyInfeasible (conv_check/trait.rs:34), streak fields + gate in OptErrorConvCheck (conv_check/opt_error.rs), main-loop mapping in ipopt_alg.rs:475 → SolverReturn::LocalInfeasibility, options in upstream_options.rs / application.rs / alg_builder.rs.
Why first: removes three hand-tuned, fragile cycle detectors in invoke_restoration (ipopt_alg.rs:984-1052) with a principled test; faithful to Ipopt's IpRestoConvCheck.cppLOCALLY_INFEASIBLE, of which pounce previously had only the restoration-side half.
Part B — penalty-IPM (proposed second, multi-week)
A true penalty-IPM modifies the KKT system: barrier problem becomes min f(x) + ν‖c(x)‖₁ + barrier, constraints enter as penalized elastic variables, steering rule drives ν from predicted infeasibility reduction (Curtis–Nocedal–Wächter 2010). Reuses the restoration NLP's 5-block elastic reformulation applied to the main problem; shares the feasibility direction with strategy #4's normal step. Should not start until #4 Phase 1 is evaluated.
Note: pounce already has a PenaltyLsAcceptor (penalty-based globalization, not a full penalty-IPM) and a pounce-l1penalty crate.
Open questions
Default Part A on?Resolved: yes, default on (infeas_stationarity_tol = 1e-8, infeas_max_streak = 5).
Retire the three cycle detectors immediately or keep one release as belt-and-suspenders? (Recommendation in design note: leave for one release, measure overlap, then delete.)
Tune infeas_stationarity_tol, κ, N on the restoration-heavy subset (S365, S365MOD, PFIT1/4, ACOPR family).
Status
8a711f3("feat(conv): rapid infeasibility detection in the main loop") and widened by84a8ef1("Widen locally-infeasible detection to inner-failure exits"). On by default (infeas_stationarity_tol = 1e-8,infeas_max_streak = 5); regression test atcrates/pounce-restoration/tests/infeas_detection_benefit.rs. Design note status header:dev-notes/research/penalty-ipm-infeasibility-detection.md§3.Summary
Follow-up to land SOTA feasibility-restoration strategy #5. Full design note:
dev-notes/research/penalty-ipm-infeasibility-detection.md.Strategy #5 has two separable halves. The note recommends shipping the detection half first — it is small, low-risk, and high value on its own.
Part A — rapid infeasibility detection (SHIPPED)
A cheap per-iteration test that recognizes convergence to a stationary point of the infeasibility measure with
‖c(x)‖bounded away from zero, and exits immediately withLocalInfeasibilityinstead of grinding tomax_iteror thrashing restoration.The test fires when all three hold:
θ = ‖c(x)‖ > κ · constr_viol_tol(e.g.κ = 100) — violation bounded away from zero;‖J(x)ᵀc(x)‖ / max(1, ‖c(x)‖)below a tight tolerance — infeasibility stationary;Nconsecutive iterations (e.g.N = 5) — a streak counter.Jᵀcis already computable fromcurr_jac_*/curr_c/curr_d_minus_sinipopt_cq.rs— no new linear solve, a few inner products per iteration.As shipped:
IpoptCalculatedQuantities::curr_infeasibility_stationarity(ipopt_cq.rs:767),ConvergenceStatus::LocallyInfeasible(conv_check/trait.rs:34), streak fields + gate inOptErrorConvCheck(conv_check/opt_error.rs), main-loop mapping inipopt_alg.rs:475→SolverReturn::LocalInfeasibility, options inupstream_options.rs/application.rs/alg_builder.rs.Why first: removes three hand-tuned, fragile cycle detectors in
invoke_restoration(ipopt_alg.rs:984-1052) with a principled test; faithful to Ipopt'sIpRestoConvCheck.cppLOCALLY_INFEASIBLE, of which pounce previously had only the restoration-side half.Part B — penalty-IPM (proposed second, multi-week)
A true penalty-IPM modifies the KKT system: barrier problem becomes
min f(x) + ν‖c(x)‖₁ + barrier, constraints enter as penalized elastic variables, steering rule drivesνfrom predicted infeasibility reduction (Curtis–Nocedal–Wächter 2010). Reuses the restoration NLP's 5-block elastic reformulation applied to the main problem; shares the feasibility direction with strategy #4's normal step. Should not start until #4 Phase 1 is evaluated.Note: pounce already has a
PenaltyLsAcceptor(penalty-based globalization, not a full penalty-IPM) and apounce-l1penaltycrate.Open questions
Default Part A on?Resolved: yes, default on (infeas_stationarity_tol = 1e-8,infeas_max_streak = 5).infeas_stationarity_tol,κ,Non the restoration-heavy subset (S365, S365MOD, PFIT1/4, ACOPR family).PenaltyLsAcceptor+ Part A sufficient coverage of strategy Add Thierry-Biegler l1-exact penalty-barrier phase for degenerate NLPs #5?In-tree reference:
ref/Ipopt/src/Algorithm/IpRestoConvCheck.cpp.