From 6aadece14f5c4d8f8e7726fabc3c49678c49b593 Mon Sep 17 00:00:00 2001 From: stdlib-bot Date: Sun, 24 Mar 2024 11:27:09 +0000 Subject: [PATCH] Auto-generated commit --- .../evalpoly-compile-c/docs/types/index.d.ts | 6 +- .../evalpoly-compile/docs/types/index.d.ts | 6 +- .../docs/types/index.d.ts | 8 +- base/tools/evalrational-compile/README.md | 114 +- .../docs/types/index.d.ts | 17 +- .../evalrational-compile/docs/types/test.ts | 42 + .../evalrational-compile/examples/index.js | 27 +- base/tools/evalrational-compile/lib/main.js | 105 +- .../lib/templates/evalrational.float32.js.txt | 50 + .../lib/templates/loop.float32.js.txt | 70 ++ .../fixtures/coefficient_ratio.float32.js.txt | 19 + .../fixtures/coefficient_ratio_integer.js.txt | 2 +- .../fixtures/evalrational1.float32.js.txt | 50 + .../fixtures/evalrational2.float32.js.txt | 50 + .../fixtures/evalrational3.float32.js.txt | 50 + .../test/fixtures/loop1.float32.js.txt | 1070 +++++++++++++++++ .../test/fixtures/loop2.float32.js.txt | 1070 +++++++++++++++++ base/tools/evalrational-compile/test/test.js | 475 +++++++- 18 files changed, 3144 insertions(+), 87 deletions(-) create mode 100644 base/tools/evalrational-compile/lib/templates/evalrational.float32.js.txt create mode 100644 base/tools/evalrational-compile/lib/templates/loop.float32.js.txt create mode 100644 base/tools/evalrational-compile/test/fixtures/coefficient_ratio.float32.js.txt create mode 100644 base/tools/evalrational-compile/test/fixtures/evalrational1.float32.js.txt create mode 100644 base/tools/evalrational-compile/test/fixtures/evalrational2.float32.js.txt create mode 100644 base/tools/evalrational-compile/test/fixtures/evalrational3.float32.js.txt create mode 100644 base/tools/evalrational-compile/test/fixtures/loop1.float32.js.txt create mode 100644 base/tools/evalrational-compile/test/fixtures/loop2.float32.js.txt diff --git a/base/tools/evalpoly-compile-c/docs/types/index.d.ts b/base/tools/evalpoly-compile-c/docs/types/index.d.ts index 4aa909edb..511529158 100644 --- a/base/tools/evalpoly-compile-c/docs/types/index.d.ts +++ b/base/tools/evalpoly-compile-c/docs/types/index.d.ts @@ -18,6 +18,10 @@ // TypeScript Version: 4.1 +/// + +import { Collection } from '@stdlib/types/array'; + /** * Interface describing function options. */ @@ -44,7 +48,7 @@ interface Options { * var str = compile( [ 3.0, 2.0, 1.0 ] ); * // returns */ -declare function compile( c: Array, options?: Options ): string; +declare function compile( c: Collection, options?: Options ): string; // EXPORTS // diff --git a/base/tools/evalpoly-compile/docs/types/index.d.ts b/base/tools/evalpoly-compile/docs/types/index.d.ts index 93e260005..137659881 100644 --- a/base/tools/evalpoly-compile/docs/types/index.d.ts +++ b/base/tools/evalpoly-compile/docs/types/index.d.ts @@ -18,6 +18,10 @@ // TypeScript Version: 4.1 +/// + +import { Collection } from '@stdlib/types/array'; + /** * Interface describing function options. */ @@ -39,7 +43,7 @@ interface Options { * var str = compile( [ 3.0, 2.0, 1.0 ] ); * // returns */ -declare function compile( c: Array, options?: Options ): string; +declare function compile( c: Collection, options?: Options ): string; // EXPORTS // diff --git a/base/tools/evalrational-compile-c/docs/types/index.d.ts b/base/tools/evalrational-compile-c/docs/types/index.d.ts index c4233395c..22e0e869d 100644 --- a/base/tools/evalrational-compile-c/docs/types/index.d.ts +++ b/base/tools/evalrational-compile-c/docs/types/index.d.ts @@ -18,6 +18,10 @@ // TypeScript Version: 4.1 +/// + +import { Collection } from '@stdlib/types/array'; + /** * Interface describing function options. */ @@ -25,7 +29,7 @@ interface Options { /** * Input value floating-point data type (e.g., `double` or `float`). Default: `'double'`. */ - dtype?: string; + dtype?: 'double' | 'float'; /** * Function name. Default: `'evalpoly'`. @@ -48,7 +52,7 @@ interface Options { * var str = compile( P, Q ); * // returns */ -declare function compile( P: Array, Q: Array, options?: Options ): string; +declare function compile( P: Collection, Q: Collection, options?: Options ): string; // EXPORTS // diff --git a/base/tools/evalrational-compile/README.md b/base/tools/evalrational-compile/README.md index bac477150..c0a49fa56 100644 --- a/base/tools/evalrational-compile/README.md +++ b/base/tools/evalrational-compile/README.md @@ -36,9 +36,9 @@ limitations under the License. var compile = require( '@stdlib/math/base/tools/evalrational-compile' ); ``` -#### compile( P, Q ) +#### compile( P, Q\[, options] ) -Compiles a module `string` containing an exported function which evaluates a [rational function][@stdlib/math/base/tools/evalrational] having coefficients `P` and `Q`. +Compiles a module string containing an exported function which evaluates a [rational function][@stdlib/math/base/tools/evalrational] having coefficients `P` and `Q`. ```javascript var P = [ 3.0, 2.0, 1.0 ]; @@ -48,7 +48,11 @@ var str = compile( P, Q ); // returns ``` -In the example above, the output `string` would correspond to the following module: +The function supports the following `options`: + +- **dtype**: input argument floating-point data type (e.g., `float64` or `float32`). Default: `'float64'`. + +In the example above, the output string would correspond to the following module: @@ -84,12 +88,12 @@ function evalrational( x ) { ax = x; } if ( ax <= 1.0 ) { - s1 = 3.0 + (x * (2.0 + (x * 1.0))); // eslint-disable-line max-len - s2 = -1.0 + (x * (-2.0 + (x * -3.0))); // eslint-disable-line max-len + s1 = 3.0 + (x * (2.0 + (x * 1.0))); + s2 = -1.0 + (x * (-2.0 + (x * -3.0))); } else { x = 1.0 / x; - s1 = 1.0 + (x * (2.0 + (x * 3.0))); // eslint-disable-line max-len - s2 = -3.0 + (x * (-2.0 + (x * -1.0))); // eslint-disable-line max-len + s1 = 1.0 + (x * (2.0 + (x * 3.0))); + s2 = -3.0 + (x * (-2.0 + (x * -1.0))); } return s1 / s2; } @@ -102,6 +106,75 @@ module.exports = evalrational; The coefficients should be ordered in **ascending** degree, thus matching summation notation. +By default, the function assumes double-precision floating-point arithmetic. To emulate single-precision floating-point arithmetic, set the `dtype` option to `'float32'`. + +```javascript +var P = [ 3.0, 2.0, 1.0 ]; +var Q = [ -1.0, -2.0, -3.0 ]; + +var str = compile( P, Q, { + 'dtype': 'float32' +}); +// returns +``` + +In the previous example, the output string would correspond to the following module: + + + +```javascript +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var ax; + var s1; + var s2; + if ( x === 0.0 ) { + return -3.0; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = float64ToFloat32(3.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * 1.0)))); // eslint-disable-line max-len + s2 = float64ToFloat32(-1.0 + float64ToFloat32(x * float64ToFloat32(-2.0 + float64ToFloat32(x * -3.0)))); // eslint-disable-line max-len + } else { + x = float64ToFloat32( 1.0 / x ); + s1 = float64ToFloat32(1.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * 3.0)))); // eslint-disable-line max-len + s2 = float64ToFloat32(-3.0 + float64ToFloat32(x * float64ToFloat32(-2.0 + float64ToFloat32(x * -1.0)))); // eslint-disable-line max-len + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; +``` + @@ -123,32 +196,15 @@ The coefficients should be ordered in **ascending** degree, thus matching summat ```javascript -var randu = require( '@stdlib/random/base/randu' ); -var round = require( '@stdlib/math/base/special/round' ); -var Float64Array = require( '@stdlib/array/float64' ); +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); var compile = require( '@stdlib/math/base/tools/evalrational-compile' ); -var sign; -var str; -var P; -var Q; -var i; - -// Create two arrays of random coefficients... -P = new Float64Array( 10 ); -Q = new Float64Array( 10 ); -for ( i = 0; i < P.length; i++ ) { - if ( randu() < 0.5 ) { - sign = -1.0; - } else { - sign = 1.0; - } - P[ i ] = sign * round( randu()*100.0 ); - Q[ i ] = sign * round( randu()*100.0 ); -} +// Create arrays of random coefficients: +var P = discreteUniform( 10, -100, 100 ); +var Q = discreteUniform( 10, -100, 100 ); // Compile a module for evaluating a rational function: -str = compile( P, Q ); +var str = compile( P, Q ); console.log( str ); ``` diff --git a/base/tools/evalrational-compile/docs/types/index.d.ts b/base/tools/evalrational-compile/docs/types/index.d.ts index f224d81c3..749ca7163 100644 --- a/base/tools/evalrational-compile/docs/types/index.d.ts +++ b/base/tools/evalrational-compile/docs/types/index.d.ts @@ -18,11 +18,26 @@ // TypeScript Version: 4.1 +/// + +import { Collection } from '@stdlib/types/array'; + +/** +* Interface describing function options. +*/ +interface Options { + /** + * Input value floating-point data type (e.g., `float64` or `float32`). Default: `'float64'`. + */ + dtype?: 'float64' | 'float32'; +} + /** * Compiles a module string which exports a function for evaluating a rational function. * * @param P - numerator polynomial coefficients sorted in ascending degree * @param Q - denominator polynomial coefficients sorted in ascending degree +* @param options - function options * @returns module string exporting a function for evaluating a rational function * * @example @@ -32,7 +47,7 @@ * var str = compile( P, Q ); * // returns */ -declare function compile( P: Array, Q: Array ): string; +declare function compile( P: Collection, Q: Collection, options?: Options ): string; // EXPORTS // diff --git a/base/tools/evalrational-compile/docs/types/test.ts b/base/tools/evalrational-compile/docs/types/test.ts index 82cb278fa..7a58924b4 100644 --- a/base/tools/evalrational-compile/docs/types/test.ts +++ b/base/tools/evalrational-compile/docs/types/test.ts @@ -24,33 +24,75 @@ import compile = require( './index' ); // The function returns a string... { compile( [ -6.0, -5.0 ], [ 3.0, 0.5 ] ); // $ExpectType string + compile( [ 3.0, 2.0, 1.0 ], { 'dtype': 'float32' } ); // $ExpectType string } // The compiler throws an error if the function is provided a first argument which is not an array of numbers... { const Q = [ 3.0, 0.5 ]; + compile( true, Q ); // $ExpectError compile( false, Q ); // $ExpectError compile( 'abc', Q ); // $ExpectError compile( 123, Q ); // $ExpectError compile( {}, Q ); // $ExpectError compile( ( x: number ): number => x, Q ); // $ExpectError + + compile( true, Q, {} ); // $ExpectError + compile( false, Q, {} ); // $ExpectError + compile( 'abc', Q, {} ); // $ExpectError + compile( 123, Q, {} ); // $ExpectError + compile( {}, Q, {} ); // $ExpectError + compile( ( x: number ): number => x, Q, {} ); // $ExpectError } // The compiler throws an error if the function is provided a second argument which is not an array of numbers... { const P = [ -6.0, -5.0 ]; + compile( P, true ); // $ExpectError compile( P, false ); // $ExpectError compile( P, 'abc' ); // $ExpectError compile( P, 123 ); // $ExpectError compile( P, {} ); // $ExpectError compile( P, ( x: number ): number => x ); // $ExpectError + + compile( P, true, {} ); // $ExpectError + compile( P, false, {} ); // $ExpectError + compile( P, 'abc', {} ); // $ExpectError + compile( P, 123, {} ); // $ExpectError + compile( P, {}, {} ); // $ExpectError + compile( P, ( x: number ): number => x, {} ); // $ExpectError +} + +// The compiler throws an error if the function is provided a third argument which is not an object... +{ + const P = [ -6.0, -5.0 ]; + const Q = [ 3.0, 0.5 ]; + + compile( P, Q, true ); // $ExpectError + compile( P, Q, false ); // $ExpectError + compile( P, Q, 'abc' ); // $ExpectError + compile( P, Q, 123 ); // $ExpectError + compile( P, Q, ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an invalid `dtype` option... +{ + const P = [ -6.0, -5.0 ]; + const Q = [ 3.0, 0.5 ]; + + compile( P, Q, { 'dtype': true } ); // $ExpectError + compile( P, Q, { 'dtype': false } ); // $ExpectError + compile( P, Q, { 'dtype': [] } ); // $ExpectError + compile( P, Q, { 'dtype': 123 } ); // $ExpectError + compile( P, Q, { 'dtype': ( x: number ): number => x } ); // $ExpectError } // The compiler throws an error if the function is provided an insufficient number of arguments... { const P = [ -6.0, -5.0 ]; + compile(); // $ExpectError compile( P ); // $ExpectError } diff --git a/base/tools/evalrational-compile/examples/index.js b/base/tools/evalrational-compile/examples/index.js index 0dd133bde..1bde208e6 100644 --- a/base/tools/evalrational-compile/examples/index.js +++ b/base/tools/evalrational-compile/examples/index.js @@ -19,9 +19,7 @@ 'use strict'; var resolve = require( 'path' ).resolve; -var randu = require( '@stdlib/random/base/randu' ); -var round = require( './../../../../base/special/round' ); -var Float64Array = require( '@stdlib/array/float64' ); +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); var tryRequire = require( '@stdlib/utils/try-require' ); var compile = tryRequire( resolve( __dirname, '..', 'lib' ) ); @@ -32,26 +30,11 @@ if ( compile instanceof Error ) { } function main() { - var sign; - var str; - var P; - var Q; - var i; - - // Create two arrays of random coefficients... - P = new Float64Array( 10 ); - Q = new Float64Array( 10 ); - for ( i = 0; i < P.length; i++ ) { - if ( randu() < 0.5 ) { - sign = -1.0; - } else { - sign = 1.0; - } - P[ i ] = sign * round( randu()*100.0 ); - Q[ i ] = sign * round( randu()*100.0 ); - } + // Create arrays of random coefficients: + var P = discreteUniform( 10, -100, 100 ); + var Q = discreteUniform( 10, -100, 100 ); // Compile a module for evaluating a rational function: - str = compile( P, Q ); + var str = compile( P, Q ); console.log( str ); } diff --git a/base/tools/evalrational-compile/lib/main.js b/base/tools/evalrational-compile/lib/main.js index 81289ac12..b774195b0 100644 --- a/base/tools/evalrational-compile/lib/main.js +++ b/base/tools/evalrational-compile/lib/main.js @@ -24,6 +24,8 @@ var join = require( 'path' ).join; var readFile = require( '@stdlib/fs/read-file' ).sync; var replace = require( '@stdlib/string/replace' ); var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var Float32Array = require( '@stdlib/array/float32' ); +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); // VARIABLES // @@ -35,9 +37,15 @@ var dir = join( __dirname, 'templates' ); // Templates: var COEFFICIENT_RATIO_TEMPLATE = readFile( join( dir, 'coefficient_ratio.js.txt' ), opts ); // eslint-disable-line id-length + var EVALRATIONAL_TEMPLATE = readFile( join( dir, 'evalrational.js.txt' ), opts ); +var EVALRATIONAL_FLOAT32_TEMPLATE = readFile( join( dir, 'evalrational.float32.js.txt' ), opts ); // eslint-disable-line id-length + var LOOP_TEMPLATE = readFile( join( dir, 'loop.js.txt' ), opts ); +var LOOP_FLOAT32_TEMPLATE = readFile( join( dir, 'loop.float32.js.txt' ), opts ); + var NAN_TEMPLATE = readFile( join( dir, 'nan.js.txt' ), opts ); + var MAX_CHARS = 66; // max-len (80) - chars already in line ('2x tab': 8, 's1 = ': 5, ';': 1) @@ -91,9 +99,10 @@ function array2list( x ) { * * @private * @param {NumericArray} x - coefficients sorted in ascending degree +* @param {string} dtype - input value floating-point data type * @returns {string} output string */ -function hornerAscending( x ) { +function hornerAscending( x, dtype ) { var str; var n; var m; @@ -101,14 +110,26 @@ function hornerAscending( x ) { n = x.length; m = n - 1; - str = x[ 0 ].toString(); + if ( dtype === 'float32' ) { + str = 'float64ToFloat32('; + } else { + str = ''; + } + str += x[ 0 ].toString(); if ( isInteger( x[ 0 ] ) ) { str += '.0'; } for ( i = 1; i < n; i++ ) { - str += ' + (x * '; - if ( i < m ) { - str += '('; + if ( dtype === 'float32' ) { + str += ' + float64ToFloat32(x * '; + if ( i < m ) { + str += 'float64ToFloat32('; + } + } else { + str += ' + (x * '; + if ( i < m ) { + str += '('; + } } str += x[ i ].toString(); if ( isInteger( x[ i ] ) ) { @@ -119,6 +140,9 @@ function hornerAscending( x ) { for ( i = 0; i < (2*m)-1; i++ ) { str += ')'; } + if ( dtype === 'float32' ) { + str += ')'; + } return str; } @@ -127,22 +151,35 @@ function hornerAscending( x ) { * * @private * @param {NumericArray} x - coefficients sorted in descending degree +* @param {string} dtype - input value floating-point data type * @returns {string} output string */ -function hornerDescending( x ) { +function hornerDescending( x, dtype ) { var str; var m; var i; m = x.length - 1; - str = x[ m ].toString(); + if ( dtype === 'float32' ) { + str = 'float64ToFloat32('; + } else { + str = ''; + } + str += x[ m ].toString(); if ( isInteger( x[ m ] ) ) { str += '.0'; } for ( i = m-1; i >= 0; i-- ) { - str += ' + (x * '; - if ( i > 0 ) { - str += '('; + if ( dtype === 'float32' ) { + str += ' + float64ToFloat32(x * '; + if ( i > 0 ) { + str += 'float64ToFloat32('; + } + } else { + str += ' + (x * '; + if ( i > 0 ) { + str += '('; + } } str += x[ i ].toString(); if ( isInteger( x[ i ] ) ) { @@ -153,6 +190,9 @@ function hornerDescending( x ) { for ( i = 0; i < (2*m)-1; i++ ) { str += ')'; } + if ( dtype === 'float32' ) { + str += ')'; + } return str; } @@ -183,6 +223,8 @@ function replaceString( src, target, str ) { * * @param {NumericArray} P - numerator polynomial coefficients sorted in ascending degree * @param {NumericArray} Q - denominator polynomial coefficients sorted in ascending degree +* @param {Options} [options] - function options +* @param {string} [options.dtype='float64'] - input value floating-point data type * @returns {string} module string exporting a function for evaluating a rational function * * @example @@ -192,10 +234,19 @@ function replaceString( src, target, str ) { * var str = compile( P, Q ); * // returns */ -function compile( P, Q ) { +function compile( P, Q, options ) { + var opts; + var tmpl; var str; var n; + var r; + opts = { + 'dtype': 'float64' + }; + if ( arguments.length > 2 ) { + opts.dtype = options.dtype || opts.dtype; + } n = P.length; // If no coefficients, the function always returns NaN... @@ -206,22 +257,38 @@ function compile( P, Q ) { if ( n !== Q.length ) { return NAN_TEMPLATE; } + r = P[0] / Q[0]; + if ( opts.dtype === 'float32' ) { + P = new Float32Array( P ); + Q = new Float32Array( Q ); + r = float64ToFloat32( r ); + } // If P and Q only have one coefficient, the function always returns the ratio of those coefficients... if ( n === 1 ) { - return replace( COEFFICIENT_RATIO_TEMPLATE, '{{ratio}}', value2string( P[0] / Q[0] ) ); + return replace( COEFFICIENT_RATIO_TEMPLATE, '{{ratio}}', value2string( r ) ); } // Avoid exceeding the maximum stack size on V8 by using a simple loop :(. Note that the choice of `500` was empirically determined... if ( n > 500 ) { - str = replace( LOOP_TEMPLATE, '{{P}}', array2list( P ) ); + if ( opts.dtype === 'float32' ) { + tmpl = LOOP_FLOAT32_TEMPLATE; + } else { + tmpl = LOOP_TEMPLATE; + } + str = replace( tmpl, '{{P}}', array2list( P ) ); str = replace( str, '{{Q}}', array2list( Q ) ); - return replace( str, '{{ratio}}', value2string( P[0]/Q[0] ) ); + return replace( str, '{{ratio}}', value2string( r ) ); } // If more than one coefficient, apply Horner's method... - str = replaceString( EVALRATIONAL_TEMPLATE, 'P_ASCENDING', hornerAscending( P ) ); - str = replaceString( str, 'Q_ASCENDING', hornerAscending( Q ) ); - str = replaceString( str, 'P_DESCENDING', hornerDescending( P ) ); - str = replaceString( str, 'Q_DESCENDING', hornerDescending( Q ) ); - return replace( str, '{{ratio}}', value2string( P[0]/Q[0] ) ); + if ( opts.dtype === 'float32' ) { + tmpl = EVALRATIONAL_FLOAT32_TEMPLATE; + } else { + tmpl = EVALRATIONAL_TEMPLATE; + } + str = replaceString( tmpl, 'P_ASCENDING', hornerAscending( P, opts.dtype ) ); + str = replaceString( str, 'Q_ASCENDING', hornerAscending( Q, opts.dtype ) ); + str = replaceString( str, 'P_DESCENDING', hornerDescending( P, opts.dtype ) ); + str = replaceString( str, 'Q_DESCENDING', hornerDescending( Q, opts.dtype ) ); + return replace( str, '{{ratio}}', value2string( r ) ); } diff --git a/base/tools/evalrational-compile/lib/templates/evalrational.float32.js.txt b/base/tools/evalrational-compile/lib/templates/evalrational.float32.js.txt new file mode 100644 index 000000000..9cc338633 --- /dev/null +++ b/base/tools/evalrational-compile/lib/templates/evalrational.float32.js.txt @@ -0,0 +1,50 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var ax; + var s1; + var s2; + if ( x === 0.0 ) { + return {{ratio}}; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = {{P_ASCENDING}};{{P_ASCENDING_ESLINT}} + s2 = {{Q_ASCENDING}};{{Q_ASCENDING_ESLINT}} + } else { + x = float64ToFloat32( 1.0 / x ); + s1 = {{P_DESCENDING}};{{P_DESCENDING_ESLINT}} + s2 = {{Q_DESCENDING}};{{Q_DESCENDING_ESLINT}} + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/lib/templates/loop.float32.js.txt b/base/tools/evalrational-compile/lib/templates/loop.float32.js.txt new file mode 100644 index 000000000..8d41096d7 --- /dev/null +++ b/base/tools/evalrational-compile/lib/templates/loop.float32.js.txt @@ -0,0 +1,70 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); +var abs = require( '@stdlib/math/base/special/abs' ); + + +// VARIABLES // + +var P = [ +{{P}} +]; +var Q = [ +{{Q}} +]; +var END = P.length - 1; + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var s1; + var s2; + var i; + + if ( x === 0.0 ) { + return {{ratio}}; + } + if ( abs( x ) <= 1.0 ) { + s1 = P[ END ]; + s2 = Q[ END ]; + for ( i = END-1; i >= 0; i-- ) { + s1 = float64ToFloat32( s1 * x ); + s2 = float64ToFloat32( s2 * x ); + s1 = float64ToFloat32( s1 + P[ i ] ); + s2 = float64ToFloat32( s2 + Q[ i ] ); + } + } else { + x = float64ToFloat32( 1.0 / x ); // use inverse to avoid overflow + s1 = P[ 0 ]; + s2 = Q[ 0 ]; + for ( i = 1; i <= END; i++ ) { + s1 = float64ToFloat32( s1 * x ); + s2 = float64ToFloat32( s2 * x ); + s1 = float64ToFloat32( s1 + P[ i ] ); + s2 = float64ToFloat32( s2 + Q[ i ] ); + } + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/fixtures/coefficient_ratio.float32.js.txt b/base/tools/evalrational-compile/test/fixtures/coefficient_ratio.float32.js.txt new file mode 100644 index 000000000..9c5441284 --- /dev/null +++ b/base/tools/evalrational-compile/test/fixtures/coefficient_ratio.float32.js.txt @@ -0,0 +1,19 @@ +'use strict'; + +// MAIN // + +/** +* Evaluates a rational function. +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational() { + return -6.28000020980835; +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/fixtures/coefficient_ratio_integer.js.txt b/base/tools/evalrational-compile/test/fixtures/coefficient_ratio_integer.js.txt index 0dd61b1ff..bc02f6d8c 100644 --- a/base/tools/evalrational-compile/test/fixtures/coefficient_ratio_integer.js.txt +++ b/base/tools/evalrational-compile/test/fixtures/coefficient_ratio_integer.js.txt @@ -10,7 +10,7 @@ * @returns {number} evaluated rational function */ function evalrational() { - return -2.0; + return -1.5; } diff --git a/base/tools/evalrational-compile/test/fixtures/evalrational1.float32.js.txt b/base/tools/evalrational-compile/test/fixtures/evalrational1.float32.js.txt new file mode 100644 index 000000000..49b2b1280 --- /dev/null +++ b/base/tools/evalrational-compile/test/fixtures/evalrational1.float32.js.txt @@ -0,0 +1,50 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var ax; + var s1; + var s2; + if ( x === 0.0 ) { + return 0.25; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = float64ToFloat32(1.0 + float64ToFloat32(x * float64ToFloat32(2.5 + float64ToFloat32(x * float64ToFloat32(3.140000104904175 + float64ToFloat32(x * -1.0)))))); // eslint-disable-line max-len + s2 = float64ToFloat32(4.0 + float64ToFloat32(x * float64ToFloat32(-3.5 + float64ToFloat32(x * float64ToFloat32(2.200000047683716 + float64ToFloat32(x * 1.25)))))); // eslint-disable-line max-len + } else { + x = float64ToFloat32( 1.0 / x ); + s1 = float64ToFloat32(-1.0 + float64ToFloat32(x * float64ToFloat32(3.140000104904175 + float64ToFloat32(x * float64ToFloat32(2.5 + float64ToFloat32(x * 1.0)))))); // eslint-disable-line max-len + s2 = float64ToFloat32(1.25 + float64ToFloat32(x * float64ToFloat32(2.200000047683716 + float64ToFloat32(x * float64ToFloat32(-3.5 + float64ToFloat32(x * 4.0)))))); // eslint-disable-line max-len + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/fixtures/evalrational2.float32.js.txt b/base/tools/evalrational-compile/test/fixtures/evalrational2.float32.js.txt new file mode 100644 index 000000000..10ccc1b43 --- /dev/null +++ b/base/tools/evalrational-compile/test/fixtures/evalrational2.float32.js.txt @@ -0,0 +1,50 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var ax; + var s1; + var s2; + if ( x === 0.0 ) { + return -0.5233333706855774; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = float64ToFloat32(-3.140000104904175 + float64ToFloat32(x * 0.0)); + s2 = float64ToFloat32(6.0 + float64ToFloat32(x * 0.0)); + } else { + x = float64ToFloat32( 1.0 / x ); + s1 = float64ToFloat32(0.0 + float64ToFloat32(x * -3.140000104904175)); + s2 = float64ToFloat32(0.0 + float64ToFloat32(x * 6.0)); + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/fixtures/evalrational3.float32.js.txt b/base/tools/evalrational-compile/test/fixtures/evalrational3.float32.js.txt new file mode 100644 index 000000000..07ef4f2b3 --- /dev/null +++ b/base/tools/evalrational-compile/test/fixtures/evalrational3.float32.js.txt @@ -0,0 +1,50 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var ax; + var s1; + var s2; + if ( x === 0.0 ) { + return -0.5233333706855774; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = float64ToFloat32(-3.140000104904175 + float64ToFloat32(x * float64ToFloat32(0.0 + float64ToFloat32(x * float64ToFloat32(4.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * float64ToFloat32(3.0 + float64ToFloat32(x * float64ToFloat32(9.0 + float64ToFloat32(x * 5.400000095367432)))))))))))); // eslint-disable-line max-len + s2 = float64ToFloat32(6.0 + float64ToFloat32(x * float64ToFloat32(0.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * float64ToFloat32(1.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * float64ToFloat32(4.800000190734863 + float64ToFloat32(x * 2.200000047683716)))))))))))); // eslint-disable-line max-len + } else { + x = float64ToFloat32( 1.0 / x ); + s1 = float64ToFloat32(5.400000095367432 + float64ToFloat32(x * float64ToFloat32(9.0 + float64ToFloat32(x * float64ToFloat32(3.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * float64ToFloat32(4.0 + float64ToFloat32(x * float64ToFloat32(0.0 + float64ToFloat32(x * -3.140000104904175)))))))))))); // eslint-disable-line max-len + s2 = float64ToFloat32(2.200000047683716 + float64ToFloat32(x * float64ToFloat32(4.800000190734863 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * float64ToFloat32(1.0 + float64ToFloat32(x * float64ToFloat32(2.0 + float64ToFloat32(x * float64ToFloat32(0.0 + float64ToFloat32(x * 6.0)))))))))))); // eslint-disable-line max-len + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/fixtures/loop1.float32.js.txt b/base/tools/evalrational-compile/test/fixtures/loop1.float32.js.txt new file mode 100644 index 000000000..d062bdb4f --- /dev/null +++ b/base/tools/evalrational-compile/test/fixtures/loop1.float32.js.txt @@ -0,0 +1,1070 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); +var abs = require( '@stdlib/math/base/special/abs' ); + + +// VARIABLES // + +var P = [ + 0.0, + 1.0, + 2.0, + 3.0, + 4.0, + 5.0, + 6.0, + 7.0, + 8.0, + 9.0, + 10.0, + 11.0, + 12.0, + 13.0, + 14.0, + 15.0, + 16.0, + 17.0, + 18.0, + 19.0, + 20.0, + 21.0, + 22.0, + 23.0, + 24.0, + 25.0, + 26.0, + 27.0, + 28.0, + 29.0, + 30.0, + 31.0, + 32.0, + 33.0, + 34.0, + 35.0, + 36.0, + 37.0, + 38.0, + 39.0, + 40.0, + 41.0, + 42.0, + 43.0, + 44.0, + 45.0, + 46.0, + 47.0, + 48.0, + 49.0, + 50.0, + 51.0, + 52.0, + 53.0, + 54.0, + 55.0, + 56.0, + 57.0, + 58.0, + 59.0, + 60.0, + 61.0, + 62.0, + 63.0, + 64.0, + 65.0, + 66.0, + 67.0, + 68.0, + 69.0, + 70.0, + 71.0, + 72.0, + 73.0, + 74.0, + 75.0, + 76.0, + 77.0, + 78.0, + 79.0, + 80.0, + 81.0, + 82.0, + 83.0, + 84.0, + 85.0, + 86.0, + 87.0, + 88.0, + 89.0, + 90.0, + 91.0, + 92.0, + 93.0, + 94.0, + 95.0, + 96.0, + 97.0, + 98.0, + 99.0, + 100.0, + 101.0, + 102.0, + 103.0, + 104.0, + 105.0, + 106.0, + 107.0, + 108.0, + 109.0, + 110.0, + 111.0, + 112.0, + 113.0, + 114.0, + 115.0, + 116.0, + 117.0, + 118.0, + 119.0, + 120.0, + 121.0, + 122.0, + 123.0, + 124.0, + 125.0, + 126.0, + 127.0, + 128.0, + 129.0, + 130.0, + 131.0, + 132.0, + 133.0, + 134.0, + 135.0, + 136.0, + 137.0, + 138.0, + 139.0, + 140.0, + 141.0, + 142.0, + 143.0, + 144.0, + 145.0, + 146.0, + 147.0, + 148.0, + 149.0, + 150.0, + 151.0, + 152.0, + 153.0, + 154.0, + 155.0, + 156.0, + 157.0, + 158.0, + 159.0, + 160.0, + 161.0, + 162.0, + 163.0, + 164.0, + 165.0, + 166.0, + 167.0, + 168.0, + 169.0, + 170.0, + 171.0, + 172.0, + 173.0, + 174.0, + 175.0, + 176.0, + 177.0, + 178.0, + 179.0, + 180.0, + 181.0, + 182.0, + 183.0, + 184.0, + 185.0, + 186.0, + 187.0, + 188.0, + 189.0, + 190.0, + 191.0, + 192.0, + 193.0, + 194.0, + 195.0, + 196.0, + 197.0, + 198.0, + 199.0, + 200.0, + 201.0, + 202.0, + 203.0, + 204.0, + 205.0, + 206.0, + 207.0, + 208.0, + 209.0, + 210.0, + 211.0, + 212.0, + 213.0, + 214.0, + 215.0, + 216.0, + 217.0, + 218.0, + 219.0, + 220.0, + 221.0, + 222.0, + 223.0, + 224.0, + 225.0, + 226.0, + 227.0, + 228.0, + 229.0, + 230.0, + 231.0, + 232.0, + 233.0, + 234.0, + 235.0, + 236.0, + 237.0, + 238.0, + 239.0, + 240.0, + 241.0, + 242.0, + 243.0, + 244.0, + 245.0, + 246.0, + 247.0, + 248.0, + 249.0, + 250.0, + 251.0, + 252.0, + 253.0, + 254.0, + 255.0, + 256.0, + 257.0, + 258.0, + 259.0, + 260.0, + 261.0, + 262.0, + 263.0, + 264.0, + 265.0, + 266.0, + 267.0, + 268.0, + 269.0, + 270.0, + 271.0, + 272.0, + 273.0, + 274.0, + 275.0, + 276.0, + 277.0, + 278.0, + 279.0, + 280.0, + 281.0, + 282.0, + 283.0, + 284.0, + 285.0, + 286.0, + 287.0, + 288.0, + 289.0, + 290.0, + 291.0, + 292.0, + 293.0, + 294.0, + 295.0, + 296.0, + 297.0, + 298.0, + 299.0, + 300.0, + 301.0, + 302.0, + 303.0, + 304.0, + 305.0, + 306.0, + 307.0, + 308.0, + 309.0, + 310.0, + 311.0, + 312.0, + 313.0, + 314.0, + 315.0, + 316.0, + 317.0, + 318.0, + 319.0, + 320.0, + 321.0, + 322.0, + 323.0, + 324.0, + 325.0, + 326.0, + 327.0, + 328.0, + 329.0, + 330.0, + 331.0, + 332.0, + 333.0, + 334.0, + 335.0, + 336.0, + 337.0, + 338.0, + 339.0, + 340.0, + 341.0, + 342.0, + 343.0, + 344.0, + 345.0, + 346.0, + 347.0, + 348.0, + 349.0, + 350.0, + 351.0, + 352.0, + 353.0, + 354.0, + 355.0, + 356.0, + 357.0, + 358.0, + 359.0, + 360.0, + 361.0, + 362.0, + 363.0, + 364.0, + 365.0, + 366.0, + 367.0, + 368.0, + 369.0, + 370.0, + 371.0, + 372.0, + 373.0, + 374.0, + 375.0, + 376.0, + 377.0, + 378.0, + 379.0, + 380.0, + 381.0, + 382.0, + 383.0, + 384.0, + 385.0, + 386.0, + 387.0, + 388.0, + 389.0, + 390.0, + 391.0, + 392.0, + 393.0, + 394.0, + 395.0, + 396.0, + 397.0, + 398.0, + 399.0, + 400.0, + 401.0, + 402.0, + 403.0, + 404.0, + 405.0, + 406.0, + 407.0, + 408.0, + 409.0, + 410.0, + 411.0, + 412.0, + 413.0, + 414.0, + 415.0, + 416.0, + 417.0, + 418.0, + 419.0, + 420.0, + 421.0, + 422.0, + 423.0, + 424.0, + 425.0, + 426.0, + 427.0, + 428.0, + 429.0, + 430.0, + 431.0, + 432.0, + 433.0, + 434.0, + 435.0, + 436.0, + 437.0, + 438.0, + 439.0, + 440.0, + 441.0, + 442.0, + 443.0, + 444.0, + 445.0, + 446.0, + 447.0, + 448.0, + 449.0, + 450.0, + 451.0, + 452.0, + 453.0, + 454.0, + 455.0, + 456.0, + 457.0, + 458.0, + 459.0, + 460.0, + 461.0, + 462.0, + 463.0, + 464.0, + 465.0, + 466.0, + 467.0, + 468.0, + 469.0, + 470.0, + 471.0, + 472.0, + 473.0, + 474.0, + 475.0, + 476.0, + 477.0, + 478.0, + 479.0, + 480.0, + 481.0, + 482.0, + 483.0, + 484.0, + 485.0, + 486.0, + 487.0, + 488.0, + 489.0, + 490.0, + 491.0, + 492.0, + 493.0, + 494.0, + 495.0, + 496.0, + 497.0, + 498.0, + 499.0, + 500.0 +]; +var Q = [ + 1.0, + 2.0, + 3.0, + 4.0, + 5.0, + 6.0, + 7.0, + 8.0, + 9.0, + 10.0, + 11.0, + 12.0, + 13.0, + 14.0, + 15.0, + 16.0, + 17.0, + 18.0, + 19.0, + 20.0, + 21.0, + 22.0, + 23.0, + 24.0, + 25.0, + 26.0, + 27.0, + 28.0, + 29.0, + 30.0, + 31.0, + 32.0, + 33.0, + 34.0, + 35.0, + 36.0, + 37.0, + 38.0, + 39.0, + 40.0, + 41.0, + 42.0, + 43.0, + 44.0, + 45.0, + 46.0, + 47.0, + 48.0, + 49.0, + 50.0, + 51.0, + 52.0, + 53.0, + 54.0, + 55.0, + 56.0, + 57.0, + 58.0, + 59.0, + 60.0, + 61.0, + 62.0, + 63.0, + 64.0, + 65.0, + 66.0, + 67.0, + 68.0, + 69.0, + 70.0, + 71.0, + 72.0, + 73.0, + 74.0, + 75.0, + 76.0, + 77.0, + 78.0, + 79.0, + 80.0, + 81.0, + 82.0, + 83.0, + 84.0, + 85.0, + 86.0, + 87.0, + 88.0, + 89.0, + 90.0, + 91.0, + 92.0, + 93.0, + 94.0, + 95.0, + 96.0, + 97.0, + 98.0, + 99.0, + 100.0, + 101.0, + 102.0, + 103.0, + 104.0, + 105.0, + 106.0, + 107.0, + 108.0, + 109.0, + 110.0, + 111.0, + 112.0, + 113.0, + 114.0, + 115.0, + 116.0, + 117.0, + 118.0, + 119.0, + 120.0, + 121.0, + 122.0, + 123.0, + 124.0, + 125.0, + 126.0, + 127.0, + 128.0, + 129.0, + 130.0, + 131.0, + 132.0, + 133.0, + 134.0, + 135.0, + 136.0, + 137.0, + 138.0, + 139.0, + 140.0, + 141.0, + 142.0, + 143.0, + 144.0, + 145.0, + 146.0, + 147.0, + 148.0, + 149.0, + 150.0, + 151.0, + 152.0, + 153.0, + 154.0, + 155.0, + 156.0, + 157.0, + 158.0, + 159.0, + 160.0, + 161.0, + 162.0, + 163.0, + 164.0, + 165.0, + 166.0, + 167.0, + 168.0, + 169.0, + 170.0, + 171.0, + 172.0, + 173.0, + 174.0, + 175.0, + 176.0, + 177.0, + 178.0, + 179.0, + 180.0, + 181.0, + 182.0, + 183.0, + 184.0, + 185.0, + 186.0, + 187.0, + 188.0, + 189.0, + 190.0, + 191.0, + 192.0, + 193.0, + 194.0, + 195.0, + 196.0, + 197.0, + 198.0, + 199.0, + 200.0, + 201.0, + 202.0, + 203.0, + 204.0, + 205.0, + 206.0, + 207.0, + 208.0, + 209.0, + 210.0, + 211.0, + 212.0, + 213.0, + 214.0, + 215.0, + 216.0, + 217.0, + 218.0, + 219.0, + 220.0, + 221.0, + 222.0, + 223.0, + 224.0, + 225.0, + 226.0, + 227.0, + 228.0, + 229.0, + 230.0, + 231.0, + 232.0, + 233.0, + 234.0, + 235.0, + 236.0, + 237.0, + 238.0, + 239.0, + 240.0, + 241.0, + 242.0, + 243.0, + 244.0, + 245.0, + 246.0, + 247.0, + 248.0, + 249.0, + 250.0, + 251.0, + 252.0, + 253.0, + 254.0, + 255.0, + 256.0, + 257.0, + 258.0, + 259.0, + 260.0, + 261.0, + 262.0, + 263.0, + 264.0, + 265.0, + 266.0, + 267.0, + 268.0, + 269.0, + 270.0, + 271.0, + 272.0, + 273.0, + 274.0, + 275.0, + 276.0, + 277.0, + 278.0, + 279.0, + 280.0, + 281.0, + 282.0, + 283.0, + 284.0, + 285.0, + 286.0, + 287.0, + 288.0, + 289.0, + 290.0, + 291.0, + 292.0, + 293.0, + 294.0, + 295.0, + 296.0, + 297.0, + 298.0, + 299.0, + 300.0, + 301.0, + 302.0, + 303.0, + 304.0, + 305.0, + 306.0, + 307.0, + 308.0, + 309.0, + 310.0, + 311.0, + 312.0, + 313.0, + 314.0, + 315.0, + 316.0, + 317.0, + 318.0, + 319.0, + 320.0, + 321.0, + 322.0, + 323.0, + 324.0, + 325.0, + 326.0, + 327.0, + 328.0, + 329.0, + 330.0, + 331.0, + 332.0, + 333.0, + 334.0, + 335.0, + 336.0, + 337.0, + 338.0, + 339.0, + 340.0, + 341.0, + 342.0, + 343.0, + 344.0, + 345.0, + 346.0, + 347.0, + 348.0, + 349.0, + 350.0, + 351.0, + 352.0, + 353.0, + 354.0, + 355.0, + 356.0, + 357.0, + 358.0, + 359.0, + 360.0, + 361.0, + 362.0, + 363.0, + 364.0, + 365.0, + 366.0, + 367.0, + 368.0, + 369.0, + 370.0, + 371.0, + 372.0, + 373.0, + 374.0, + 375.0, + 376.0, + 377.0, + 378.0, + 379.0, + 380.0, + 381.0, + 382.0, + 383.0, + 384.0, + 385.0, + 386.0, + 387.0, + 388.0, + 389.0, + 390.0, + 391.0, + 392.0, + 393.0, + 394.0, + 395.0, + 396.0, + 397.0, + 398.0, + 399.0, + 400.0, + 401.0, + 402.0, + 403.0, + 404.0, + 405.0, + 406.0, + 407.0, + 408.0, + 409.0, + 410.0, + 411.0, + 412.0, + 413.0, + 414.0, + 415.0, + 416.0, + 417.0, + 418.0, + 419.0, + 420.0, + 421.0, + 422.0, + 423.0, + 424.0, + 425.0, + 426.0, + 427.0, + 428.0, + 429.0, + 430.0, + 431.0, + 432.0, + 433.0, + 434.0, + 435.0, + 436.0, + 437.0, + 438.0, + 439.0, + 440.0, + 441.0, + 442.0, + 443.0, + 444.0, + 445.0, + 446.0, + 447.0, + 448.0, + 449.0, + 450.0, + 451.0, + 452.0, + 453.0, + 454.0, + 455.0, + 456.0, + 457.0, + 458.0, + 459.0, + 460.0, + 461.0, + 462.0, + 463.0, + 464.0, + 465.0, + 466.0, + 467.0, + 468.0, + 469.0, + 470.0, + 471.0, + 472.0, + 473.0, + 474.0, + 475.0, + 476.0, + 477.0, + 478.0, + 479.0, + 480.0, + 481.0, + 482.0, + 483.0, + 484.0, + 485.0, + 486.0, + 487.0, + 488.0, + 489.0, + 490.0, + 491.0, + 492.0, + 493.0, + 494.0, + 495.0, + 496.0, + 497.0, + 498.0, + 499.0, + 500.0, + 501.0 +]; +var END = P.length - 1; + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var s1; + var s2; + var i; + + if ( x === 0.0 ) { + return 0.0; + } + if ( abs( x ) <= 1.0 ) { + s1 = P[ END ]; + s2 = Q[ END ]; + for ( i = END-1; i >= 0; i-- ) { + s1 = float64ToFloat32( s1 * x ); + s2 = float64ToFloat32( s2 * x ); + s1 = float64ToFloat32( s1 + P[ i ] ); + s2 = float64ToFloat32( s2 + Q[ i ] ); + } + } else { + x = float64ToFloat32( 1.0 / x ); // use inverse to avoid overflow + s1 = P[ 0 ]; + s2 = Q[ 0 ]; + for ( i = 1; i <= END; i++ ) { + s1 = float64ToFloat32( s1 * x ); + s2 = float64ToFloat32( s2 * x ); + s1 = float64ToFloat32( s1 + P[ i ] ); + s2 = float64ToFloat32( s2 + Q[ i ] ); + } + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/fixtures/loop2.float32.js.txt b/base/tools/evalrational-compile/test/fixtures/loop2.float32.js.txt new file mode 100644 index 000000000..8fb272c41 --- /dev/null +++ b/base/tools/evalrational-compile/test/fixtures/loop2.float32.js.txt @@ -0,0 +1,1070 @@ +'use strict'; + +// MODULES // + +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); +var abs = require( '@stdlib/math/base/special/abs' ); + + +// VARIABLES // + +var P = [ + 0.5, + 1.5, + 2.5, + 3.5, + 4.5, + 5.5, + 6.5, + 7.5, + 8.5, + 9.5, + 10.5, + 11.5, + 12.5, + 13.5, + 14.5, + 15.5, + 16.5, + 17.5, + 18.5, + 19.5, + 20.5, + 21.5, + 22.5, + 23.5, + 24.5, + 25.5, + 26.5, + 27.5, + 28.5, + 29.5, + 30.5, + 31.5, + 32.5, + 33.5, + 34.5, + 35.5, + 36.5, + 37.5, + 38.5, + 39.5, + 40.5, + 41.5, + 42.5, + 43.5, + 44.5, + 45.5, + 46.5, + 47.5, + 48.5, + 49.5, + 50.5, + 51.5, + 52.5, + 53.5, + 54.5, + 55.5, + 56.5, + 57.5, + 58.5, + 59.5, + 60.5, + 61.5, + 62.5, + 63.5, + 64.5, + 65.5, + 66.5, + 67.5, + 68.5, + 69.5, + 70.5, + 71.5, + 72.5, + 73.5, + 74.5, + 75.5, + 76.5, + 77.5, + 78.5, + 79.5, + 80.5, + 81.5, + 82.5, + 83.5, + 84.5, + 85.5, + 86.5, + 87.5, + 88.5, + 89.5, + 90.5, + 91.5, + 92.5, + 93.5, + 94.5, + 95.5, + 96.5, + 97.5, + 98.5, + 99.5, + 100.5, + 101.5, + 102.5, + 103.5, + 104.5, + 105.5, + 106.5, + 107.5, + 108.5, + 109.5, + 110.5, + 111.5, + 112.5, + 113.5, + 114.5, + 115.5, + 116.5, + 117.5, + 118.5, + 119.5, + 120.5, + 121.5, + 122.5, + 123.5, + 124.5, + 125.5, + 126.5, + 127.5, + 128.5, + 129.5, + 130.5, + 131.5, + 132.5, + 133.5, + 134.5, + 135.5, + 136.5, + 137.5, + 138.5, + 139.5, + 140.5, + 141.5, + 142.5, + 143.5, + 144.5, + 145.5, + 146.5, + 147.5, + 148.5, + 149.5, + 150.5, + 151.5, + 152.5, + 153.5, + 154.5, + 155.5, + 156.5, + 157.5, + 158.5, + 159.5, + 160.5, + 161.5, + 162.5, + 163.5, + 164.5, + 165.5, + 166.5, + 167.5, + 168.5, + 169.5, + 170.5, + 171.5, + 172.5, + 173.5, + 174.5, + 175.5, + 176.5, + 177.5, + 178.5, + 179.5, + 180.5, + 181.5, + 182.5, + 183.5, + 184.5, + 185.5, + 186.5, + 187.5, + 188.5, + 189.5, + 190.5, + 191.5, + 192.5, + 193.5, + 194.5, + 195.5, + 196.5, + 197.5, + 198.5, + 199.5, + 200.5, + 201.5, + 202.5, + 203.5, + 204.5, + 205.5, + 206.5, + 207.5, + 208.5, + 209.5, + 210.5, + 211.5, + 212.5, + 213.5, + 214.5, + 215.5, + 216.5, + 217.5, + 218.5, + 219.5, + 220.5, + 221.5, + 222.5, + 223.5, + 224.5, + 225.5, + 226.5, + 227.5, + 228.5, + 229.5, + 230.5, + 231.5, + 232.5, + 233.5, + 234.5, + 235.5, + 236.5, + 237.5, + 238.5, + 239.5, + 240.5, + 241.5, + 242.5, + 243.5, + 244.5, + 245.5, + 246.5, + 247.5, + 248.5, + 249.5, + 250.5, + 251.5, + 252.5, + 253.5, + 254.5, + 255.5, + 256.5, + 257.5, + 258.5, + 259.5, + 260.5, + 261.5, + 262.5, + 263.5, + 264.5, + 265.5, + 266.5, + 267.5, + 268.5, + 269.5, + 270.5, + 271.5, + 272.5, + 273.5, + 274.5, + 275.5, + 276.5, + 277.5, + 278.5, + 279.5, + 280.5, + 281.5, + 282.5, + 283.5, + 284.5, + 285.5, + 286.5, + 287.5, + 288.5, + 289.5, + 290.5, + 291.5, + 292.5, + 293.5, + 294.5, + 295.5, + 296.5, + 297.5, + 298.5, + 299.5, + 300.5, + 301.5, + 302.5, + 303.5, + 304.5, + 305.5, + 306.5, + 307.5, + 308.5, + 309.5, + 310.5, + 311.5, + 312.5, + 313.5, + 314.5, + 315.5, + 316.5, + 317.5, + 318.5, + 319.5, + 320.5, + 321.5, + 322.5, + 323.5, + 324.5, + 325.5, + 326.5, + 327.5, + 328.5, + 329.5, + 330.5, + 331.5, + 332.5, + 333.5, + 334.5, + 335.5, + 336.5, + 337.5, + 338.5, + 339.5, + 340.5, + 341.5, + 342.5, + 343.5, + 344.5, + 345.5, + 346.5, + 347.5, + 348.5, + 349.5, + 350.5, + 351.5, + 352.5, + 353.5, + 354.5, + 355.5, + 356.5, + 357.5, + 358.5, + 359.5, + 360.5, + 361.5, + 362.5, + 363.5, + 364.5, + 365.5, + 366.5, + 367.5, + 368.5, + 369.5, + 370.5, + 371.5, + 372.5, + 373.5, + 374.5, + 375.5, + 376.5, + 377.5, + 378.5, + 379.5, + 380.5, + 381.5, + 382.5, + 383.5, + 384.5, + 385.5, + 386.5, + 387.5, + 388.5, + 389.5, + 390.5, + 391.5, + 392.5, + 393.5, + 394.5, + 395.5, + 396.5, + 397.5, + 398.5, + 399.5, + 400.5, + 401.5, + 402.5, + 403.5, + 404.5, + 405.5, + 406.5, + 407.5, + 408.5, + 409.5, + 410.5, + 411.5, + 412.5, + 413.5, + 414.5, + 415.5, + 416.5, + 417.5, + 418.5, + 419.5, + 420.5, + 421.5, + 422.5, + 423.5, + 424.5, + 425.5, + 426.5, + 427.5, + 428.5, + 429.5, + 430.5, + 431.5, + 432.5, + 433.5, + 434.5, + 435.5, + 436.5, + 437.5, + 438.5, + 439.5, + 440.5, + 441.5, + 442.5, + 443.5, + 444.5, + 445.5, + 446.5, + 447.5, + 448.5, + 449.5, + 450.5, + 451.5, + 452.5, + 453.5, + 454.5, + 455.5, + 456.5, + 457.5, + 458.5, + 459.5, + 460.5, + 461.5, + 462.5, + 463.5, + 464.5, + 465.5, + 466.5, + 467.5, + 468.5, + 469.5, + 470.5, + 471.5, + 472.5, + 473.5, + 474.5, + 475.5, + 476.5, + 477.5, + 478.5, + 479.5, + 480.5, + 481.5, + 482.5, + 483.5, + 484.5, + 485.5, + 486.5, + 487.5, + 488.5, + 489.5, + 490.5, + 491.5, + 492.5, + 493.5, + 494.5, + 495.5, + 496.5, + 497.5, + 498.5, + 499.5, + 500.5 +]; +var Q = [ + 1.5, + 2.5, + 3.5, + 4.5, + 5.5, + 6.5, + 7.5, + 8.5, + 9.5, + 10.5, + 11.5, + 12.5, + 13.5, + 14.5, + 15.5, + 16.5, + 17.5, + 18.5, + 19.5, + 20.5, + 21.5, + 22.5, + 23.5, + 24.5, + 25.5, + 26.5, + 27.5, + 28.5, + 29.5, + 30.5, + 31.5, + 32.5, + 33.5, + 34.5, + 35.5, + 36.5, + 37.5, + 38.5, + 39.5, + 40.5, + 41.5, + 42.5, + 43.5, + 44.5, + 45.5, + 46.5, + 47.5, + 48.5, + 49.5, + 50.5, + 51.5, + 52.5, + 53.5, + 54.5, + 55.5, + 56.5, + 57.5, + 58.5, + 59.5, + 60.5, + 61.5, + 62.5, + 63.5, + 64.5, + 65.5, + 66.5, + 67.5, + 68.5, + 69.5, + 70.5, + 71.5, + 72.5, + 73.5, + 74.5, + 75.5, + 76.5, + 77.5, + 78.5, + 79.5, + 80.5, + 81.5, + 82.5, + 83.5, + 84.5, + 85.5, + 86.5, + 87.5, + 88.5, + 89.5, + 90.5, + 91.5, + 92.5, + 93.5, + 94.5, + 95.5, + 96.5, + 97.5, + 98.5, + 99.5, + 100.5, + 101.5, + 102.5, + 103.5, + 104.5, + 105.5, + 106.5, + 107.5, + 108.5, + 109.5, + 110.5, + 111.5, + 112.5, + 113.5, + 114.5, + 115.5, + 116.5, + 117.5, + 118.5, + 119.5, + 120.5, + 121.5, + 122.5, + 123.5, + 124.5, + 125.5, + 126.5, + 127.5, + 128.5, + 129.5, + 130.5, + 131.5, + 132.5, + 133.5, + 134.5, + 135.5, + 136.5, + 137.5, + 138.5, + 139.5, + 140.5, + 141.5, + 142.5, + 143.5, + 144.5, + 145.5, + 146.5, + 147.5, + 148.5, + 149.5, + 150.5, + 151.5, + 152.5, + 153.5, + 154.5, + 155.5, + 156.5, + 157.5, + 158.5, + 159.5, + 160.5, + 161.5, + 162.5, + 163.5, + 164.5, + 165.5, + 166.5, + 167.5, + 168.5, + 169.5, + 170.5, + 171.5, + 172.5, + 173.5, + 174.5, + 175.5, + 176.5, + 177.5, + 178.5, + 179.5, + 180.5, + 181.5, + 182.5, + 183.5, + 184.5, + 185.5, + 186.5, + 187.5, + 188.5, + 189.5, + 190.5, + 191.5, + 192.5, + 193.5, + 194.5, + 195.5, + 196.5, + 197.5, + 198.5, + 199.5, + 200.5, + 201.5, + 202.5, + 203.5, + 204.5, + 205.5, + 206.5, + 207.5, + 208.5, + 209.5, + 210.5, + 211.5, + 212.5, + 213.5, + 214.5, + 215.5, + 216.5, + 217.5, + 218.5, + 219.5, + 220.5, + 221.5, + 222.5, + 223.5, + 224.5, + 225.5, + 226.5, + 227.5, + 228.5, + 229.5, + 230.5, + 231.5, + 232.5, + 233.5, + 234.5, + 235.5, + 236.5, + 237.5, + 238.5, + 239.5, + 240.5, + 241.5, + 242.5, + 243.5, + 244.5, + 245.5, + 246.5, + 247.5, + 248.5, + 249.5, + 250.5, + 251.5, + 252.5, + 253.5, + 254.5, + 255.5, + 256.5, + 257.5, + 258.5, + 259.5, + 260.5, + 261.5, + 262.5, + 263.5, + 264.5, + 265.5, + 266.5, + 267.5, + 268.5, + 269.5, + 270.5, + 271.5, + 272.5, + 273.5, + 274.5, + 275.5, + 276.5, + 277.5, + 278.5, + 279.5, + 280.5, + 281.5, + 282.5, + 283.5, + 284.5, + 285.5, + 286.5, + 287.5, + 288.5, + 289.5, + 290.5, + 291.5, + 292.5, + 293.5, + 294.5, + 295.5, + 296.5, + 297.5, + 298.5, + 299.5, + 300.5, + 301.5, + 302.5, + 303.5, + 304.5, + 305.5, + 306.5, + 307.5, + 308.5, + 309.5, + 310.5, + 311.5, + 312.5, + 313.5, + 314.5, + 315.5, + 316.5, + 317.5, + 318.5, + 319.5, + 320.5, + 321.5, + 322.5, + 323.5, + 324.5, + 325.5, + 326.5, + 327.5, + 328.5, + 329.5, + 330.5, + 331.5, + 332.5, + 333.5, + 334.5, + 335.5, + 336.5, + 337.5, + 338.5, + 339.5, + 340.5, + 341.5, + 342.5, + 343.5, + 344.5, + 345.5, + 346.5, + 347.5, + 348.5, + 349.5, + 350.5, + 351.5, + 352.5, + 353.5, + 354.5, + 355.5, + 356.5, + 357.5, + 358.5, + 359.5, + 360.5, + 361.5, + 362.5, + 363.5, + 364.5, + 365.5, + 366.5, + 367.5, + 368.5, + 369.5, + 370.5, + 371.5, + 372.5, + 373.5, + 374.5, + 375.5, + 376.5, + 377.5, + 378.5, + 379.5, + 380.5, + 381.5, + 382.5, + 383.5, + 384.5, + 385.5, + 386.5, + 387.5, + 388.5, + 389.5, + 390.5, + 391.5, + 392.5, + 393.5, + 394.5, + 395.5, + 396.5, + 397.5, + 398.5, + 399.5, + 400.5, + 401.5, + 402.5, + 403.5, + 404.5, + 405.5, + 406.5, + 407.5, + 408.5, + 409.5, + 410.5, + 411.5, + 412.5, + 413.5, + 414.5, + 415.5, + 416.5, + 417.5, + 418.5, + 419.5, + 420.5, + 421.5, + 422.5, + 423.5, + 424.5, + 425.5, + 426.5, + 427.5, + 428.5, + 429.5, + 430.5, + 431.5, + 432.5, + 433.5, + 434.5, + 435.5, + 436.5, + 437.5, + 438.5, + 439.5, + 440.5, + 441.5, + 442.5, + 443.5, + 444.5, + 445.5, + 446.5, + 447.5, + 448.5, + 449.5, + 450.5, + 451.5, + 452.5, + 453.5, + 454.5, + 455.5, + 456.5, + 457.5, + 458.5, + 459.5, + 460.5, + 461.5, + 462.5, + 463.5, + 464.5, + 465.5, + 466.5, + 467.5, + 468.5, + 469.5, + 470.5, + 471.5, + 472.5, + 473.5, + 474.5, + 475.5, + 476.5, + 477.5, + 478.5, + 479.5, + 480.5, + 481.5, + 482.5, + 483.5, + 484.5, + 485.5, + 486.5, + 487.5, + 488.5, + 489.5, + 490.5, + 491.5, + 492.5, + 493.5, + 494.5, + 495.5, + 496.5, + 497.5, + 498.5, + 499.5, + 500.5, + 501.5 +]; +var END = P.length - 1; + + +// MAIN // + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the rational function +* @returns {number} evaluated rational function +*/ +function evalrational( x ) { + var s1; + var s2; + var i; + + if ( x === 0.0 ) { + return 0.3333333432674408; + } + if ( abs( x ) <= 1.0 ) { + s1 = P[ END ]; + s2 = Q[ END ]; + for ( i = END-1; i >= 0; i-- ) { + s1 = float64ToFloat32( s1 * x ); + s2 = float64ToFloat32( s2 * x ); + s1 = float64ToFloat32( s1 + P[ i ] ); + s2 = float64ToFloat32( s2 + Q[ i ] ); + } + } else { + x = float64ToFloat32( 1.0 / x ); // use inverse to avoid overflow + s1 = P[ 0 ]; + s2 = Q[ 0 ]; + for ( i = 1; i <= END; i++ ) { + s1 = float64ToFloat32( s1 * x ); + s2 = float64ToFloat32( s2 * x ); + s1 = float64ToFloat32( s1 + P[ i ] ); + s2 = float64ToFloat32( s2 + Q[ i ] ); + } + } + return float64ToFloat32( s1 / s2 ); +} + + +// EXPORTS // + +module.exports = evalrational; diff --git a/base/tools/evalrational-compile/test/test.js b/base/tools/evalrational-compile/test/test.js index b1cc50871..4d24707c6 100644 --- a/base/tools/evalrational-compile/test/test.js +++ b/base/tools/evalrational-compile/test/test.js @@ -16,6 +16,8 @@ * limitations under the License. */ +/* eslint-disable max-len */ + 'use strict'; // MODULES // @@ -26,6 +28,7 @@ var tape = require( 'tape' ); var IS_BROWSER = require( '@stdlib/assert/is-browser' ); var readFile = require( '@stdlib/fs/read-file' ).sync; var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); var tryRequire = require( '@stdlib/utils/try-require' ); @@ -63,6 +66,52 @@ tape( 'the function returns a string', opts, function test( t ) { t.end(); }); +tape( 'the function returns a string (dtype=float64)', opts, function test( t ) { + var options; + var str; + + options = { + 'dtype': 'float64' + }; + + str = compile( [], [], options ); + t.equal( typeof str, 'string', 'returns a string' ); + + str = compile( [ 1.0 ], [ 2.0 ], options ); + t.equal( typeof str, 'string', 'returns a string' ); + + str = compile( [ 1.0, 2.0, 3.0 ], [ 3.0, 2.0, 1.0 ], options ); + t.equal( typeof str, 'string', 'returns a string' ); + + str = compile( new Float64Array( 501 ), new Float64Array( 501 ), options ); + t.equal( typeof str, 'string', 'returns a string' ); + + t.end(); +}); + +tape( 'the function returns a string (dtype=float32)', opts, function test( t ) { + var options; + var str; + + options = { + 'dtype': 'float32' + }; + + str = compile( [], [], options ); + t.equal( typeof str, 'string', 'returns a string' ); + + str = compile( [ 1.0 ], [ 2.0 ], options ); + t.equal( typeof str, 'string', 'returns a string' ); + + str = compile( [ 1.0, 2.0, 3.0 ], [ 3.0, 2.0, 1.0 ], options ); + t.equal( typeof str, 'string', 'returns a string' ); + + str = compile( new Float32Array( 501 ), new Float32Array( 501 ), options ); + t.equal( typeof str, 'string', 'returns a string' ); + + t.end(); +}); + tape( 'if provided empty coefficient arrays, the function returns a module string containing an exported function which always returns `NaN`', opts, function test( t ) { var expected; var actual; @@ -81,6 +130,46 @@ tape( 'if provided empty coefficient arrays, the function returns a module strin t.end(); }); +tape( 'if provided empty coefficient arrays, the function returns a module string containing an exported function which always returns `NaN` (dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'nan.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [], [], { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided empty coefficient arrays, the function returns a module string containing an exported function which always returns `NaN` (dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'nan.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [], [], { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'if provided coefficient arrays having different lengths, the function returns a module string containing an exported function which always returns `NaN`', opts, function test( t ) { var expected; var actual; @@ -99,6 +188,46 @@ tape( 'if provided coefficient arrays having different lengths, the function ret t.end(); }); +tape( 'if provided coefficient arrays having different lengths, the function returns a module string containing an exported function which always returns `NaN` (dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'nan.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [ 1.0, 2.0 ], [ 1.0, 2.0, 3.0 ], { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided coefficient arrays having different lengths, the function returns a module string containing an exported function which always returns `NaN` (dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'nan.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [ 1.0, 2.0 ], [ 1.0, 2.0, 3.0 ], { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'if provided coefficient arrays each containing 1 coefficient, the function returns a module string containing an exported function which always returns the ratio of those two coefficients', opts, function test( t ) { var expected; var actual; @@ -117,6 +246,46 @@ tape( 'if provided coefficient arrays each containing 1 coefficient, the functio t.end(); }); +tape( 'if provided coefficient arrays each containing 1 coefficient, the function returns a module string containing an exported function which always returns the ratio of those two coefficients (dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'coefficient_ratio.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [ 3.14 ], [ -0.5 ], { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided coefficient arrays each containing 1 coefficient, the function returns a module string containing an exported function which always returns the ratio of those two coefficients (dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'coefficient_ratio.float32.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( new Float32Array( [ 3.14 ] ), new Float32Array( [ -0.5 ] ), { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'if provided coefficient arrays each containing 1 coefficient, the function returns a module string containing an exported function which always returns the ratio of those two coefficients (integer values)', opts, function test( t ) { var expected; var actual; @@ -129,7 +298,47 @@ tape( 'if provided coefficient arrays each containing 1 coefficient, the functio }; expected = readFile( fpath, fopts ); - actual = compile( [ -3.0 ], [ 1.5 ] ); + actual = compile( [ -3.0 ], [ 2.0 ] ); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided coefficient arrays each containing 1 coefficient, the function returns a module string containing an exported function which always returns the ratio of those two coefficients (integer values; dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'coefficient_ratio_integer.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [ -3.0 ], [ 2.0 ], { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided coefficient arrays each containing 1 coefficient, the function returns a module string containing an exported function which always returns the ratio of those two coefficients (integer values; dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'coefficient_ratio_integer.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( new Float32Array( [ -3.0 ] ), new Float32Array( [ 2.0 ] ), { + 'dtype': 'float32' + }); t.equal( actual, expected, 'returns expected value' ); t.end(); @@ -153,6 +362,46 @@ tape( 'the function returns a module string containing an exported function whic t.end(); }); +tape( 'the function returns a module string containing an exported function which evaluates a rational function (dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'evalrational1.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [ 1.0, 2.5, 3.14, -1.0 ], [ 4.0, -3.5, 2.2, 1.25 ], { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a module string containing an exported function which evaluates a rational function (dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'evalrational1.float32.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( new Float32Array( [ 1.0, 2.5, 3.14, -1.0 ] ), new Float32Array( [ 4.0, -3.5, 2.2, 1.25 ] ), { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function returns a module string containing an exported function which evaluates a rational function', opts, function test( t ) { var expected; var actual; @@ -171,6 +420,46 @@ tape( 'the function returns a module string containing an exported function whic t.end(); }); +tape( 'the function returns a module string containing an exported function which evaluates a rational function (dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'evalrational2.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( [ -3.14, 0.0 ], [ 6.0, 0.0 ], { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a module string containing an exported function which evaluates a rational function (dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + + fpath = join( __dirname, 'fixtures', 'evalrational2.float32.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + actual = compile( new Float32Array( [ -3.14, 0.0 ] ), new Float32Array( [ 6.0, 0.0 ] ), { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function returns a module string containing an exported function which evaluates a rational function', opts, function test( t ) { var expected; var actual; @@ -193,6 +482,54 @@ tape( 'the function returns a module string containing an exported function whic t.end(); }); +tape( 'the function returns a module string containing an exported function which evaluates a rational function (dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + var P; + var Q; + + fpath = join( __dirname, 'fixtures', 'evalrational3.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + P = [ -3.14, 0.0, 4.0, 2.0, 3.0, 9.0, 5.4 ]; + Q = [ 6.0, 0.0, 2.0, 1.0, 2.0, 4.8, 2.2 ]; + actual = compile( P, Q, { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a module string containing an exported function which evaluates a rational function (dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + var P; + var Q; + + fpath = join( __dirname, 'fixtures', 'evalrational3.float32.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + P = new Float32Array( [ -3.14, 0.0, 4.0, 2.0, 3.0, 9.0, 5.4 ] ); + Q = new Float32Array( [ 6.0, 0.0, 2.0, 1.0, 2.0, 4.8, 2.2 ] ); + actual = compile( P, Q, { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function returns a module string containing an exported function which evaluates a rational function (large number of coefficients; integers)', opts, function test( t ) { var expected; var actual; @@ -208,11 +545,11 @@ tape( 'the function returns a module string containing an exported function whic }; expected = readFile( fpath, fopts ); - P = new Array( 501 ); - Q = new Array( 501 ); - for ( i = 0; i < P.length; i++ ) { - P[ i ] = i; - Q[ i ] = i + 1; + P = []; + Q = []; + for ( i = 0; i < 501; i++ ) { + P.push( i ); + Q.push( i+1 ); } actual = compile( P, Q ); t.equal( actual, expected, 'returns expected value' ); @@ -220,6 +557,64 @@ tape( 'the function returns a module string containing an exported function whic t.end(); }); +tape( 'the function returns a module string containing an exported function which evaluates a rational function (large number of coefficients; integers; dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + var P; + var Q; + var i; + + fpath = join( __dirname, 'fixtures', 'loop1.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + P = []; + Q = []; + for ( i = 0; i < 501; i++ ) { + P.push( i ); + Q.push( i+1 ); + } + actual = compile( P, Q, { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a module string containing an exported function which evaluates a rational function (large number of coefficients; integers; dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + var P; + var Q; + var i; + + fpath = join( __dirname, 'fixtures', 'loop1.float32.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + P = []; + Q = []; + for ( i = 0; i < 501; i++ ) { + P.push( i ); + Q.push( i+1 ); + } + actual = compile( new Float32Array( P ), new Float32Array( Q ), { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function returns a module string containing an exported function which evaluates a rational function (large number of coefficients; decimals)', opts, function test( t ) { var expected; var actual; @@ -235,14 +630,72 @@ tape( 'the function returns a module string containing an exported function whic }; expected = readFile( fpath, fopts ); - P = new Array( 501 ); - Q = new Array( 501 ); - for ( i = 0; i < P.length; i++ ) { - P[ i ] = i + 0.1; - Q[ i ] = i + 1.1; + P = []; + Q = []; + for ( i = 0; i < 501; i++ ) { + P.push( i+0.1 ); + Q.push( i+1.1 ); } actual = compile( P, Q ); t.equal( actual, expected, 'returns expected value' ); t.end(); }); + +tape( 'the function returns a module string containing an exported function which evaluates a rational function (large number of coefficients; decimals; dtype=float64)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + var P; + var Q; + var i; + + fpath = join( __dirname, 'fixtures', 'loop2.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + P = []; + Q = []; + for ( i = 0; i < 501; i++ ) { + P.push( i+0.1 ); + Q.push( i+1.1 ); + } + actual = compile( P, Q, { + 'dtype': 'float64' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a module string containing an exported function which evaluates a rational function (large number of coefficients; decimals; dtype=float32)', opts, function test( t ) { + var expected; + var actual; + var fpath; + var fopts; + var P; + var Q; + var i; + + fpath = join( __dirname, 'fixtures', 'loop2.float32.js.txt' ); + fopts = { + 'encoding': 'utf8' + }; + expected = readFile( fpath, fopts ); + + P = []; + Q = []; + for ( i = 0; i < 501; i++ ) { + P.push( i+0.5 ); + Q.push( i+1.5 ); + } + actual = compile( new Float32Array( P ), new Float32Array( Q ), { + 'dtype': 'float32' + }); + t.equal( actual, expected, 'returns expected value' ); + + t.end(); +});