From 1a53e1c32eee18d38e3d04cabf1980af06adcc22 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Mon, 21 Jan 2019 15:09:55 -0700 Subject: [PATCH] fixes #8 - change convergence checking logic to remove infinite looping (#9) * change default convergence epsilon to 1e-9 for a bit more resistance to long convergence times * change tolerance to 1e-8 to adapt to new default convergence epsilon * change test for convergence from delta-x to objective function, which catches convergence much better --- .../gibbous/optim/convex/ConvergenceEpsilon.java | 2 +- .../manyangled/gibbous/optim/convex/NewtonOptimizer.java | 8 ++++---- src/test/java/com/manyangled/gibbous/COTestingUtils.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/manyangled/gibbous/optim/convex/ConvergenceEpsilon.java b/src/main/java/com/manyangled/gibbous/optim/convex/ConvergenceEpsilon.java index 4c7b5ef..074b964 100644 --- a/src/main/java/com/manyangled/gibbous/optim/convex/ConvergenceEpsilon.java +++ b/src/main/java/com/manyangled/gibbous/optim/convex/ConvergenceEpsilon.java @@ -37,5 +37,5 @@ public ConvergenceEpsilon(double eps) { } /** Default convergence epsilon value */ - public static final double CONVERGENCE_EPSILON_DEFAULT = 1e-10; + public static final double CONVERGENCE_EPSILON_DEFAULT = 1e-9; } diff --git a/src/main/java/com/manyangled/gibbous/optim/convex/NewtonOptimizer.java b/src/main/java/com/manyangled/gibbous/optim/convex/NewtonOptimizer.java index 50ddaf6..8c5db73 100644 --- a/src/main/java/com/manyangled/gibbous/optim/convex/NewtonOptimizer.java +++ b/src/main/java/com/manyangled/gibbous/optim/convex/NewtonOptimizer.java @@ -121,8 +121,6 @@ public PointValuePair doOptimize() { KKTSolution sol = kktSolver.solve(hess, grad); if (sol.lambdaSquared <= (2.0 * epsilon)) break; RealVector xDelta = sol.xDelta; - // Halt if there is no further movement in solution space - if (xDelta.getNorm() < epsilon) break; double gdd = grad.dotProduct(xDelta); RealVector tx = null; double tv = 0.0; @@ -154,6 +152,8 @@ public PointValuePair doOptimize() { double vprv = v; x = tx; v = tv; + // if improvement becomes very small then we are converged + if (Math.abs(1.0 - (v / vprv)) < epsilon) break; // Check halting condition if configured if ((halting != null) && halting.checker.converged( getIterations(), @@ -182,8 +182,6 @@ public PointValuePair doOptimize() { KKTSolution sol = kktSolver.solve(hess, A, AT, grad, A.operate(x).subtract(b)); RealVector xDelta = sol.xDelta; RealVector nuDelta = sol.nuPlus.subtract(nu); - // Halt if there is no further movement in solution space - if (xDelta.getNorm() < epsilon) break; RealVector tx = null; RealVector tnu = null; double tv = 0.0; @@ -219,6 +217,8 @@ public PointValuePair doOptimize() { x = tx; nu = tnu; v = tv; + // if improvement becomes very small then we are converged + if (Math.abs(1.0 - (v / vprv)) < epsilon) break; // check halting condition, if it was configured if ((halting != null) && halting.checker.converged( getIterations(), diff --git a/src/test/java/com/manyangled/gibbous/COTestingUtils.java b/src/test/java/com/manyangled/gibbous/COTestingUtils.java index 66058f6..346cb6c 100644 --- a/src/test/java/com/manyangled/gibbous/COTestingUtils.java +++ b/src/test/java/com/manyangled/gibbous/COTestingUtils.java @@ -26,7 +26,7 @@ import com.manyangled.gibbous.optim.convex.QuadraticFunction; public class COTestingUtils { - public static final double eps = 1e-9; + public static final double eps = 1e-8; public static QuadraticFunction translatedQF(double h, double[] center) { double[] all1 = new double[center.length];