sc: stop over-solving the solver's quadratic subproblem
Each major iteration of the sequential quadratic solver solves a quadratic subproblem with Frank-Wolfe, where every inner step is a CoinMP linear solve. The loop ran until the duality gap fell below a tiny absolute floor, which on harder models meant many inner linear solves spent driving the gap to a precision the outer loop does not need: it re-samples and re-solves around the accepted step anyway. Also stop once the gap has shrunk to a small fraction of its value on the first inner step. The step is then good enough to accept, and the outer trust-region loop corrects any remaining error. This cuts inner linear solves with no loss of solution quality: on the resource model the solver still reaches the same optimum. Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> Change-Id: I80d118176840ab6c63ac939f962e8f8d3bb9a3b9 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4924 Tested-by: Jenkins CPCI <releng@collaboraoffice.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit b63997355fee236cded23bc32e813bc412ed8984) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209439 Tested-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Tested-by: Jenkins
This commit is contained in:
committed by
Xisco Fauli
parent
8e0d1c26c5
commit
508dfcabb8
@@ -373,6 +373,8 @@ SLPSolver::solveTrustRegionQp(const ScSolverCellHashMap& rCells, const std::vect
|
||||
|
||||
constexpr int nMaxFrankWolfe = 50;
|
||||
constexpr double fGapTolerance = 1.0e-9;
|
||||
constexpr double fGapFraction = 1.0e-3;
|
||||
double fInitialGap = 0.0;
|
||||
for (int nFrankWolfe = 0; nFrankWolfe < nMaxFrankWolfe; ++nFrankWolfe)
|
||||
{
|
||||
// Gradient of the quadratic model at the current step: B d + g.
|
||||
@@ -399,7 +401,13 @@ SLPSolver::solveTrustRegionQp(const ScSolverCellHashMap& rCells, const std::vect
|
||||
|
||||
// Duality gap: how much the linear model could still improve.
|
||||
double fGap = -dotProduct(aQuadraticGradient, aDirection);
|
||||
if (fGap < fGapTolerance)
|
||||
if (nFrankWolfe == 0)
|
||||
fInitialGap = fGap;
|
||||
// Stop once the subproblem is solved well enough: the gap has shrunk to
|
||||
// a small fraction of its initial value, or below an absolute floor.
|
||||
// Driving the gap all the way to zero is wasted work, because the outer
|
||||
// trust-region loop re-samples and re-solves around the accepted step.
|
||||
if (fGap < fGapTolerance || fGap < fGapFraction * fInitialGap)
|
||||
break;
|
||||
|
||||
// Exact line search of the quadratic along the Frank-Wolfe direction.
|
||||
|
||||
Reference in New Issue
Block a user