Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 79x 79x 79x 79x 79x 79x 79x 79x 79x 79x 79x 79x 20x 20x 59x 59x 59x 59x 79x 23x 23x 19x 19x 23x 40x 40x 79x 1x 1x 39x 79x 2x 2x 37x 37x 79x 7x 7x 37x 37x 37x 37x 37x 79x 85x 85x 85x 29x 29x 56x 56x 56x 85x 2x 2x 2x 54x 54x 85x 54x 85x 54x 54x 54x 54x 54x 85x 4x 4x 85x 79x 19x 19x 18x 79x 1x 1x 1x 1x 1x | /**
* @license Apache-2.0
*
* Copyright (c) 2022 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
// MODULES //
var isIteratorLike = require( '@stdlib/assert/is-iterator-like' );
var abs = require( '@stdlib/math/base/special/abs' );
var EPS = require( '@stdlib/constants/float64/eps' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive;
var format = require( '@stdlib/string/format' );
var validate = require( './validate.js' );
// VARIABLES //
var TINY = 1.0e-50;
// MAIN //
/**
* Evaluates the terms of a continued fraction.
*
* @param {Iterator} iterator - input iterator
* @param {Options} [options] - options
* @param {NonNegativeInteger} [options.iter=1e308] - maximum number of iterations
* @param {PositiveNumber} [options.tol] - tolerance at which to terminate further evaluation of the continued fraction
* @throws {TypeError} must provide an iterator
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide validate options
* @returns {(number|null)} result
*
* @example
* var iterContinuedFractionSeq = require( '@stdlib/math/iter/sequences/continued-fraction' );
*
* // Create an iterator for generating continued fraction terms:
* var it = iterContinuedFractionSeq( 3.245 );
*
* // Reconstruct the original value from the terms:
* var v = iterContinuedFraction( it );
* // returns ~3.245
*/
function iterContinuedFraction( iterator ) {
var delta;
var opts;
var err;
var b0;
var o;
var C;
var D;
var f;
var b;
var i;
if ( !isIteratorLike( iterator ) ) {
throw new TypeError( format( 'invalid argument. Must provide an iterator. Value: `%s`.', iterator ) );
}
opts = {
'iter': 1e308,
'tol': EPS
};
if ( arguments.length > 1 ) {
err = validate( opts, arguments[ 1 ] );
if ( err ) {
throw err;
}
}
// Get the first iterated value...
o = iterator.next();
if ( o.done ) {
return null;
}
b0 = o.value;
if ( !isNumber( b0 ) || isnan( b0 ) ) {
return b0;
}
// Initialize parameters of the modified Lentz's algorithm...
f = b0;
if ( f === 0.0 ) {
f = TINY;
}
C = f;
D = 0.0;
// Evaluate the terms of the continued fraction...
i = 1;
while ( i < opts.iter ) {
// Get the next iterated value...
o = iterator.next();
if ( o.done ) {
break;
}
i += 1;
b = o.value;
if ( !isNumber( b ) || isnan( b ) ) {
f = NaN;
break;
}
// Use the modified Lentz's algorithm to find the next convergent...
D += b; // b_i + a_i*D_{i-1}, where a_i = 1.0 for all i
if ( D === 0.0 ) {
D = TINY;
}
C = b + ( 1.0/C ); // b_i + a_i/C_{i-1}, where a_i = 1.0 for all i
if ( C === 0.0 ) {
C = TINY;
}
D = 1.0 / D;
delta = C * D;
f *= delta;
// Check whether we can terminate computation...
if ( abs( delta - 1.0 ) <= opts.tol ) {
break;
}
}
if ( i <= 1 ) {
return b0;
}
return f;
}
// EXPORTS //
module.exports = iterContinuedFraction;
|