private boolean getNextPosition( final Function1D<DoubleMatrix1D, Double> function, final Function1D<DoubleMatrix1D, DoubleMatrix1D> grad, final DataBundle data) { final DoubleMatrix1D p = getDirection(data); if (data.getLambda0() < 1.0) { data.setLambda0(1.0); } else { data.setLambda0(data.getLambda0() * BETA); } updatePosition(p, function, data); final double g1 = data.getG1(); // the function is invalid at the new position, try to recover if (Double.isInfinite(g1) || Double.isNaN(g1)) { bisectBacktrack(p, function, data); } if (data.getG1() > data.getG0() / (1 + ALPHA * data.getLambda0())) { quadraticBacktrack(p, function, data); int count = 0; while (data.getG1() > data.getG0() / (1 + ALPHA * data.getLambda0())) { if (count > 5) { return false; } cubicBacktrack(p, function, data); count++; } } final DoubleMatrix1D deltaX = data.getDeltaX(); data.setX((DoubleMatrix1D) MA.add(data.getX(), deltaX)); data.setG0(data.getG1()); final DoubleMatrix1D gradNew = grad.evaluate(data.getX()); data.setDeltaGrad((DoubleMatrix1D) MA.subtract(gradNew, data.getGrad())); data.setGrad(gradNew); return true; }
private boolean isConverged(final DataBundle data) { final DoubleMatrix1D deltaX = data.getDeltaX(); final DoubleMatrix1D x = data.getX(); final int n = deltaX.getNumberOfElements(); double diff, scale; for (int i = 0; i < n; i++) { diff = Math.abs(deltaX.getEntry(i)); scale = Math.abs(x.getEntry(i)); if (diff > _absoluteTol + scale * _relativeTol) { return false; } } return (MA.getNorm2(data.getGrad()) < _absoluteTol); }
private DoubleMatrix1D getDirection(final DataBundle data) { return (DoubleMatrix1D) MA.multiply(data.getInverseHessianEsimate(), MA.scale(data.getGrad(), -1.0)); }