From 5e0cc08287071a4d183c6bf1787b4ca08787fa32 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Thu, 7 Apr 2016 14:08:54 -0400 Subject: [PATCH 01/12] Add tool fcn to sum the elements of an infinite series --- .../math/base/tools/sum-series/README.md | 107 ++++++++++++++ .../base/tools/sum-series/examples/index.js | 18 +++ .../math/base/tools/sum-series/lib/basic.js | 54 +++++++ .../base/tools/sum-series/lib/generators.js | 66 +++++++++ .../math/base/tools/sum-series/lib/index.js | 10 ++ .../math/base/tools/sum-series/package.json | 23 +++ .../sum-series/test/es2015/test.generator.js | 30 ++++ .../math/base/tools/sum-series/test/test.js | 137 ++++++++++++++++++ 8 files changed, 445 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/README.md create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/package.json create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md b/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md new file mode 100644 index 000000000000..e0b5ba0376b5 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md @@ -0,0 +1,107 @@ +sum-series +=== +> Compute the sum of an [infinite series][infinite-series]. + + +## Usage + +``` javascript +var sumSeries = require( 'math-sum-series' ); +``` + +#### sumSeries( generator[, options ] ) + +Computes the sum of the series given by the supplied `generator` argument. `generator` can be either an ES6 [Generator object][es6-generator] or a function which +returns successive elements of the series at each invocation. + +Using an ES6 [Generator object][es6-generator]: + +```javascript +var gen = geometricSeriesGenerator( 0.9 ); +var out = sumSeries( gen ); +// returns 10 + +function* geometricSeriesGenerator( x ) { + var exponent = 0; + while ( true ) { + yield Math.pow( x, exponent ); + exponent += 1; + } +} +``` + +Alternatively, one can use a closure to achieve the same goal: + +```javascript +var gen = geometricSeriesClosure( 0.9 ) +var out = sumSeries( gen ); +// returns 10 + +function geometricSeriesClosure( x ) { + var exponent = -1; + return function() { + exponent += 1; + return Math.pow( x, exponent ); + }; +} +``` + +The `function` accepts the following `options`: +* __max_terms__: integer denoting the maximum number of terms to be summed. Default: `1000000`. +* __tolerance__: number primitive specifying the tolerance used to assess convergence. Default: `2.22e-16`. +* __init__: number primitive specifying the initial value of the returned sum. Default: `0`. + +By default, the initial value of the sum is `0`. To choose a different one, use the `init` option. + +```javascript +var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { + 'init': 1 +}); +// returns 3 +``` + +To change the maximum number of terms to be summed, set the `max_terms` option. + +```javascript +var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { + 'max_terms': 10 +}); +// returns ~1.998 (infinite sum is 2) +``` + +The default tolerance of `1e-16` used to assess convergence can be changed via the `tolerance` option. + +```javascript +var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { + 'tolerance': 1e-3 +}); +// returns ~1.998 +``` + + + +## Examples + +``` javascript +var log1p = require( 'math-float64-log1p' ); +var sumSeries = require( 'math-sum-series' ); + +function* log1p_series( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + while ( true ) { + m_prod *= m_mult; + yield ( m_prod / ++k ); + } +} + +console.log( 'log1p(0.5) evaluated via math-log1p module: %d', log1p( 0.5 ) ); +console.log( 'log1p(0.5) evaluated via infinite series expansion: %d', sumSeries( log1p_series( 0.5 ) ) ); +``` + + + +[infinite-series]: https://en.wikipedia.org/wiki/Series_%28mathematics%29 +[es6-generator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* + diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js new file mode 100644 index 000000000000..862c269f1f7a --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js @@ -0,0 +1,18 @@ +'use strict'; + +var log1p = require( '@stdlib/math/base/special/log1p' ); +var sumSeries = require( './../lib' ); + +/* jshint esnext: true */ +function* log1p_series( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + while ( true ) { + m_prod *= m_mult; + yield ( m_prod / ++k ); + } +} + +console.log( 'log1p(0.5) evaluated via math-log1p module: %d', log1p( 0.5 ) ); +console.log( 'log1p(0.5) evaluated via infinite series expansion: %d', sumSeries( log1p_series( 0.5 ) ) ); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js new file mode 100644 index 000000000000..fae4f5b76c49 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js @@ -0,0 +1,54 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); + + +// CONSTANTS // + +var TOLERANCE = require( '@stdlib/math/constants/float64-eps' ); +var MAX_TERMS = 1000000; + + +// SUM SERIES // + +/** +* FUNCTION: sum_series( generator[, opts] ) +* Sums the element of the series given by the supplied function. +* +* @param {Function} generator - series function +* @param {Object} [opts] - function options +* @param {Number} [opts.max_terms=1000000] - maximum number of terms to be added +* @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance +* @param {Number} [opts.init=0] - initial value of the resulting sum +* @returns {Number} sum of all series terms +*/ +function sum_series( generator, options ) { + var opts = {}; + var tolerance; + var counter; + var result; + var next_term; + + if ( arguments.length > 1 ) { + opts = options; + } + tolerance = opts.tolerance || TOLERANCE; + counter = opts.max_terms || MAX_TERMS; + result = opts.init || 0; + + // Repeatedly call function... + do { + next_term = generator(); + result += next_term; + } + while( ( abs(tolerance * result) < abs(next_term) ) && --counter ); + + return result; +} // end FUNCTION sum_series() + + +// EXPORTS // + +module.exports = sum_series; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js new file mode 100644 index 000000000000..a81d30edccdc --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js @@ -0,0 +1,66 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); + + +// CONSTANTS // + +var TOLERANCE = require( '@stdlib/math/constants/float64-eps' ); +var MAX_TERMS = 1000000; + + +// SUM SERIES // + +/** +* FUNCTION: sum_series( generator[, opts] ) +* Sums the element of the series given by the supplied function. +* +* @param {Function} generator - series function +* @param {Object} [opts] - function options +* @param {Number} [opts.max_terms=1000000] - maximum number of terms to be added +* @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance +* @param {Number} [opts.init=0] - initial value of the resulting sum +* @returns {Number} sum of all series terms +*/ +function sum_series( generator, options ) { + var opts = {}; + var tolerance; + var isgenerator; + var counter; + var result; + var next_term; + + if ( arguments.length > 1 ) { + opts = options; + } + tolerance = opts.tolerance || TOLERANCE; + counter = opts.max_terms || MAX_TERMS; + result = opts.init || 0; + + isgenerator = typeof generator.next === 'function'; + if ( isgenerator === true ) { + // Case A: Iterate over generator object created by a generator function... + /* jshint esnext: true */ + for ( next_term of generator ) { + result += next_term; + if ( (abs(tolerance * result) >= abs(next_term) ) || --counter === 0 ) { + break; + } + } + } else { + // Case B: Repeatedly call function... + do { + next_term = generator(); + result += next_term; + } + while( ( abs(tolerance * result) < abs(next_term) ) && --counter ); + } + return result; +} // end FUNCTION sum_series() + + +// EXPORTS // + +module.exports = sum_series; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js new file mode 100644 index 000000000000..5aa7202bfd57 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js @@ -0,0 +1,10 @@ +'use strict'; + +// MODULES // + +var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )(); + + +// EXPORTS // + +module.exports = hasGeneratorsSupport ? require( './generators.js' ) : require( './basic.js' ); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json b/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json new file mode 100644 index 000000000000..31f59421c346 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json @@ -0,0 +1,23 @@ +{ + "name": "", + "version": "0.0.0", + "description": "Compute the sum of an infinite series.", + "author": {}, + "contributors": [], + "scripts": {}, + "main": "./lib", + "repository": {}, + "keywords": [ + "stdlib", + "stdmath", + "mathematics", + "math", + "series", + "fraction", + "expansion" + ], + "bugs": {}, + "dependencies": {}, + "devDependencies": {}, + "license": "MIT" +} diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js new file mode 100644 index 000000000000..4b28f4e8a5de --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js @@ -0,0 +1,30 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); +var log1p = require( '@stdlib/math/base/special/log1p' ); +var tape = require( 'tape' ); +var sumSeries = require( './../../lib/' ); + + +// TESTS // + +tape( 'the function calculates the sum of an infinite series provided by a generator', function test( t ) { + // log1p( 0.5 ): + var actual = sumSeries( generator( 0.5 ) ); + var expected = log1p( 0.5 ); + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function* generator( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + while ( true ) { + m_prod *= m_mult; + yield ( m_prod / ++k ); + } + } +}); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js new file mode 100644 index 000000000000..24a4df8fb972 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -0,0 +1,137 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); +var log1p = require( '@stdlib/math/base/special/log1p' ); +var proxyquire = require( 'proxyquire' ); +var tape = require( 'tape' ); +var sumSeries = require( './../lib/' ); +var sumSeriesBasic = proxyquire( './../lib/', { + 'detect-generator-support': function(){ return false; } +}); + + +// VARIABLES // + +var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.equal( typeof sumSeries, 'function', 'main export is a function' ); + t.end(); +}); + +// Run generator function tests if environment supports `function*()`... + +if ( hasGeneratorsSupport ) { + require( './es2015/test.generator.js' ); +} + +tape( 'the function calculates the sum of an infinite series provided by a closure', function test( t ) { + // log1p( 0.5 ): + var actual = sumSeries( closure( 0.5 ) ); + var expected = log1p( 0.5 ); + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of an infinite series provided by a closure (when generators are not supported)', function test( t ) { + // log1p( 0.5 ): + var actual = sumSeriesBasic( closure( 0.5 ) ); + var expected = log1p( 0.5 ); + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of an infinite series with a specified initial value', function test( t ) { + // log1p( 0.5 ) + 2: + var actual = sumSeries( closure( 0.5 ), { 'init' : 2 } ); + var expected = log1p( 0.5 ) + 2; + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of an infinite series with a specified initial value (when generators are not supported)', function test( t ) { + // log1p( 0.5 ) + 2: + var actual = sumSeriesBasic( closure( 0.5 ), { 'init' : 2 } ); + var expected = log1p( 0.5 ) + 2; + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of a user-defined number of terms of the series', function test( t ) { + var actual = sumSeries( closure( 0.5 ), { 'max_terms' : 3 } ); + var expected = 6; + + t.equal( actual, expected, 'returned result is equal to expected value. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure() { + var k = 1; + return function() { + return k++; + }; + } +}); + +tape( 'the function calculates the sum of a user-defined number of terms of the series (when generators are not supported)', function test( t ) { + var actual = sumSeriesBasic( closure( 0.5 ), { 'max_terms' : 3 } ); + var expected = 6; + + t.equal( actual, expected, 'returned result is equal to expected value. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure() { + var k = 1; + return function() { + return k++; + }; + } +}); From 992ee485083c29c824fadee4c0fd163085710850 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Thu, 7 Apr 2016 14:09:28 -0400 Subject: [PATCH 02/12] Print test filename --- lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js index 24a4df8fb972..0d1970ad584c 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -20,6 +20,7 @@ var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )() // TESTS // tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); t.equal( typeof sumSeries, 'function', 'main export is a function' ); t.end(); }); From f650e8cb9340c49fa93034228c28d3ac97093069 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Thu, 7 Apr 2016 15:35:32 -0400 Subject: [PATCH 03/12] Rename generator test file and parent directory --- .../{es2015/test.generator.js => es2015-generator/index.js} | 0 .../@stdlib/math/base/tools/sum-series/test/test.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/node_modules/@stdlib/math/base/tools/sum-series/test/{es2015/test.generator.js => es2015-generator/index.js} (100%) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js similarity index 100% rename from lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js rename to lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js index 0d1970ad584c..43377e1b0366 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -28,7 +28,7 @@ tape( 'main export is a function', function test( t ) { // Run generator function tests if environment supports `function*()`... if ( hasGeneratorsSupport ) { - require( './es2015/test.generator.js' ); + require( './es2015-generator' ); } tape( 'the function calculates the sum of an infinite series provided by a closure', function test( t ) { From d1ec38cdbb6b89496e26ab55d8b799d821644fd2 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Thu, 7 Apr 2016 14:08:54 -0400 Subject: [PATCH 04/12] Add tool fcn to sum the elements of an infinite series --- .../math/base/tools/sum-series/README.md | 107 ++++++++++++++ .../base/tools/sum-series/examples/index.js | 18 +++ .../math/base/tools/sum-series/lib/basic.js | 54 +++++++ .../base/tools/sum-series/lib/generators.js | 66 +++++++++ .../math/base/tools/sum-series/lib/index.js | 10 ++ .../math/base/tools/sum-series/package.json | 23 +++ .../sum-series/test/es2015/test.generator.js | 30 ++++ .../math/base/tools/sum-series/test/test.js | 137 ++++++++++++++++++ 8 files changed, 445 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/README.md create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/package.json create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js create mode 100644 lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md b/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md new file mode 100644 index 000000000000..e0b5ba0376b5 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md @@ -0,0 +1,107 @@ +sum-series +=== +> Compute the sum of an [infinite series][infinite-series]. + + +## Usage + +``` javascript +var sumSeries = require( 'math-sum-series' ); +``` + +#### sumSeries( generator[, options ] ) + +Computes the sum of the series given by the supplied `generator` argument. `generator` can be either an ES6 [Generator object][es6-generator] or a function which +returns successive elements of the series at each invocation. + +Using an ES6 [Generator object][es6-generator]: + +```javascript +var gen = geometricSeriesGenerator( 0.9 ); +var out = sumSeries( gen ); +// returns 10 + +function* geometricSeriesGenerator( x ) { + var exponent = 0; + while ( true ) { + yield Math.pow( x, exponent ); + exponent += 1; + } +} +``` + +Alternatively, one can use a closure to achieve the same goal: + +```javascript +var gen = geometricSeriesClosure( 0.9 ) +var out = sumSeries( gen ); +// returns 10 + +function geometricSeriesClosure( x ) { + var exponent = -1; + return function() { + exponent += 1; + return Math.pow( x, exponent ); + }; +} +``` + +The `function` accepts the following `options`: +* __max_terms__: integer denoting the maximum number of terms to be summed. Default: `1000000`. +* __tolerance__: number primitive specifying the tolerance used to assess convergence. Default: `2.22e-16`. +* __init__: number primitive specifying the initial value of the returned sum. Default: `0`. + +By default, the initial value of the sum is `0`. To choose a different one, use the `init` option. + +```javascript +var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { + 'init': 1 +}); +// returns 3 +``` + +To change the maximum number of terms to be summed, set the `max_terms` option. + +```javascript +var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { + 'max_terms': 10 +}); +// returns ~1.998 (infinite sum is 2) +``` + +The default tolerance of `1e-16` used to assess convergence can be changed via the `tolerance` option. + +```javascript +var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { + 'tolerance': 1e-3 +}); +// returns ~1.998 +``` + + + +## Examples + +``` javascript +var log1p = require( 'math-float64-log1p' ); +var sumSeries = require( 'math-sum-series' ); + +function* log1p_series( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + while ( true ) { + m_prod *= m_mult; + yield ( m_prod / ++k ); + } +} + +console.log( 'log1p(0.5) evaluated via math-log1p module: %d', log1p( 0.5 ) ); +console.log( 'log1p(0.5) evaluated via infinite series expansion: %d', sumSeries( log1p_series( 0.5 ) ) ); +``` + + + +[infinite-series]: https://en.wikipedia.org/wiki/Series_%28mathematics%29 +[es6-generator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* + diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js new file mode 100644 index 000000000000..862c269f1f7a --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/examples/index.js @@ -0,0 +1,18 @@ +'use strict'; + +var log1p = require( '@stdlib/math/base/special/log1p' ); +var sumSeries = require( './../lib' ); + +/* jshint esnext: true */ +function* log1p_series( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + while ( true ) { + m_prod *= m_mult; + yield ( m_prod / ++k ); + } +} + +console.log( 'log1p(0.5) evaluated via math-log1p module: %d', log1p( 0.5 ) ); +console.log( 'log1p(0.5) evaluated via infinite series expansion: %d', sumSeries( log1p_series( 0.5 ) ) ); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js new file mode 100644 index 000000000000..fae4f5b76c49 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js @@ -0,0 +1,54 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); + + +// CONSTANTS // + +var TOLERANCE = require( '@stdlib/math/constants/float64-eps' ); +var MAX_TERMS = 1000000; + + +// SUM SERIES // + +/** +* FUNCTION: sum_series( generator[, opts] ) +* Sums the element of the series given by the supplied function. +* +* @param {Function} generator - series function +* @param {Object} [opts] - function options +* @param {Number} [opts.max_terms=1000000] - maximum number of terms to be added +* @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance +* @param {Number} [opts.init=0] - initial value of the resulting sum +* @returns {Number} sum of all series terms +*/ +function sum_series( generator, options ) { + var opts = {}; + var tolerance; + var counter; + var result; + var next_term; + + if ( arguments.length > 1 ) { + opts = options; + } + tolerance = opts.tolerance || TOLERANCE; + counter = opts.max_terms || MAX_TERMS; + result = opts.init || 0; + + // Repeatedly call function... + do { + next_term = generator(); + result += next_term; + } + while( ( abs(tolerance * result) < abs(next_term) ) && --counter ); + + return result; +} // end FUNCTION sum_series() + + +// EXPORTS // + +module.exports = sum_series; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js new file mode 100644 index 000000000000..a81d30edccdc --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js @@ -0,0 +1,66 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); + + +// CONSTANTS // + +var TOLERANCE = require( '@stdlib/math/constants/float64-eps' ); +var MAX_TERMS = 1000000; + + +// SUM SERIES // + +/** +* FUNCTION: sum_series( generator[, opts] ) +* Sums the element of the series given by the supplied function. +* +* @param {Function} generator - series function +* @param {Object} [opts] - function options +* @param {Number} [opts.max_terms=1000000] - maximum number of terms to be added +* @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance +* @param {Number} [opts.init=0] - initial value of the resulting sum +* @returns {Number} sum of all series terms +*/ +function sum_series( generator, options ) { + var opts = {}; + var tolerance; + var isgenerator; + var counter; + var result; + var next_term; + + if ( arguments.length > 1 ) { + opts = options; + } + tolerance = opts.tolerance || TOLERANCE; + counter = opts.max_terms || MAX_TERMS; + result = opts.init || 0; + + isgenerator = typeof generator.next === 'function'; + if ( isgenerator === true ) { + // Case A: Iterate over generator object created by a generator function... + /* jshint esnext: true */ + for ( next_term of generator ) { + result += next_term; + if ( (abs(tolerance * result) >= abs(next_term) ) || --counter === 0 ) { + break; + } + } + } else { + // Case B: Repeatedly call function... + do { + next_term = generator(); + result += next_term; + } + while( ( abs(tolerance * result) < abs(next_term) ) && --counter ); + } + return result; +} // end FUNCTION sum_series() + + +// EXPORTS // + +module.exports = sum_series; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js new file mode 100644 index 000000000000..5aa7202bfd57 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js @@ -0,0 +1,10 @@ +'use strict'; + +// MODULES // + +var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )(); + + +// EXPORTS // + +module.exports = hasGeneratorsSupport ? require( './generators.js' ) : require( './basic.js' ); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json b/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json new file mode 100644 index 000000000000..31f59421c346 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json @@ -0,0 +1,23 @@ +{ + "name": "", + "version": "0.0.0", + "description": "Compute the sum of an infinite series.", + "author": {}, + "contributors": [], + "scripts": {}, + "main": "./lib", + "repository": {}, + "keywords": [ + "stdlib", + "stdmath", + "mathematics", + "math", + "series", + "fraction", + "expansion" + ], + "bugs": {}, + "dependencies": {}, + "devDependencies": {}, + "license": "MIT" +} diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js new file mode 100644 index 000000000000..4b28f4e8a5de --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js @@ -0,0 +1,30 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); +var log1p = require( '@stdlib/math/base/special/log1p' ); +var tape = require( 'tape' ); +var sumSeries = require( './../../lib/' ); + + +// TESTS // + +tape( 'the function calculates the sum of an infinite series provided by a generator', function test( t ) { + // log1p( 0.5 ): + var actual = sumSeries( generator( 0.5 ) ); + var expected = log1p( 0.5 ); + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function* generator( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + while ( true ) { + m_prod *= m_mult; + yield ( m_prod / ++k ); + } + } +}); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js new file mode 100644 index 000000000000..24a4df8fb972 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -0,0 +1,137 @@ +'use strict'; + +// MODULES // + +var abs = require( '@stdlib/math/base/special/abs' ); +var log1p = require( '@stdlib/math/base/special/log1p' ); +var proxyquire = require( 'proxyquire' ); +var tape = require( 'tape' ); +var sumSeries = require( './../lib/' ); +var sumSeriesBasic = proxyquire( './../lib/', { + 'detect-generator-support': function(){ return false; } +}); + + +// VARIABLES // + +var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.equal( typeof sumSeries, 'function', 'main export is a function' ); + t.end(); +}); + +// Run generator function tests if environment supports `function*()`... + +if ( hasGeneratorsSupport ) { + require( './es2015/test.generator.js' ); +} + +tape( 'the function calculates the sum of an infinite series provided by a closure', function test( t ) { + // log1p( 0.5 ): + var actual = sumSeries( closure( 0.5 ) ); + var expected = log1p( 0.5 ); + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of an infinite series provided by a closure (when generators are not supported)', function test( t ) { + // log1p( 0.5 ): + var actual = sumSeriesBasic( closure( 0.5 ) ); + var expected = log1p( 0.5 ); + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of an infinite series with a specified initial value', function test( t ) { + // log1p( 0.5 ) + 2: + var actual = sumSeries( closure( 0.5 ), { 'init' : 2 } ); + var expected = log1p( 0.5 ) + 2; + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of an infinite series with a specified initial value (when generators are not supported)', function test( t ) { + // log1p( 0.5 ) + 2: + var actual = sumSeriesBasic( closure( 0.5 ), { 'init' : 2 } ); + var expected = log1p( 0.5 ) + 2; + + t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure( x ) { + var k = 0; + var m_mult = -x; + var m_prod = -1; + return function() { + m_prod *= m_mult; + return ( m_prod / ++k ); + }; + } +}); + +tape( 'the function calculates the sum of a user-defined number of terms of the series', function test( t ) { + var actual = sumSeries( closure( 0.5 ), { 'max_terms' : 3 } ); + var expected = 6; + + t.equal( actual, expected, 'returned result is equal to expected value. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure() { + var k = 1; + return function() { + return k++; + }; + } +}); + +tape( 'the function calculates the sum of a user-defined number of terms of the series (when generators are not supported)', function test( t ) { + var actual = sumSeriesBasic( closure( 0.5 ), { 'max_terms' : 3 } ); + var expected = 6; + + t.equal( actual, expected, 'returned result is equal to expected value. actual: ' + actual + '; expected: ' + expected + '.' ); + t.end(); + + function closure() { + var k = 1; + return function() { + return k++; + }; + } +}); From 9c5f2a0b2d80aa630deea2d60acbfc5d77668921 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Thu, 7 Apr 2016 14:09:28 -0400 Subject: [PATCH 05/12] Print test filename --- lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js index 24a4df8fb972..0d1970ad584c 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -20,6 +20,7 @@ var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )() // TESTS // tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); t.equal( typeof sumSeries, 'function', 'main export is a function' ); t.end(); }); From 1288a57c0dbb0310236b9bad455fdd24d0f648c7 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Thu, 7 Apr 2016 15:35:32 -0400 Subject: [PATCH 06/12] Rename generator test file and parent directory --- .../{es2015/test.generator.js => es2015-generator/index.js} | 0 .../@stdlib/math/base/tools/sum-series/test/test.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/node_modules/@stdlib/math/base/tools/sum-series/test/{es2015/test.generator.js => es2015-generator/index.js} (100%) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js similarity index 100% rename from lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015/test.generator.js rename to lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js index 0d1970ad584c..43377e1b0366 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -28,7 +28,7 @@ tape( 'main export is a function', function test( t ) { // Run generator function tests if environment supports `function*()`... if ( hasGeneratorsSupport ) { - require( './es2015/test.generator.js' ); + require( './es2015-generator' ); } tape( 'the function calculates the sum of an infinite series provided by a closure', function test( t ) { From 1302e2281c8295fad54e6106d7c87c6f58a77193 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Fri, 6 May 2016 21:20:25 -0400 Subject: [PATCH 07/12] Remove version number --- .../@stdlib/math/base/tools/sum-series/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json b/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json index 31f59421c346..854107e38dfb 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/package.json @@ -1,6 +1,6 @@ { "name": "", - "version": "0.0.0", + "version": "", "description": "Compute the sum of an infinite series.", "author": {}, "contributors": [], From 21a4082d6e686463386298ee982570e588975053 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Fri, 6 May 2016 21:25:37 -0400 Subject: [PATCH 08/12] Remove trailing slash in local require statements --- .../math/base/tools/sum-series/test/es2015-generator/index.js | 3 ++- .../@stdlib/math/base/tools/sum-series/test/test.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js index 4b28f4e8a5de..138c6470f6b0 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js @@ -5,7 +5,7 @@ var abs = require( '@stdlib/math/base/special/abs' ); var log1p = require( '@stdlib/math/base/special/log1p' ); var tape = require( 'tape' ); -var sumSeries = require( './../../lib/' ); +var sumSeries = require( './../../lib' ); // TESTS // @@ -18,6 +18,7 @@ tape( 'the function calculates the sum of an infinite series provided by a gener t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); + /* jshint esnext: true */ function* generator( x ) { var k = 0; var m_mult = -x; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js index 43377e1b0366..b3c8a39a87ae 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -6,8 +6,8 @@ var abs = require( '@stdlib/math/base/special/abs' ); var log1p = require( '@stdlib/math/base/special/log1p' ); var proxyquire = require( 'proxyquire' ); var tape = require( 'tape' ); -var sumSeries = require( './../lib/' ); -var sumSeriesBasic = proxyquire( './../lib/', { +var sumSeries = require( './../lib' ); +var sumSeriesBasic = proxyquire( './../lib', { 'detect-generator-support': function(){ return false; } }); From 70237492d5b2ce768652d64a7b52de18a51c13d6 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Fri, 6 May 2016 21:32:48 -0400 Subject: [PATCH 09/12] Clean-up of README.md --- .../math/base/tools/sum-series/README.md | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md b/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md index e0b5ba0376b5..f7db66b02f7a 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/README.md @@ -6,13 +6,12 @@ sum-series ## Usage ``` javascript -var sumSeries = require( 'math-sum-series' ); +var sumSeries = require( '@stdlib/math/base/tools/sum-series' ); ``` #### sumSeries( generator[, options ] ) -Computes the sum of the series given by the supplied `generator` argument. `generator` can be either an ES6 [Generator object][es6-generator] or a function which -returns successive elements of the series at each invocation. +Computes the sum of the series given by the supplied `generator` argument. `generator` can be either an ES6 [Generator object][es6-generator] or a function which returns successive elements of the series at each invocation. Using an ES6 [Generator object][es6-generator]: @@ -47,32 +46,32 @@ function geometricSeriesClosure( x ) { ``` The `function` accepts the following `options`: -* __max_terms__: integer denoting the maximum number of terms to be summed. Default: `1000000`. +* __maxTerms__: integer denoting the maximum number of terms to be summed. Default: `1000000`. * __tolerance__: number primitive specifying the tolerance used to assess convergence. Default: `2.22e-16`. -* __init__: number primitive specifying the initial value of the returned sum. Default: `0`. +* __initialValue__: number primitive specifying the initial value of the returned sum. Default: `0`. -By default, the initial value of the sum is `0`. To choose a different one, use the `init` option. +By default, the initial value of the sum is `0`. To choose a different one, use the `initialValue` option. ```javascript -var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { +var out = sumSeries( geometricSeriesGenerator( 0.5 ), { 'init': 1 }); // returns 3 ``` -To change the maximum number of terms to be summed, set the `max_terms` option. +To change the maximum number of terms to be summed, set the `maxTerms` option. ```javascript -var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { +var out = sumSeries( geometricSeriesGenerator( 0.5 ), { 'max_terms': 10 }); // returns ~1.998 (infinite sum is 2) ``` -The default tolerance of `1e-16` used to assess convergence can be changed via the `tolerance` option. +The default tolerance of `2.22e-16` used to assess convergence can be changed via the `tolerance` option. ```javascript -var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { +var out = sumSeries( geometricSeriesGenerator( 0.5 ), { 'tolerance': 1e-3 }); // returns ~1.998 @@ -83,8 +82,8 @@ var out = continued_fraction( geometricSeriesGenerator( 0.5 ), { ## Examples ``` javascript -var log1p = require( 'math-float64-log1p' ); -var sumSeries = require( 'math-sum-series' ); +var log1p = require( '@stdlib/math/base/special/log1p' ); +var sumSeries = require( '@stdlib/math/base/tools/sum-series' ); function* log1p_series( x ) { var k = 0; From 4d8e748f0a92093fa563a28920608271686e6f85 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Fri, 6 May 2016 21:33:08 -0400 Subject: [PATCH 10/12] Reorder variable declarations, change option names --- .../math/base/tools/sum-series/lib/basic.js | 13 +++++++------ .../math/base/tools/sum-series/lib/generators.js | 15 ++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js index fae4f5b76c49..7adee27b673d 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js @@ -19,24 +19,25 @@ var MAX_TERMS = 1000000; * * @param {Function} generator - series function * @param {Object} [opts] - function options -* @param {Number} [opts.max_terms=1000000] - maximum number of terms to be added +* @param {Number} [opts.maxTerms=1000000] - maximum number of terms to be added * @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance -* @param {Number} [opts.init=0] - initial value of the resulting sum +* @param {Number} [opts.initialValue=0] - initial value of the resulting sum * @returns {Number} sum of all series terms */ function sum_series( generator, options ) { - var opts = {}; + var next_term; var tolerance; var counter; var result; - var next_term; + var opts; + opts = {}; if ( arguments.length > 1 ) { opts = options; } tolerance = opts.tolerance || TOLERANCE; - counter = opts.max_terms || MAX_TERMS; - result = opts.init || 0; + counter = opts.maxTerms || MAX_TERMS; + result = opts.initialValue || 0; // Repeatedly call function... do { diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js index a81d30edccdc..c94ae41ca504 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js @@ -19,25 +19,26 @@ var MAX_TERMS = 1000000; * * @param {Function} generator - series function * @param {Object} [opts] - function options -* @param {Number} [opts.max_terms=1000000] - maximum number of terms to be added +* @param {Number} [opts.maxTerms=1000000] - maximum number of terms to be added * @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance -* @param {Number} [opts.init=0] - initial value of the resulting sum +* @param {Number} [opts.initialValue=0] - initial value of the resulting sum * @returns {Number} sum of all series terms */ function sum_series( generator, options ) { - var opts = {}; - var tolerance; var isgenerator; + var next_term; + var tolerance; var counter; var result; - var next_term; + var opts; + opts = {}; if ( arguments.length > 1 ) { opts = options; } tolerance = opts.tolerance || TOLERANCE; - counter = opts.max_terms || MAX_TERMS; - result = opts.init || 0; + counter = opts.maxTerms || MAX_TERMS; + result = opts.initialValue || 0; isgenerator = typeof generator.next === 'function'; if ( isgenerator === true ) { From b4e2729ae8d5c557801fdce68a75b7e00ea371f8 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Fri, 6 May 2016 22:12:39 -0400 Subject: [PATCH 11/12] Name anonymous functions, change tolerance and option names in tests --- .../sum-series/test/es2015-generator/index.js | 4 +-- .../math/base/tools/sum-series/test/test.js | 35 +++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js index 138c6470f6b0..720b06c6dac8 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js @@ -6,16 +6,16 @@ var abs = require( '@stdlib/math/base/special/abs' ); var log1p = require( '@stdlib/math/base/special/log1p' ); var tape = require( 'tape' ); var sumSeries = require( './../../lib' ); +var EPS = require( '@stdlib/math/constants/float64-eps' ); // TESTS // tape( 'the function calculates the sum of an infinite series provided by a generator', function test( t ) { - // log1p( 0.5 ): var actual = sumSeries( generator( 0.5 ) ); var expected = log1p( 0.5 ); - t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.ok( abs( actual - expected ) < EPS, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); /* jshint esnext: true */ diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js index b3c8a39a87ae..a90f4b8cef65 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/test.js @@ -8,8 +8,9 @@ var proxyquire = require( 'proxyquire' ); var tape = require( 'tape' ); var sumSeries = require( './../lib' ); var sumSeriesBasic = proxyquire( './../lib', { - 'detect-generator-support': function(){ return false; } + 'detect-generator-support': function getFalse(){ return false; } }); +var EPS = require( '@stdlib/math/constants/float64-eps' ); // VARIABLES // @@ -32,18 +33,17 @@ if ( hasGeneratorsSupport ) { } tape( 'the function calculates the sum of an infinite series provided by a closure', function test( t ) { - // log1p( 0.5 ): var actual = sumSeries( closure( 0.5 ) ); var expected = log1p( 0.5 ); - t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.ok( abs( actual - expected ) < EPS, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); function closure( x ) { var k = 0; var m_mult = -x; var m_prod = -1; - return function() { + return function next() { m_prod *= m_mult; return ( m_prod / ++k ); }; @@ -51,18 +51,17 @@ tape( 'the function calculates the sum of an infinite series provided by a closu }); tape( 'the function calculates the sum of an infinite series provided by a closure (when generators are not supported)', function test( t ) { - // log1p( 0.5 ): var actual = sumSeriesBasic( closure( 0.5 ) ); var expected = log1p( 0.5 ); - t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.ok( abs( actual - expected ) < EPS, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); function closure( x ) { var k = 0; var m_mult = -x; var m_prod = -1; - return function() { + return function next() { m_prod *= m_mult; return ( m_prod / ++k ); }; @@ -70,18 +69,17 @@ tape( 'the function calculates the sum of an infinite series provided by a closu }); tape( 'the function calculates the sum of an infinite series with a specified initial value', function test( t ) { - // log1p( 0.5 ) + 2: - var actual = sumSeries( closure( 0.5 ), { 'init' : 2 } ); + var actual = sumSeries( closure( 0.5 ), { 'initialValue' : 2 } ); var expected = log1p( 0.5 ) + 2; - t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.ok( abs( actual - expected ) < EPS, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); function closure( x ) { var k = 0; var m_mult = -x; var m_prod = -1; - return function() { + return function next() { m_prod *= m_mult; return ( m_prod / ++k ); }; @@ -89,18 +87,17 @@ tape( 'the function calculates the sum of an infinite series with a specified in }); tape( 'the function calculates the sum of an infinite series with a specified initial value (when generators are not supported)', function test( t ) { - // log1p( 0.5 ) + 2: - var actual = sumSeriesBasic( closure( 0.5 ), { 'init' : 2 } ); + var actual = sumSeriesBasic( closure( 0.5 ), { 'initialValue' : 2 } ); var expected = log1p( 0.5 ) + 2; - t.ok( abs( actual - expected ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); + t.ok( abs( actual - expected ) < EPS, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); function closure( x ) { var k = 0; var m_mult = -x; var m_prod = -1; - return function() { + return function next() { m_prod *= m_mult; return ( m_prod / ++k ); }; @@ -108,7 +105,7 @@ tape( 'the function calculates the sum of an infinite series with a specified in }); tape( 'the function calculates the sum of a user-defined number of terms of the series', function test( t ) { - var actual = sumSeries( closure( 0.5 ), { 'max_terms' : 3 } ); + var actual = sumSeries( closure( 0.5 ), { 'maxTerms' : 3 } ); var expected = 6; t.equal( actual, expected, 'returned result is equal to expected value. actual: ' + actual + '; expected: ' + expected + '.' ); @@ -116,14 +113,14 @@ tape( 'the function calculates the sum of a user-defined number of terms of the function closure() { var k = 1; - return function() { + return function next() { return k++; }; } }); tape( 'the function calculates the sum of a user-defined number of terms of the series (when generators are not supported)', function test( t ) { - var actual = sumSeriesBasic( closure( 0.5 ), { 'max_terms' : 3 } ); + var actual = sumSeriesBasic( closure( 0.5 ), { 'maxTerms' : 3 } ); var expected = 6; t.equal( actual, expected, 'returned result is equal to expected value. actual: ' + actual + '; expected: ' + expected + '.' ); @@ -131,7 +128,7 @@ tape( 'the function calculates the sum of a user-defined number of terms of the function closure() { var k = 1; - return function() { + return function next() { return k++; }; } From 7aa9616a18a40710141694b3f779660eb9106127 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Fri, 6 May 2016 22:22:29 -0400 Subject: [PATCH 12/12] Add TODOs, JSDoc examples --- .../math/base/tools/sum-series/lib/basic.js | 16 ++++++++++++-- .../base/tools/sum-series/lib/generators.js | 17 +++++++++++++-- .../math/base/tools/sum-series/lib/index.js | 21 +++++++++++++++++++ .../sum-series/test/es2015-generator/index.js | 1 + 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js index 7adee27b673d..f47d8c7776ce 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/basic.js @@ -14,8 +14,7 @@ var MAX_TERMS = 1000000; // SUM SERIES // /** -* FUNCTION: sum_series( generator[, opts] ) -* Sums the element of the series given by the supplied function. +* Sum the element of the series given by the supplied function. * * @param {Function} generator - series function * @param {Object} [opts] - function options @@ -23,6 +22,19 @@ var MAX_TERMS = 1000000; * @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance * @param {Number} [opts.initialValue=0] - initial value of the resulting sum * @returns {Number} sum of all series terms +* +* @example +* var gen = geometricSeriesClosure( 0.9 ) +* var out = sumSeries( gen ); +* // returns 10 +* +* function geometricSeriesClosure( x ) { +* var exponent = -1; +* return function() { +* exponent += 1; +* return Math.pow( x, exponent ); +* }; +* } */ function sum_series( generator, options ) { var next_term; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js index c94ae41ca504..9b594fbc7863 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/generators.js @@ -14,8 +14,7 @@ var MAX_TERMS = 1000000; // SUM SERIES // /** -* FUNCTION: sum_series( generator[, opts] ) -* Sums the element of the series given by the supplied function. +* Sum the element of the series given by the supplied function. * * @param {Function} generator - series function * @param {Object} [opts] - function options @@ -23,6 +22,19 @@ var MAX_TERMS = 1000000; * @param {Number} [opts.tolerance=2.22e-16] - further terms are only added as long as the next term is greater than current term times the tolerance * @param {Number} [opts.initialValue=0] - initial value of the resulting sum * @returns {Number} sum of all series terms +* +* @example +* var gen = geometricSeriesGenerator( 0.9 ); +* var out = sumSeries( gen ); +* // returns 10 +* +* function* geometricSeriesGenerator( x ) { +* var exponent = 0; +* while ( true ) { +* yield Math.pow( x, exponent ); +* exponent += 1; +* } +* } */ function sum_series( generator, options ) { var isgenerator; @@ -43,6 +55,7 @@ function sum_series( generator, options ) { isgenerator = typeof generator.next === 'function'; if ( isgenerator === true ) { // Case A: Iterate over generator object created by a generator function... + // TODO: remove once switch to ESLint is complete /* jshint esnext: true */ for ( next_term of generator ) { result += next_term; diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js index 5aa7202bfd57..432e886e2a38 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/lib/index.js @@ -1,5 +1,26 @@ 'use strict'; +/** +* Sum the element of the series given by the supplied function. +* +* @module @stdlib/math/base/tools/sum-series +* +* @example +* var sumSeries = require( '@stdlib/math/base/tools/sum-series' ); +* +* var gen = geometricSeriesClosure( 0.9 ) +* var out = sumSeries( gen ); +* // returns 10 +* +* function geometricSeriesClosure( x ) { +* var exponent = -1; +* return function() { +* exponent += 1; +* return Math.pow( x, exponent ); +* }; +* } +*/ + // MODULES // var hasGeneratorsSupport = require( '@stdlib/utils/detect-generator-support' )(); diff --git a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js index 720b06c6dac8..db37aa2862ff 100644 --- a/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js +++ b/lib/node_modules/@stdlib/math/base/tools/sum-series/test/es2015-generator/index.js @@ -18,6 +18,7 @@ tape( 'the function calculates the sum of an infinite series provided by a gener t.ok( abs( actual - expected ) < EPS, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected + '.' ); t.end(); + // TODO: remove once switch to ESLint is complete /* jshint esnext: true */ function* generator( x ) { var k = 0;