[ 
https://issues.apache.org/jira/browse/NUMBERS-175?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17443930#comment-17443930
 ] 

Gilles Sadowski commented on NUMBERS-175:
-----------------------------------------

In the preceding comment, there seems to have been a formatting error in the 
second code excerpt.

Wrt the API, I'd tend to think that explicit classes are clearer (and 
self-documenting).

{code}
public abstract class GeneralizedContinuedFraction
    implements DoubleSupplier {
    private Double result;
    private Exception exception;

    // ...

    public double getAsDouble() {
        if (result != null) {
            return result;
        }

        if (exception != null) {
            throw exception;
        } else {
            try {
                evaluate();
            } catch (Exception e) {
                exception = e;
            }

            return getAsDouble();
        }
    }

    private void evaluate() {
        // Compute and cache.
        result = ...
    }

    public interface Coefficient {
        double a();
        double b();
    }

    public abstract Iterable<Coefficient> coefficients;
}
{code}

> Add continued fraction implementations using a generator of terms
> -----------------------------------------------------------------
>
>                 Key: NUMBERS-175
>                 URL: https://issues.apache.org/jira/browse/NUMBERS-175
>             Project: Commons Numbers
>          Issue Type: Improvement
>          Components: fraction
>    Affects Versions: 1.0
>            Reporter: Alex Herbert
>            Priority: Minor
>
> The ContinuedFraction class allows computation of:
> {noformat}
> b0 +        a1  
>      ------------------
>      b1 +     a2       
>           -------------
>           b2 +    a3
>                --------
>                b3 + ...{noformat}
> This is done using an abstract class that is extended to implement the 
> methods to get the terms:
> {code:java}
> double getA(int n, double x);
> double getB(int n, double x);{code}
> This allows the fraction to be reused to generate results for different 
> points to evaluate. However:
>  * It does not lend itself to fractions where the terms can be computed using 
> recursion:
> {noformat}
> b(n+1) = f( b(n) ) {noformat}
>  * It requires two method calls to generate terms a_n and b_n for each 
> iteration thus preventing optimisation of the computation using the input n 
> for values shared between computation of a and b. 
> An alternative method is to support a generator of the paired terms a_n and 
> b_n:
> {code:java}
> static double continuedFraction(Supplier<double[]> gen);{code}
> To be used in a single evaluation as:
> {code:java}
> Supplier<double[]> goldenRatio = () -> return new double[] {1, 1};
> double gr = continuedFraction(goldenRatio);
> // gr = 1.61803398874...{code}
> An additional feature is to support a simple continued fraction where all 
> partial numerators are 1:
> {noformat}
> b0 +         1  
>      ------------------
>      b1 +      1       
>           -------------
>           b2 +    1
>                --------
>                b3 + ...
> {noformat}
> E.g. using:
> {code:java}
> static double simpleContinuedFraction(DoubleSupplier gen); {code}
> h3. Addition
> In some situations it is an advantage to not evaluate the leading term b0. 
> The term may not be part of a regular series, or may be zero:
> {noformat}
>              a1  
>      ------------------
>      b1 +      a2       
>           -------------
>           b2 +    a3
>                --------
>                b3 + ...
> {noformat}
> h3. API
> Using the nomeclature from Wikipedia and Wolfram suggests the following:
> {code:java}
> public static final class GeneralizedContinuedFraction {
>     /**
>      * Evaluate the continued fraction from the generator for partial 
> numerator
>      * a and partial denominator b.
>      * <pre>
>      * b0 +        a1
>      *      ------------------
>      *      b1 +     a2
>      *           -------------
>      *           b2 +    a3
>      *                --------
>      *                b3 + ...
>      * </pre>
>      *
>      * <p>Note: The first generated partial numerator a0 is discarded.
>      *
>      * @param gen Generator
>      * @return the continued fraction value
>      */
>     public static double value(Supplier<double[]> gen);
>     /**
>      * Evaluate the continued fraction from the generator for partial 
> numerator
>      * a and partial denominator b.
>      * <pre>
>      *             a1
>      *      ------------------
>      *      b1 +     a2
>      *           -------------
>      *           b2 +    a3
>      *                --------
>      *                b3 + ...
>      * </pre>
>      *
>      * <p>Note: Both of the first terms a and b are used.
>      *
>      * @param gen Generator
>      * @return the continued fraction value
>      */
>     public static double valueA(Supplier<double[]> gen);
> }
> public static final class SimpleContinuedFraction {
>     public static double value(DoubleSupplier gen);
>     public static double valueA(DoubleSupplier gen);
> }
>  {code}
> The API should support the optional parameters to control the convergence 
> tolerance and the maximum number of iterations.
> The variant to evaluate without the leading b0 term is not essential. It can 
> be evaluated by starting the generator at the next iteration using:
> {code:java}
> Supplier<double[]> gen = ...; // Start at terms (a1,b1)
> // Evaluation will discard a1;
> // this value (separately computed) is then used to compute the result
> double value = a1 / GeneralizedContinuedFraction.value(gen);{code}
> This variant is present in the Boost c++ library and used to evaluate terms 
> for the gamma function.
> See:
> [https://en.wikipedia.org/wiki/Continued_fraction]
> [https://mathworld.wolfram.com/SimpleContinuedFraction.html]
> [https://mathworld.wolfram.com/GeneralizedContinuedFraction.html]
> [Boost Continued Fraction (v 
> 1_77_0)|https://www.boost.org/doc/libs/1_77_0/libs/math/doc/html/math_toolkit/internals/cf.html]
>  



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to