iterContinuedFractionSeq

Create an iterator which generates a list of all continued fraction terms which can be obtained given the precision of a provided number.

A generalized continued fraction has the form

x equals b 0 plus ContinuedFraction a 1 Over b 1 plus StartFraction a 2 Over b 2 plus StartFraction a 3 Over b 3 plus StartFraction a 4 Over b 4 plus ellipsis

If a_i = 1 for all i, the above expression reduces to a simple continued fraction.

x equals b 0 plus ContinuedFraction 1 Over b 1 plus StartFraction 1 Over b 2 plus StartFraction 1 Over b 3 plus StartFraction 1 Over b 4 plus ellipsis

where the values b_i are called the coefficients or terms of the continued fraction and the rationals

b 0 comma b 0 plus StartFraction 1 Over b 1 EndFraction comma b 0 plus StartStartFraction 1 OverOver b 1 plus StartFraction 1 Over b Baseline 2 EndFraction EndEndFraction comma b 0 plus StartStartStartFraction 1 OverOverOver b 1 plus StartStartFraction 1 OverOver b Baseline 2 plus StartFraction 1 Over b Baseline 3 EndFraction EndEndFraction EndEndEndFraction comma ellipsis

are called convergents.

Usage

var iterContinuedFractionSeq = require( '@stdlib/math/iter/sequences/continued-fraction' );

iterContinuedFractionSeq( x, [options] )

Returns an iterator which generates a list of all continued fraction terms (b_i) which can be obtained given the precision of x.

var it = iterContinuedFractionSeq( 3.245 );
// returns <Object>

var v = it.next().value;
// returns 3

v = it.next().value;
// returns 4

v = it.next().value;
// returns 12

v = it.next().value;
// returns 4

var bool = it.next().done;
// returns true

The returned iterator protocol-compliant object has the following properties:

  • next: function which returns an iterator protocol-compliant object containing the next iterated value (if one exists) assigned to a value property and a done property having a boolean value indicating whether the iterator is finished.
  • return: function which closes an iterator and returns a single (optional) argument in an iterator protocol-compliant object.

The function supports the following options:

  • iter: maximum number of iterations. Default: 1e308.

  • tol: tolerance at which to terminate further evaluation of the continued fraction. Default: floating-point epsilon.

  • returns: specifies the type of result to return. Must be one of the following options:

    • terms: return continued fraction terms.
    • convergents: return continued fraction convergents.
    • *: return both continued fraction terms and their associated convergents as a two-element array: [ <term>, <convergent> ].

    Default: 'terms'.

By default, in theory, the function returns an infinite iterator; however, in practice, due to limited precision, every floating-point number is a rational number, and, thus, every returned iterator will end in a finite number of iterations. To explicitly cap the maximum number of iterations, set the iter option.

var opts = {
    'iter': 2
};
var it = iterContinuedFractionSeq( 3.245, opts );
// returns <Object>

var v = it.next().value;
// returns 3

v = it.next().value;
// returns 4

var bool = it.next().done;
// returns true

The returned iterator terminates once the difference between the input value x and a continued fraction approximation is sufficiently small. The default tolerance is floating-point epsilon (~2.22e-16). Once an update to a continued fraction approximation is less than or equal to this tolerance, the iterator terminates. To adjust the tolerance (e.g., to return a rough approximation of an input value x), set the tol option.

var opts = {
    'tol': 1.0e-7
};
var it = iterContinuedFractionSeq( 3.141592653589793, opts );
// returns <Object>

var v = it.next().value;
// returns 3

v = it.next().value;
// returns 7

v = it.next().value;
// returns 16

var bool = it.next().done;
// returns true

// The returned terms [3; 7, 16] evaluate to 3.1415929203539825

By default, the returned iterator returns continued fraction terms. To return convergents, set the returns option to 'convergents'.

var it = iterContinuedFractionSeq( 3.245, {
    'returns': 'convergents'
});
// returns <Object>

var v = it.next().value;
// returns 3.0

v = it.next().value;
// returns 3.25

v = it.next().value;
// returns ~3.2449

v = it.next().value;
// returns 3.245

var bool = it.next().done;
// returns true

To return both continued fraction terms and their associated convergents, set the returns option to *.

var it = iterContinuedFractionSeq( 3.245, {
    'returns': '*'
});
// returns <Object>

var v = it.next().value;
// returns [ 3, 3.0 ]

v = it.next().value;
// returns [ 4, 3.25 ]

v = it.next().value;
// returns [ 12, ~3.2449 ]

v = it.next().value;
// returns [ 4, 3.245 ]

var bool = it.next().done;
// returns true

Notes

  • The returned iterator returns the terms for a simple continued fraction.
  • For x < 0, the returned iterator returns negated terms for |x| (i.e., if the terms for |x| are [b0; b1, b2, ..., bn], the returned iterator returns [-b0; -b1, -b2, ..., -bn]). While other continued fraction representations are possible, floating-point rounding error can introduce asymmetries when evaluating terms to recover the original values for |x| and x < 0. Accordingly, alternative continued fraction representations for negative input values are not supported.
  • If an environment supports Symbol.iterator, the returned iterator is iterable.

Examples

var PI = require( '@stdlib/constants/float64/pi' );
var iterContinuedFractionSeq = require( '@stdlib/math/iter/sequences/continued-fraction' );

function evaluate( terms ) {
    var sum;
    var N;
    var i;

    N = terms.length;
    sum = 0.0;
    if ( N > 1 ) {
        sum = 1.0 / terms[ N-1 ];
        for ( i = N-2; i > 0; i-- ) {
            sum = 1.0 / ( terms[ i ] + sum );
        }
    }
    sum += terms[ 0 ];
    return sum;
}

// Create an iterator:
var opts = {
    'iter': 20
};
var it = iterContinuedFractionSeq( PI, opts );

// Perform manual iteration...
var terms = [];
var v;
while ( true ) {
    v = it.next();
    if ( v.done ) {
        break;
    }
    terms.push( v.value );
}
console.log( 'original: %d', PI );
console.log( terms );
console.log( 'computed: %d', evaluate( terms ) );
Did you find this page helpful?