@Test public void testConvergenceOnFunctionAccuracy() { BracketingNthOrderBrentSolverDFP solver = new BracketingNthOrderBrentSolverDFP( relativeAccuracy, absoluteAccuracy, field.newDfp(1.0e-20), 20); UnivariateDfpFunction f = new UnivariateDfpFunction() { public Dfp value(Dfp x) { Dfp one = field.getOne(); Dfp oneHalf = one.divide(2); Dfp xMo = x.subtract(one); Dfp xMh = x.subtract(oneHalf); Dfp xPh = x.add(oneHalf); Dfp xPo = x.add(one); return xMo.multiply(xMh).multiply(x).multiply(xPh).multiply(xPo); } }; Dfp result = solver.solve( 20, f, field.newDfp(0.2), field.newDfp(0.9), field.newDfp(0.4), AllowedSolution.BELOW_SIDE); Assert.assertTrue(f.value(result).abs().lessThan(solver.getFunctionValueAccuracy())); Assert.assertTrue(f.value(result).negativeOrNull()); Assert.assertTrue( result.subtract(field.newDfp(0.5)).subtract(solver.getAbsoluteAccuracy()).positiveOrNull()); result = solver.solve( 20, f, field.newDfp(-0.9), field.newDfp(-0.2), field.newDfp(-0.4), AllowedSolution.ABOVE_SIDE); Assert.assertTrue(f.value(result).abs().lessThan(solver.getFunctionValueAccuracy())); Assert.assertTrue(f.value(result).positiveOrNull()); Assert.assertTrue( result.add(field.newDfp(0.5)).subtract(solver.getAbsoluteAccuracy()).negativeOrNull()); }
private void check( UnivariateDfpFunction f, int maxEval, double min, double max, AllowedSolution allowedSolution) { BracketingNthOrderBrentSolverDFP solver = new BracketingNthOrderBrentSolverDFP( relativeAccuracy, absoluteAccuracy, functionValueAccuracy, 20); Dfp xResult = solver.solve(maxEval, f, field.newDfp(min), field.newDfp(max), allowedSolution); Dfp yResult = f.value(xResult); switch (allowedSolution) { case ANY_SIDE: Assert.assertTrue(yResult.abs().lessThan(functionValueAccuracy.multiply(2))); break; case LEFT_SIDE: { boolean increasing = f.value(xResult).add(absoluteAccuracy).greaterThan(yResult); Assert.assertTrue(increasing ? yResult.negativeOrNull() : yResult.positiveOrNull()); break; } case RIGHT_SIDE: { boolean increasing = f.value(xResult).add(absoluteAccuracy).greaterThan(yResult); Assert.assertTrue(increasing ? yResult.positiveOrNull() : yResult.negativeOrNull()); break; } case BELOW_SIDE: Assert.assertTrue(yResult.negativeOrNull()); break; case ABOVE_SIDE: Assert.assertTrue(yResult.positiveOrNull()); break; default: // this should never happen throw new MathInternalError(null); } }