Description
The ContinuedFraction class evaluates using the same algorithm as the GeneralizedContinuedFraction. These should use the same code to eliminate duplication.
The GeneralizedContinuedFraction has the latest version of the algorithm with a bug fix for detecting invalid update steps and increased support for very small convergence epsilon (see NUMBERS-175).
The simple approach is to call the GeneralizedContinuedFraction by creating a generator from the ContinuedFraction and the argument x:
public double evaluate(double x, double epsilon, int maxIterations) { // Delegate to GeneralizedContinuedFraction // Get the first coefficient final double b0 = getB(0, x); // Generate coefficients from (a1,b1) final Supplier<Coefficient> gen = new Supplier<Coefficient>() { private int n; @Override public Coefficient get() { n++; final double a = getA(n, x); final double b = getB(n, x); return Coefficient.of(a, b); } }; // Invoke appropriate method based on magnitude of first term if (Math.abs(b0) < SMALL) { return GeneralizedContinuedFraction.value(b0, gen, epsilon, maxIterations); } return GeneralizedContinuedFraction.evaluate(b0, gen, epsilon, maxIterations); }
This will only evaluate each used coefficient once. It requires exposure of the GeneralizedContinuedFraction.evaluate method at the package level.
The threshold for small values and default for iterations can be exposed as package private from GeneralizedContinuedFraction. This ensures the method calls the appropriate evaluation method based on the magnitude of the first term b0 with the same defaults.