@Override public DoubleArray getRoot(Function<DoubleArray, DoubleArray> function, DoubleArray startPosition) { return findRoot(function, startPosition); }
DoubleArray startPosition) { checkInputs(function, startPosition); DoubleMatrix estimate = _initializationFunction.getInitializedMatrix(jacobianFunction, startPosition); if (!getNextPosition(function, estimate, data)) { if (isConverged(data)) { return data.getX(); // this can happen if the starting position is the root while (!isConverged(data)) { if (!getNextPosition(function, estimate, data)) { estimate = _initializationFunction.getInitializedMatrix(jacobianFunction, data.getX()); jacReconCount = 1; if (!getNextPosition(function, estimate, data)) { if (isConverged(data)) { getErrorMessage(data, jacobianFunction); log.info(msg); throw new MathException(msg); if (count > _maxSteps) { throw new MathException("Failed to converge - maximum iterations of " + _maxSteps + " reached." + getErrorMessage(data, jacobianFunction));
data.setLambda0(data.getLambda0() * BETA); updatePosition(p, function, data); double g1 = data.getG1(); if (!Doubles.isFinite(g1)) { bisectBacktrack(p, function, data); quadraticBacktrack(p, function, data); int count = 0; while (data.getG1() > data.getG0() / (1 + ALPHA * data.getLambda0())) { return false; cubicBacktrack(p, function, data); count++;
private void quadraticBacktrack( DoubleArray p, Function<DoubleArray, DoubleArray> function, DataBundle data) { double lambda0 = data.getLambda0(); double g0 = data.getG0(); double lambda = Math.max(0.01 * lambda0, g0 * lambda0 * lambda0 / (data.getG1() + g0 * (2 * lambda0 - 1))); data.swapLambdaAndReplace(lambda); updatePosition(p, function, data); }
private void bisectBacktrack(DoubleArray p, Function<DoubleArray, DoubleArray> function, DataBundle data) { do { data.setLambda0(data.getLambda0() * 0.1); updatePosition(p, function, data); if (data.getLambda0() == 0.0) { throw new MathException("Failed to converge"); } } while (Double.isNaN(data.getG1()) || Double.isInfinite(data.getG1()) || Double.isNaN(data.getG2()) || Double.isInfinite(data.getG2())); }
@Override public DoubleArray findRoot(Function<DoubleArray, DoubleArray> function, DoubleArray startPosition) { VectorFieldFirstOrderDifferentiator jac = new VectorFieldFirstOrderDifferentiator(); return findRoot(function, jac.differentiate(function), startPosition); }
private void cubicBacktrack(DoubleArray p, Function<DoubleArray, DoubleArray> function, DataBundle data) { double temp1, temp2, temp3, temp4, temp5; double lambda0 = data.getLambda0(); double lambda1 = data.getLambda1(); double g0 = data.getG0(); temp1 = 1.0 / lambda0 / lambda0; temp2 = 1.0 / lambda1 / lambda1; temp3 = data.getG1() + g0 * (2 * lambda0 - 1.0); temp4 = data.getG2() + g0 * (2 * lambda1 - 1.0); temp5 = 1.0 / (lambda0 - lambda1); double a = temp5 * (temp1 * temp3 - temp2 * temp4); double b = temp5 * (-lambda1 * temp1 * temp3 + lambda0 * temp2 * temp4); double lambda = (-b + Math.sqrt(b * b + 6 * a * g0)) / 3 / a; lambda = Math.min(Math.max(lambda, 0.01 * lambda0), 0.75 * lambda1); // make sure new lambda is between 1% & 75% of old value data.swapLambdaAndReplace(lambda); updatePosition(p, function, data); }
protected void assertFunction2D(final BaseNewtonVectorRootFinder rootFinder, final double eps) { final DoubleArray x0 = DoubleArray.of(-0.0, 0.0); final DoubleArray x1 = rootFinder.findRoot(FUNCTION2D, JACOBIAN2D, x0); assertEquals(1.0, x1.get(0), eps); assertEquals(1.0, x1.get(1), eps); }
protected void assertFunction3D(final BaseNewtonVectorRootFinder rootFinder, final double eps) { final DoubleArray x0 = DoubleArray.of(0.8, 0.2, -0.7); final DoubleArray x1 = rootFinder.findRoot(FUNCTION3D, JACOBIAN3D, x0); assertEquals(1.0, x1.get(0), eps); assertEquals(0.0, x1.get(1), eps); assertEquals(-1.0, x1.get(2), eps); }