Skip to main content

Module ftb_floor

Module ftb_floor 

Source
Expand description

Centrality-floored fraction-to-the-boundary (pounce gh#1098).

Ipopt’s rule α = τ·α_bnd, τ = max(τ_min, 1 − μ), lets the slack or bound multiplier that blocks a step land at (1 − τ) ≈ μ of its value once μ is small. A blocking pair that sat on the central path (s·v ≈ μ) is then knocked to s·v ≈ μ², six orders off it at μ = 1.8e-6, and when the next direction reverses the step the solver spends 5–10 iterations recentering it. On Mittelmann qcqp1500-1nc that cycle is the whole of the crawl: a walk from vertex to vertex of a nonconvex polytope at ~15 iterations per net change of active set, for ~1200 iterations at a fixed μ (Ipopt 3.14 crawls identically).

The remedy is Mehrotra’s step-length heuristic (Mehrotra 1992 §5; Wright, Primal-Dual Interior-Point Methods, eq. (10.9)): keep a 1 − γ floor on the fraction, but let the step approach the boundary beyond it only while the blocking pair’s complementarity product stays ≥ γ·μ, so a variable driven to its bound lands near its central value instead of at μ of itself.

It is applied only to a blocking pair that is currently centered (s·v ≥ γ·μ). The rule presumes a neighbourhood of the central path; a pair already far below it has no centrality to preserve, and holding its step at 1 − γ only slows its way to zero. Measured on Mittelmann clnlbeam (a bang-bang switching point migrating across 39 998 doubly-bounded variables whose blockers sit at s·v/μ ≈ 1e-3…1e-6): the uncentered rule hit max_iter where the default converges.

The floored step is capped at the τ rule’s step, so the floor only ever shortens a step. Uncapped, a pair far above the central path early on (s·v = 9 at μ = 0.1) was allowed a longer step than τ and landed at γμ, less central than upstream leaves it; that flipped issue_390_nonlinear_equality_scale at row scale 1e-8 from an infeasibility certificate to Restoration_Failed.

Off by default (γ = 0 restores upstream’s rule exactly). Even capped, at γ = 0.01 it is the only setting measured that solves Mittelmann qcqp1500-1c (148 iterations; main and the default both hit the CPU limit), but it also turns the discs fixture into a false Infeasible_Problem_Detected on the exact leg and changes the verdict of three purpose-built integration tests (issue_884, masked_certificate_fuzz with the certificate veto off, line_search_options_wiring). The measured opt-in for gh#1098 is perturb_slack_fact=0.03 alone.

Constants§

DEFAULT_FTB_CENTRALITY_FLOOR
Registered default of ftb_centrality_floor (γ).
DEFAULT_PERTURB_SLACK_FACT
Registered default of perturb_slack_fact (δ_s = fact · δ_x). 1 is upstream Ipopt’s tie; 0.03 solves gh#1098 but is opt-in, see the option’s registration and dev-notes/qcqp1500-crawl-slack-perturbation.md.
DEFAULT_PERTURB_SLACK_MAX_ROWS
Registered default of perturb_slack_max_rows (δ_s = fact · min(1, max_rows / m_d) · δ_x). On a model with at most this many inequality rows the rule is upstream’s exactly; above it the slack-block perturbation is scaled down so that δ_s · m_d stays at the level a model with max_rows rows would see. 0 disables the cap. See PdPerturbationHandler::delta_s_fact_effective and dev-notes/qcqp1500-crawl-slack-perturbation.md.

Functions§

floored_alphas
Returns Some((alpha_p, alpha_d)) or None when a block is not a dense vector (restoration’s compound iterates); the caller then keeps the ordinary τ rule.