diff --git a/.gitattributes b/.gitattributes index 10a16e6..a4a9190 100644 --- a/.gitattributes +++ b/.gitattributes @@ -40,10 +40,23 @@ *.mov binary # Override what is considered "vendored" by GitHub's linguist: -/deps/** linguist-vendored=false -/lib/node_modules/** linguist-vendored=false linguist-generated=false -test/fixtures/** linguist-vendored=false -tools/** linguist-vendored=false +/lib/node_modules/** -linguist-vendored -linguist-generated -# Override what is considered "documentation" by GitHub's linguist: -examples/** linguist-documentation=false +# Configure directories which should *not* be included in GitHub language statistics: +/deps/** linguist-vendored +/workshops/** linguist-vendored + +benchmark/** linguist-vendored +docs/* linguist-documentation +etc/** linguist-vendored +examples/** linguist-documentation +scripts/** linguist-vendored +test/** linguist-vendored +tools/** linguist-vendored + +# Configure files which should *not* be included in GitHub language statistics: +Makefile linguist-vendored +*.mk linguist-vendored + +# Configure files which should be included in GitHub language statistics: +docs/types/*.d.ts -linguist-documentation diff --git a/.github/workflows/productionize.yml b/.github/workflows/productionize.yml index ec90164..f92a6c5 100644 --- a/.github/workflows/productionize.yml +++ b/.github/workflows/productionize.yml @@ -344,7 +344,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() @@ -518,7 +517,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() @@ -698,7 +696,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3eec50e..ad3a3e0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -218,7 +218,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 72d048d..cff626c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -95,6 +95,5 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() diff --git a/.github/workflows/test_bundles.yml b/.github/workflows/test_bundles.yml index 6d77abd..5b5879a 100644 --- a/.github/workflows/test_bundles.yml +++ b/.github/workflows/test_bundles.yml @@ -94,7 +94,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() @@ -139,7 +138,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() @@ -184,6 +182,5 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() diff --git a/.github/workflows/test_coverage.yml b/.github/workflows/test_coverage.yml index f4eda1e..2bcf0cd 100644 --- a/.github/workflows/test_coverage.yml +++ b/.github/workflows/test_coverage.yml @@ -119,7 +119,6 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() diff --git a/.github/workflows/test_install.yml b/.github/workflows/test_install.yml index b38f159..ed4d240 100644 --- a/.github/workflows/test_install.yml +++ b/.github/workflows/test_install.yml @@ -81,6 +81,5 @@ jobs: uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 # v3.16.2 with: status: ${{ job.status }} - steps: ${{ toJson(steps) }} channel: '#npm-ci' if: failure() diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 4500383..0570891 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -5,6 +5,7 @@ Adarsh Palaskar Aditya Sapra AgPriyanshu18 <113460573+AgPriyanshu18@users.noreply.github.com> +Aleksandr <112382387+alextes90@users.noreply.github.com> Ali Salesi Aman Bhansali Amit Jimiwal @@ -69,8 +70,10 @@ Seyyed Parsa Neshaei Shashank Shekhar Singh Shivam <11shivam00@gmail.com> Shraddheya Shendre +Shubh Mehta <93862397+Shubh942@users.noreply.github.com> Shubham Mishra Snehil Shah <130062020+Snehil-Shah@users.noreply.github.com> +Soumajit Chatterjee <121816890+soumajit23@users.noreply.github.com> Spandan Barve Stephannie Jiménez Gacha Suraj kumar <125961509+kumarsuraj212003@users.noreply.github.com> @@ -83,4 +86,5 @@ Yernar Yergaziyev naveen nishant-s7 <97207366+nishant-s7@users.noreply.github.com> orimiles5 <97595296+orimiles5@users.noreply.github.com> +rainn <88160429+AmCodesLame@users.noreply.github.com> rei2hu diff --git a/README.md b/README.md index 9568095..9bf9767 100644 --- a/README.md +++ b/README.md @@ -87,21 +87,19 @@ The function has the following parameters: - **N**: number of indexed elements. - **x**: input [`Float64Array`][@stdlib/array/float64]. -- **strideX**: index increment for `x`. +- **strideX**: index increment for the strided array. - **out**: output [`Float64Array`][@stdlib/array/float64] whose first element is the sum and whose second element is the number of non-NaN elements. - **strideOut**: index increment for `out`. -The `N` and `stride` parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in `x`, +The `N` and `stride` parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in the strided array, ```javascript var Float64Array = require( '@stdlib/array-float64' ); -var floor = require( '@stdlib/math-base-special-floor' ); var x = new Float64Array( [ 1.0, 2.0, NaN, -7.0, NaN, 3.0, 4.0, 2.0 ] ); var out = new Float64Array( 2 ); -var N = floor( x.length / 2 ); -var v = dnannsumpw( N, x, 2, out, 1 ); +var v = dnannsumpw( 4, x, 2, out, 1 ); // returns [ 5.0, 2 ] ``` @@ -111,7 +109,6 @@ Note that indexing is relative to the first index. To introduce an offset, use [ ```javascript var Float64Array = require( '@stdlib/array-float64' ); -var floor = require( '@stdlib/math-base-special-floor' ); var x0 = new Float64Array( [ 2.0, 1.0, NaN, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); var x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element @@ -119,9 +116,7 @@ var x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd var out0 = new Float64Array( 4 ); var out1 = new Float64Array( out0.buffer, out0.BYTES_PER_ELEMENT*2 ); // start at 3rd element -var N = floor( x0.length / 2 ); - -var v = dnannsumpw( N, x1, 2, out1, 1 ); +var v = dnannsumpw( 4, x1, 2, out1, 1 ); // returns [ 5.0, 4 ] ``` @@ -141,20 +136,18 @@ var v = dnannsumpw.ndarray( x.length, x, 1, 0, out, 1, 0 ); The function has the following additional parameters: -- **offsetX**: starting index for `x`. +- **offsetX**: starting index for the strided array. - **offsetOut**: starting index for `out`. -While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to calculate the sum of every other value in `x` starting from the second value +While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to calculate the sum of every other value in the strided array starting from the second value ```javascript var Float64Array = require( '@stdlib/array-float64' ); -var floor = require( '@stdlib/math-base-special-floor' ); var x = new Float64Array( [ 2.0, 1.0, NaN, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); var out = new Float64Array( 4 ); -var N = floor( x.length / 2 ); -var v = dnannsumpw.ndarray( N, x, 2, 1, out, 2, 1 ); +var v = dnannsumpw.ndarray( 4, x, 2, 1, out, 2, 1 ); // returns [ 0.0, 5.0, 0.0, 4 ] ``` @@ -180,22 +173,20 @@ var v = dnannsumpw.ndarray( N, x, 2, 1, out, 2, 1 ); ```javascript -var randu = require( '@stdlib/random-base-randu' ); -var round = require( '@stdlib/math-base-special-round' ); +var discreteUniform = require( '@stdlib/random-base-discrete-uniform' ); +var bernoulli = require( '@stdlib/random-base-bernoulli' ); +var filledarrayBy = require( '@stdlib/array-filled-by' ); var Float64Array = require( '@stdlib/array-float64' ); var dnannsumpw = require( '@stdlib/blas-ext-base-dnannsumpw' ); -var x; -var i; - -x = new Float64Array( 10 ); -for ( i = 0; i < x.length; i++ ) { - if ( randu() < 0.2 ) { - x[ i ] = NaN; - } else { - x[ i ] = round( randu()*100.0 ); +function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return discreteUniform( 0, 100 ); } + return NaN; } + +var x = filledarrayBy( 10, 'float64', rand ); console.log( x ); var out = new Float64Array( 2 ); diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js index 678e5b9..b82e16a 100644 --- a/benchmark/benchmark.js +++ b/benchmark/benchmark.js @@ -21,7 +21,9 @@ // MODULES // var bench = require( '@stdlib/bench-harness' ); -var randu = require( '@stdlib/random-base-randu' ); +var uniform = require( '@stdlib/random-base-uniform' ); +var bernoulli = require( '@stdlib/random-base-bernoulli' ); +var filledarrayBy = require( '@stdlib/array-filled-by' ); var isnan = require( '@stdlib/math-base-assert-is-nan' ); var pow = require( '@stdlib/math-base-special-pow' ); var Float64Array = require( '@stdlib/array-float64' ); @@ -41,19 +43,18 @@ var dnannsumpw = require( './../lib/dnannsumpw.js' ); function createBenchmark( len ) { var out; var x; - var i; - x = new Float64Array( len ); - for ( i = 0; i < len; i++ ) { - if ( randu() < 0.2 ) { - x[ i ] = NaN; - } else { - x[ i ] = ( randu()*10.0 ) - 20.0; - } - } + x = filledarrayBy( len, 'float64', rand ); out = new Float64Array( 2 ); return benchmark; + function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; + } + function benchmark( b ) { var i; diff --git a/benchmark/benchmark.native.js b/benchmark/benchmark.native.js index b788923..36fe104 100644 --- a/benchmark/benchmark.native.js +++ b/benchmark/benchmark.native.js @@ -22,7 +22,9 @@ var resolve = require( 'path' ).resolve; var bench = require( '@stdlib/bench-harness' ); -var randu = require( '@stdlib/random-base-randu' ); +var uniform = require( '@stdlib/random-base-uniform' ); +var bernoulli = require( '@stdlib/random-base-bernoulli' ); +var filledarrayBy = require( '@stdlib/array-filled-by' ); var isnan = require( '@stdlib/math-base-assert-is-nan' ); var pow = require( '@stdlib/math-base-special-pow' ); var Float64Array = require( '@stdlib/array-float64' ); @@ -50,19 +52,18 @@ var opts = { function createBenchmark( len ) { var out; var x; - var i; - x = new Float64Array( len ); - for ( i = 0; i < len; i++ ) { - if ( randu() < 0.2 ) { - x[ i ] = NaN; - } else { - x[ i ] = ( randu()*10.0 ) - 20.0; - } - } + x = filledarrayBy( len, 'float64', rand ); out = new Float64Array( 2 ); return benchmark; + function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; + } + function benchmark( b ) { var i; diff --git a/benchmark/benchmark.ndarray.js b/benchmark/benchmark.ndarray.js index 93aa40d..d086288 100644 --- a/benchmark/benchmark.ndarray.js +++ b/benchmark/benchmark.ndarray.js @@ -21,7 +21,9 @@ // MODULES // var bench = require( '@stdlib/bench-harness' ); -var randu = require( '@stdlib/random-base-randu' ); +var uniform = require( '@stdlib/random-base-uniform' ); +var bernoulli = require( '@stdlib/random-base-bernoulli' ); +var filledarrayBy = require( '@stdlib/array-filled-by' ); var isnan = require( '@stdlib/math-base-assert-is-nan' ); var pow = require( '@stdlib/math-base-special-pow' ); var Float64Array = require( '@stdlib/array-float64' ); @@ -41,19 +43,18 @@ var dnannsumpw = require( './../lib/ndarray.js' ); function createBenchmark( len ) { var out; var x; - var i; - x = new Float64Array( len ); - for ( i = 0; i < len; i++ ) { - if ( randu() < 0.2 ) { - x[ i ] = NaN; - } else { - x[ i ] = ( randu()*10.0 ) - 20.0; - } - } + x = filledarrayBy( len, 'float64', rand ); out = new Float64Array( 2 ); return benchmark; + function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; + } + function benchmark( b ) { var i; diff --git a/benchmark/benchmark.ndarray.native.js b/benchmark/benchmark.ndarray.native.js index 3550d5e..95abcbd 100644 --- a/benchmark/benchmark.ndarray.native.js +++ b/benchmark/benchmark.ndarray.native.js @@ -22,7 +22,9 @@ var resolve = require( 'path' ).resolve; var bench = require( '@stdlib/bench-harness' ); -var randu = require( '@stdlib/random-base-randu' ); +var uniform = require( '@stdlib/random-base-uniform' ); +var bernoulli = require( '@stdlib/random-base-bernoulli' ); +var filledarrayBy = require( '@stdlib/array-filled-by' ); var isnan = require( '@stdlib/math-base-assert-is-nan' ); var pow = require( '@stdlib/math-base-special-pow' ); var Float64Array = require( '@stdlib/array-float64' ); @@ -50,19 +52,18 @@ var opts = { function createBenchmark( len ) { var out; var x; - var i; - x = new Float64Array( len ); - for ( i = 0; i < len; i++ ) { - if ( randu() < 0.2 ) { - x[ i ] = NaN; - } else { - x[ i ] = ( randu()*10.0 ) - 20.0; - } - } + x = filledarrayBy( len, 'float64', rand ); out = new Float64Array( 2 ); return benchmark; + function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; + } + function benchmark( b ) { var i; diff --git a/dist/index.js.map b/dist/index.js.map index 02ea95b..f6353f8 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../lib/sumpw.js", "../lib/dnannsumpw.js", "../lib/ndarray.js", "../lib/main.js", "../lib/index.js"], - "sourcesContent": ["/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar isnan = require( '@stdlib/math-base-assert-is-nan' );\nvar floor = require( '@stdlib/math-base-special-floor' );\n\n\n// VARIABLES //\n\n// Blocksize for pairwise summation (NOTE: decreasing the blocksize decreases rounding error as more pairs are summed, but also decreases performance. Because the inner loop is unrolled eight times, the blocksize is effectively `16`.):\nvar BLOCKSIZE = 128;\n\n\n// MAIN //\n\n/**\n* Computes the sum of a double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* ## Method\n*\n* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.\n*\n* ## References\n*\n* - Higham, Nicholas J. 1993. \"The Accuracy of Floating Point Summation.\" _SIAM Journal on Scientific Computing_ 14 (4): 783\u201399. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).\n*\n* @private\n* @param {PositiveInteger} N - number of indexed elements\n* @param {Float64Array} x - input array\n* @param {integer} strideX - `x` stride length\n* @param {NonNegativeInteger} offsetX - `x` starting index\n* @param {Float64Array} out - two-element output array whose first element is the accumulated sum and whose second element is the accumulated number of summed values\n* @param {integer} strideOut - `out` stride length\n* @param {NonNegativeInteger} offsetOut - `out` starting index\n* @returns {Float64Array} output array\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var floor = require( '@stdlib/math-base-special-floor' );\n*\n* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );\n* var N = floor( x.length / 2 );\n*\n* var out = new Float64Array( [ 0.0, 0 ] );\n* var v = sumpw( N, x, 2, 1, out, 1, 0 );\n* // returns [ 5.0, 4 ]\n*/\nfunction sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) {\n\tvar ix;\n\tvar io;\n\tvar s0;\n\tvar s1;\n\tvar s2;\n\tvar s3;\n\tvar s4;\n\tvar s5;\n\tvar s6;\n\tvar s7;\n\tvar M;\n\tvar s;\n\tvar n;\n\tvar v;\n\tvar i;\n\n\tif ( N <= 0 ) {\n\t\treturn out;\n\t}\n\tix = offsetX;\n\tio = offsetOut;\n\tif ( N === 1 || strideX === 0 ) {\n\t\tif ( isnan( x[ ix ] ) ) {\n\t\t\treturn out;\n\t\t}\n\t\tout[ io ] += x[ ix ];\n\t\tout[ io+strideOut ] += 1;\n\t\treturn out;\n\t}\n\tif ( N < 8 ) {\n\t\t// Use simple summation...\n\t\ts = 0.0;\n\t\tn = 0;\n\t\tfor ( i = 0; i < N; i++ ) {\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t}\n\t\tout[ io ] += s;\n\t\tout[ io+strideOut ] += n;\n\t\treturn out;\n\t}\n\tif ( N <= BLOCKSIZE ) {\n\t\t// Sum a block with 8 accumulators (by loop unrolling, we lower the effective blocksize to 16)...\n\t\ts0 = 0.0;\n\t\ts1 = 0.0;\n\t\ts2 = 0.0;\n\t\ts3 = 0.0;\n\t\ts4 = 0.0;\n\t\ts5 = 0.0;\n\t\ts6 = 0.0;\n\t\ts7 = 0.0;\n\t\tn = 0;\n\n\t\tM = N % 8;\n\t\tfor ( i = 0; i < N-M; i += 8 ) {\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts0 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts1 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts2 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts3 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts4 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts5 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts6 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts7 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t}\n\t\t// Pairwise sum the accumulators:\n\t\ts = ((s0+s1) + (s2+s3)) + ((s4+s5) + (s6+s7));\n\n\t\t// Clean-up loop...\n\t\tfor ( i; i < N; i++ ) {\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t}\n\t\tout[ io ] += s;\n\t\tout[ io+strideOut ] += n;\n\t\treturn out;\n\t}\n\t// Recurse by dividing by two, but avoiding non-multiples of unroll factor...\n\tn = floor( N/2 );\n\tn -= n % 8;\n\tsumpw( n, x, strideX, ix, out, strideOut, offsetOut );\n\tsumpw( N-n, x, strideX, ix+(n*strideX), out, strideOut, offsetOut );\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = sumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar sumpw = require( './sumpw.js' );\n\n\n// MAIN //\n\n/**\n* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* ## Method\n*\n* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.\n*\n* ## References\n*\n* - Higham, Nicholas J. 1993. \"The Accuracy of Floating Point Summation.\" _SIAM Journal on Scientific Computing_ 14 (4): 783\u201399. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).\n*\n* @param {PositiveInteger} N - number of indexed elements\n* @param {Float64Array} x - input array\n* @param {integer} strideX - `x` stride length\n* @param {Float64Array} out - output array\n* @param {integer} strideOut - `out` stride length\n* @returns {Float64Array} output array\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n*\n* var x = new Float64Array( [ 1.0, -2.0, NaN, 2.0 ] );\n* var out = new Float64Array( 2 );\n*\n* var v = dnannsumpw( x.length, x, 1, out, 1 );\n* // returns [ 1.0, 3 ]\n*/\nfunction dnannsumpw( N, x, strideX, out, strideOut ) {\n\tvar ix;\n\tvar io;\n\tif ( strideX < 0 ) {\n\t\tix = (1-N) * strideX;\n\t} else {\n\t\tix = 0;\n\t}\n\tif ( strideOut < 0 ) {\n\t\tio = -strideOut;\n\t} else {\n\t\tio = 0;\n\t}\n\tout[ io ] = 0.0;\n\tout[ io+strideOut ] = 0;\n\tsumpw( N, x, strideX, ix, out, strideOut, io );\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar sumpw = require( './sumpw.js' );\n\n\n// MAIN //\n\n/**\n* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* ## Method\n*\n* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.\n*\n* ## References\n*\n* - Higham, Nicholas J. 1993. \"The Accuracy of Floating Point Summation.\" _SIAM Journal on Scientific Computing_ 14 (4): 783\u201399. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).\n*\n* @param {PositiveInteger} N - number of indexed elements\n* @param {Float64Array} x - input array\n* @param {integer} strideX - `x` stride length\n* @param {NonNegativeInteger} offsetX - `x` starting index\n* @param {Float64Array} out - output array\n* @param {integer} strideOut - `out` stride length\n* @param {NonNegativeInteger} offsetOut - `out` starting index\n* @returns {Float64Array} output array\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var floor = require( '@stdlib/math-base-special-floor' );\n*\n* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );\n* var out = new Float64Array( 2 );\n*\n* var N = floor( x.length / 2 );\n*\n* var v = dnannsumpw( N, x, 2, 1, out, 1, 0 );\n* // returns [ 5.0, 4 ]\n*/\nfunction dnannsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) {\n\tout[ offsetOut ] = 0.0;\n\tout[ offsetOut+strideOut ] = 0;\n\tsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut );\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar setReadOnly = require( '@stdlib/utils-define-nonenumerable-read-only-property' );\nvar dnannsumpw = require( './dnannsumpw.js' );\nvar ndarray = require( './ndarray.js' );\n\n\n// MAIN //\n\nsetReadOnly( dnannsumpw, 'ndarray', ndarray );\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n/**\n* Compute the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* @module @stdlib/blas-ext-base-dnannsumpw\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var dnannsumpw = require( '@stdlib/blas-ext-base-dnannsumpw' );\n*\n* var x = new Float64Array( [ 1.0, -2.0, NaN, 2.0 ] );\n* var out = new Float64Array( 2 );\n*\n* var v = dnannsumpw( x.length, x, 1, out, 1 );\n* // returns [ 1.0, 3 ]\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var floor = require( '@stdlib/math-base-special-floor' );\n* var dnannsumpw = require( '@stdlib/blas-ext-base-dnannsumpw' );\n*\n* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );\n* var out = new Float64Array( 2 );\n*\n* var N = floor( x.length / 2 );\n*\n* var v = dnannsumpw.ndarray( N, x, 2, 1, out, 1, 0 );\n* // returns [ 5.0, 4 ]\n*/\n\n// MODULES //\n\nvar join = require( 'path' ).join;\nvar tryRequire = require( '@stdlib/utils-try-require' );\nvar isError = require( '@stdlib/assert-is-error' );\nvar main = require( './main.js' );\n\n\n// MAIN //\n\nvar dnannsumpw;\nvar tmp = tryRequire( join( __dirname, './native.js' ) );\nif ( isError( tmp ) ) {\n\tdnannsumpw = main;\n} else {\n\tdnannsumpw = tmp;\n}\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n\n// exports: { \"ndarray\": \"dnannsumpw.ndarray\" }\n"], - "mappings": "uGAAA,IAAAA,EAAAC,EAAA,SAAAC,EAAAC,EAAA,cAsBA,IAAIC,EAAQ,QAAS,iCAAkC,EACnDC,EAAQ,QAAS,iCAAkC,EAMnDC,EAAY,IAqChB,SAASC,EAAOC,EAAGC,EAAGC,EAASC,EAASC,EAAKC,EAAWC,EAAY,CACnE,IAAIC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACA,EACAC,EACAC,EACAC,EACAC,EAEJ,GAAKpB,GAAK,EACT,OAAOI,EAIR,GAFAG,EAAKJ,EACLK,EAAKF,EACAN,IAAM,GAAKE,IAAY,EAC3B,OAAKN,EAAOK,EAAGM,CAAG,CAAE,IAGpBH,EAAKI,CAAG,GAAKP,EAAGM,CAAG,EACnBH,EAAKI,EAAGH,CAAU,GAAK,GAChBD,EAER,GAAKJ,EAAI,EAAI,CAIZ,IAFAiB,EAAI,EACJC,EAAI,EACEE,EAAI,EAAGA,EAAIpB,EAAGoB,IACnBD,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVF,GAAKE,EACLD,GAAK,GAENX,GAAML,EAEP,OAAAE,EAAKI,CAAG,GAAKS,EACbb,EAAKI,EAAGH,CAAU,GAAKa,EAChBd,CACR,CACA,GAAKJ,GAAKF,EAAY,CAarB,IAXAW,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EACLE,EAAI,EAEJ,EAAIlB,EAAI,EACFoB,EAAI,EAAGA,EAAIpB,EAAE,EAAGoB,GAAK,EAC1BD,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVV,GAAMU,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVT,GAAMS,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVR,GAAMQ,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVP,GAAMO,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVN,GAAMM,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVL,GAAMK,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVJ,GAAMI,EACND,GAAK,GAENX,GAAML,EACNiB,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVH,GAAMG,EACND,GAAK,GAENX,GAAML,EAMP,IAHAe,EAAMR,EAAGC,GAAOC,EAAGC,IAASC,EAAGC,GAAOC,EAAGC,IAGnCI,EAAGA,EAAIpB,EAAGoB,IACfD,EAAIlB,EAAGM,CAAG,EACLY,IAAMA,IACVF,GAAKE,EACLD,GAAK,GAENX,GAAML,EAEP,OAAAE,EAAKI,CAAG,GAAKS,EACbb,EAAKI,EAAGH,CAAU,GAAKa,EAChBd,CACR,CAEA,OAAAc,EAAIrB,EAAOG,EAAE,CAAE,EACfkB,GAAKA,EAAI,EACTnB,EAAOmB,EAAGjB,EAAGC,EAASK,EAAIH,EAAKC,EAAWC,CAAU,EACpDP,EAAOC,EAAEkB,EAAGjB,EAAGC,EAASK,EAAIW,EAAEhB,EAAUE,EAAKC,EAAWC,CAAU,EAC3DF,CACR,CAKAT,EAAO,QAAUI,IC1MjB,IAAAsB,EAAAC,EAAA,SAAAC,EAAAC,EAAA,cAsBA,IAAIC,EAAQ,IAgCZ,SAASC,EAAYC,EAAGC,EAAGC,EAASC,EAAKC,EAAY,CACpD,IAAIC,EACAC,EACJ,OAAKJ,EAAU,EACdG,GAAM,EAAEL,GAAKE,EAEbG,EAAK,EAEDD,EAAY,EAChBE,EAAK,CAACF,EAENE,EAAK,EAENH,EAAKG,CAAG,EAAI,EACZH,EAAKG,EAAGF,CAAU,EAAI,EACtBN,EAAOE,EAAGC,EAAGC,EAASG,EAAIF,EAAKC,EAAWE,CAAG,EACtCH,CACR,CAKAN,EAAO,QAAUE,IC5EjB,IAAAQ,EAAAC,EAAA,SAAAC,EAAAC,EAAA,cAsBA,IAAIC,EAAQ,IAqCZ,SAASC,EAAYC,EAAGC,EAAGC,EAASC,EAASC,EAAKC,EAAWC,EAAY,CACxE,OAAAF,EAAKE,CAAU,EAAI,EACnBF,EAAKE,EAAUD,CAAU,EAAI,EAC7BP,EAAOE,EAAGC,EAAGC,EAASC,EAASC,EAAKC,EAAWC,CAAU,EAClDF,CACR,CAKAP,EAAO,QAAUE,ICrEjB,IAAAQ,EAAAC,EAAA,SAAAC,EAAAC,EAAA,cAsBA,IAAIC,EAAc,QAAS,uDAAwD,EAC/EC,EAAa,IACbC,EAAU,IAKdF,EAAaC,EAAY,UAAWC,CAAQ,EAK5CH,EAAO,QAAUE,ICiBjB,IAAIE,EAAO,QAAS,MAAO,EAAE,KACzBC,EAAa,QAAS,2BAA4B,EAClDC,EAAU,QAAS,yBAA0B,EAC7CC,EAAO,IAKPC,EACAC,EAAMJ,EAAYD,EAAM,UAAW,aAAc,CAAE,EAClDE,EAASG,CAAI,EACjBD,EAAaD,EAEbC,EAAaC,EAMd,OAAO,QAAUD", + "sourcesContent": ["/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar isnan = require( '@stdlib/math-base-assert-is-nan' );\nvar floor = require( '@stdlib/math-base-special-floor' );\n\n\n// VARIABLES //\n\n// Blocksize for pairwise summation (NOTE: decreasing the blocksize decreases rounding error as more pairs are summed, but also decreases performance. Because the inner loop is unrolled eight times, the blocksize is effectively `16`.):\nvar BLOCKSIZE = 128;\n\n\n// MAIN //\n\n/**\n* Computes the sum of a double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* ## Method\n*\n* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.\n*\n* ## References\n*\n* - Higham, Nicholas J. 1993. \"The Accuracy of Floating Point Summation.\" _SIAM Journal on Scientific Computing_ 14 (4): 783\u201399. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).\n*\n* @private\n* @param {PositiveInteger} N - number of indexed elements\n* @param {Float64Array} x - input array\n* @param {integer} strideX - `x` stride length\n* @param {NonNegativeInteger} offsetX - `x` starting index\n* @param {Float64Array} out - two-element output array whose first element is the accumulated sum and whose second element is the accumulated number of summed values\n* @param {integer} strideOut - `out` stride length\n* @param {NonNegativeInteger} offsetOut - `out` starting index\n* @returns {Float64Array} output array\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var floor = require( '@stdlib/math-base-special-floor' );\n*\n* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );\n* var N = floor( x.length / 2 );\n*\n* var out = new Float64Array( [ 0.0, 0 ] );\n* var v = sumpw( N, x, 2, 1, out, 1, 0 );\n* // returns [ 5.0, 4 ]\n*/\nfunction sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) {\n\tvar ix;\n\tvar io;\n\tvar s0;\n\tvar s1;\n\tvar s2;\n\tvar s3;\n\tvar s4;\n\tvar s5;\n\tvar s6;\n\tvar s7;\n\tvar M;\n\tvar s;\n\tvar n;\n\tvar v;\n\tvar i;\n\n\tif ( N <= 0 ) {\n\t\treturn out;\n\t}\n\tix = offsetX;\n\tio = offsetOut;\n\tif ( N === 1 || strideX === 0 ) {\n\t\tif ( isnan( x[ ix ] ) ) {\n\t\t\treturn out;\n\t\t}\n\t\tout[ io ] += x[ ix ];\n\t\tout[ io+strideOut ] += 1;\n\t\treturn out;\n\t}\n\tif ( N < 8 ) {\n\t\t// Use simple summation...\n\t\ts = 0.0;\n\t\tn = 0;\n\t\tfor ( i = 0; i < N; i++ ) {\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t}\n\t\tout[ io ] += s;\n\t\tout[ io+strideOut ] += n;\n\t\treturn out;\n\t}\n\tif ( N <= BLOCKSIZE ) {\n\t\t// Sum a block with 8 accumulators (by loop unrolling, we lower the effective blocksize to 16)...\n\t\ts0 = 0.0;\n\t\ts1 = 0.0;\n\t\ts2 = 0.0;\n\t\ts3 = 0.0;\n\t\ts4 = 0.0;\n\t\ts5 = 0.0;\n\t\ts6 = 0.0;\n\t\ts7 = 0.0;\n\t\tn = 0;\n\n\t\tM = N % 8;\n\t\tfor ( i = 0; i < N-M; i += 8 ) {\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts0 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts1 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts2 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts3 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts4 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts5 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts6 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts7 += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t}\n\t\t// Pairwise sum the accumulators:\n\t\ts = ((s0+s1) + (s2+s3)) + ((s4+s5) + (s6+s7));\n\n\t\t// Clean-up loop...\n\t\tfor ( i; i < N; i++ ) {\n\t\t\tv = x[ ix ];\n\t\t\tif ( v === v ) {\n\t\t\t\ts += v;\n\t\t\t\tn += 1;\n\t\t\t}\n\t\t\tix += strideX;\n\t\t}\n\t\tout[ io ] += s;\n\t\tout[ io+strideOut ] += n;\n\t\treturn out;\n\t}\n\t// Recurse by dividing by two, but avoiding non-multiples of unroll factor...\n\tn = floor( N/2 );\n\tn -= n % 8;\n\tsumpw( n, x, strideX, ix, out, strideOut, offsetOut );\n\tsumpw( N-n, x, strideX, ix+(n*strideX), out, strideOut, offsetOut );\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = sumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar sumpw = require( './sumpw.js' );\n\n\n// MAIN //\n\n/**\n* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* ## Method\n*\n* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.\n*\n* ## References\n*\n* - Higham, Nicholas J. 1993. \"The Accuracy of Floating Point Summation.\" _SIAM Journal on Scientific Computing_ 14 (4): 783\u201399. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).\n*\n* @param {PositiveInteger} N - number of indexed elements\n* @param {Float64Array} x - input array\n* @param {integer} strideX - `x` stride length\n* @param {Float64Array} out - output array\n* @param {integer} strideOut - `out` stride length\n* @returns {Float64Array} output array\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n*\n* var x = new Float64Array( [ 1.0, -2.0, NaN, 2.0 ] );\n* var out = new Float64Array( 2 );\n*\n* var v = dnannsumpw( x.length, x, 1, out, 1 );\n* // returns [ 1.0, 3 ]\n*/\nfunction dnannsumpw( N, x, strideX, out, strideOut ) {\n\tvar ix;\n\tvar io;\n\tif ( strideX < 0 ) {\n\t\tix = (1-N) * strideX;\n\t} else {\n\t\tix = 0;\n\t}\n\tif ( strideOut < 0 ) {\n\t\tio = -strideOut;\n\t} else {\n\t\tio = 0;\n\t}\n\tout[ io ] = 0.0;\n\tout[ io+strideOut ] = 0;\n\tsumpw( N, x, strideX, ix, out, strideOut, io );\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar sumpw = require( './sumpw.js' );\n\n\n// MAIN //\n\n/**\n* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* ## Method\n*\n* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.\n*\n* ## References\n*\n* - Higham, Nicholas J. 1993. \"The Accuracy of Floating Point Summation.\" _SIAM Journal on Scientific Computing_ 14 (4): 783\u201399. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).\n*\n* @param {PositiveInteger} N - number of indexed elements\n* @param {Float64Array} x - input array\n* @param {integer} strideX - `x` stride length\n* @param {NonNegativeInteger} offsetX - `x` starting index\n* @param {Float64Array} out - output array\n* @param {integer} strideOut - `out` stride length\n* @param {NonNegativeInteger} offsetOut - `out` starting index\n* @returns {Float64Array} output array\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n*\n* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );\n* var out = new Float64Array( 2 );\n*\n* var v = dnannsumpw( 5, x, 2, 1, out, 1, 0 );\n* // returns [ 5.0, 4 ]\n*/\nfunction dnannsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) {\n\tout[ offsetOut ] = 0.0;\n\tout[ offsetOut+strideOut ] = 0;\n\tsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut );\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar setReadOnly = require( '@stdlib/utils-define-nonenumerable-read-only-property' );\nvar dnannsumpw = require( './dnannsumpw.js' );\nvar ndarray = require( './ndarray.js' );\n\n\n// MAIN //\n\nsetReadOnly( dnannsumpw, 'ndarray', ndarray );\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2020 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n/**\n* Compute the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.\n*\n* @module @stdlib/blas-ext-base-dnannsumpw\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var dnannsumpw = require( '@stdlib/blas-ext-base-dnannsumpw' );\n*\n* var x = new Float64Array( [ 1.0, -2.0, NaN, 2.0 ] );\n* var out = new Float64Array( 2 );\n*\n* var v = dnannsumpw( x.length, x, 1, out, 1 );\n* // returns [ 1.0, 3 ]\n*\n* @example\n* var Float64Array = require( '@stdlib/array-float64' );\n* var dnannsumpw = require( '@stdlib/blas-ext-base-dnannsumpw' );\n*\n* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );\n* var out = new Float64Array( 2 );\n*\n* var v = dnannsumpw.ndarray( 5, x, 2, 1, out, 1, 0 );\n* // returns [ 5.0, 4 ]\n*/\n\n// MODULES //\n\nvar join = require( 'path' ).join;\nvar tryRequire = require( '@stdlib/utils-try-require' );\nvar isError = require( '@stdlib/assert-is-error' );\nvar main = require( './main.js' );\n\n\n// MAIN //\n\nvar dnannsumpw;\nvar tmp = tryRequire( join( __dirname, './native.js' ) );\nif ( isError( tmp ) ) {\n\tdnannsumpw = main;\n} else {\n\tdnannsumpw = tmp;\n}\n\n\n// EXPORTS //\n\nmodule.exports = dnannsumpw;\n\n// exports: { \"ndarray\": \"dnannsumpw.ndarray\" }\n"], + "mappings": "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", "names": ["require_sumpw", "__commonJSMin", "exports", "module", "isnan", "floor", "BLOCKSIZE", "sumpw", "N", "x", "strideX", "offsetX", "out", "strideOut", "offsetOut", "ix", "io", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s", "n", "v", "i", "require_dnannsumpw", "__commonJSMin", "exports", "module", "sumpw", "dnannsumpw", "N", "x", "strideX", "out", "strideOut", "ix", "io", "require_ndarray", "__commonJSMin", "exports", "module", "sumpw", "dnannsumpw", "N", "x", "strideX", "offsetX", "out", "strideOut", "offsetOut", "require_main", "__commonJSMin", "exports", "module", "setReadOnly", "dnannsumpw", "ndarray", "join", "tryRequire", "isError", "main", "dnannsumpw", "tmp"] } diff --git a/docs/repl.txt b/docs/repl.txt index e9d9ae4..7a9cab8 100644 --- a/docs/repl.txt +++ b/docs/repl.txt @@ -20,7 +20,7 @@ Input array. strideX: integer - Index increment for `x`. + Index increment for the strided array. out: Float64Array Output array. @@ -45,18 +45,17 @@ // Using `N` and `stride` parameters: > x = new {{alias:@stdlib/array/float64}}( [ -2.0, 1.0, 1.0, -5.0, 2.0, -1.0, NaN, NaN ] ); > out = new {{alias:@stdlib/array/float64}}( 2 ); - > var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 ); - > {{alias}}( N, x, 2, out, 1 ) + > {{alias}}( 4, x, 2, out, 1 ) [ 1.0, 3 ] // Using view offsets: > var x0 = new {{alias:@stdlib/array/float64}}( [ 1.0, -2.0, 3.0, 2.0, 5.0, 1.0, NaN, NaN ] ); > var x1 = new {{alias:@stdlib/array/float64}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); - > N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 ); > out = new {{alias:@stdlib/array/float64}}( 2 ); - > {{alias}}( N, x1, 2, out, 1 ) + > {{alias}}( 4, x1, 2, out, 1 ) [ 1.0, 3 ] + {{alias}}.ndarray( N, x, strideX, offsetX, out, strideOut, offsetOut ) Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation and alternative indexing @@ -75,10 +74,10 @@ Input array. strideX: integer - Index increment for `x`. + Index increment for the strided array. offsetX: integer - Starting index for `x`. + Starting index for the strided array. out: Float64Array Output array. @@ -105,9 +104,8 @@ // Using offset parameter: > var x = new {{alias:@stdlib/array/float64}}( [ 1.0, -2.0, 3.0, 2.0, 5.0, 1.0, NaN, NaN ] ); - > var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 ); > out = new {{alias:@stdlib/array/float64}}( 2 ); - > {{alias}}.ndarray( N, x, 2, 1, out, 1, 0 ) + > {{alias}}.ndarray( 4, x, 2, 1, out, 1, 0 ) [ 1.0, 3 ] See Also diff --git a/examples/index.js b/examples/index.js index 5def9e7..916fc66 100644 --- a/examples/index.js +++ b/examples/index.js @@ -18,25 +18,22 @@ 'use strict'; -var randu = require( '@stdlib/random-base-randu' ); -var round = require( '@stdlib/math-base-special-round' ); +var discreteUniform = require( '@stdlib/random-base-discrete-uniform' ); +var bernoulli = require( '@stdlib/random-base-bernoulli' ); +var filledarrayBy = require( '@stdlib/array-filled-by' ); var Float64Array = require( '@stdlib/array-float64' ); var dnannsumpw = require( './../lib' ); -var out; -var x; -var i; - -x = new Float64Array( 10 ); -for ( i = 0; i < x.length; i++ ) { - if ( randu() < 0.2 ) { - x[ i ] = NaN; - } else { - x[ i ] = round( randu()*100.0 ); +function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return discreteUniform( 0, 100 ); } + return NaN; } + +var x = filledarrayBy( 10, 'float64', rand ); console.log( x ); -out = new Float64Array( 2 ); +var out = new Float64Array( 2 ); dnannsumpw( x.length, x, 1, out, 1 ); console.log( out ); diff --git a/include.gypi b/include.gypi index 2fa318f..9212937 100644 --- a/include.gypi +++ b/include.gypi @@ -36,7 +36,7 @@ # Source files: 'src_files': [ - '<(src_dir)/addon.cpp', + '<(src_dir)/addon.c', '[ 5.0, 4 ] */ diff --git a/lib/ndarray.js b/lib/ndarray.js index 742da74..3613fe2 100644 --- a/lib/ndarray.js +++ b/lib/ndarray.js @@ -47,14 +47,11 @@ var sumpw = require( './sumpw.js' ); * * @example * var Float64Array = require( '@stdlib/array-float64' ); -* var floor = require( '@stdlib/math-base-special-floor' ); * * var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] ); * var out = new Float64Array( 2 ); * -* var N = floor( x.length / 2 ); -* -* var v = dnannsumpw( N, x, 2, 1, out, 1, 0 ); +* var v = dnannsumpw( 5, x, 2, 1, out, 1, 0 ); * // returns [ 5.0, 4 ] */ function dnannsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { diff --git a/lib/ndarray.native.js b/lib/ndarray.native.js index 757d00c..e9fb488 100644 --- a/lib/ndarray.native.js +++ b/lib/ndarray.native.js @@ -20,7 +20,8 @@ // MODULES // -var Float64Array = require( '@stdlib/array-float64' ); +var minViewBufferIndex = require( '@stdlib/strided-base-min-view-buffer-index' ); +var offsetView = require( '@stdlib/strided-base-offset-view' ); var addon = require( './dnannsumpw.native.js' ); @@ -40,27 +41,24 @@ var addon = require( './dnannsumpw.native.js' ); * * @example * var Float64Array = require( '@stdlib/array-float64' ); -* var floor = require( '@stdlib/math-base-special-floor' ); * * var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] ); * var out = new Float64Array( 2 ); * -* var N = floor( x.length / 2 ); -* -* var v = dnannsumpw( N, x, 2, 1, out, 1, 0 ); +* var v = dnannsumpw( 5, x, 2, 1, out, 1, 0 ); * // returns [ 5.0, 4 ] */ function dnannsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { var viewOut; var viewX; - if ( strideX < 0 ) { - offsetX += (N-1) * strideX; - } + + offsetX = minViewBufferIndex( N, strideX, offsetX ); if ( strideOut < 0 ) { offsetOut += strideOut; } - viewX = new Float64Array( x.buffer, x.byteOffset+(x.BYTES_PER_ELEMENT*offsetX), x.length-offsetX ); // eslint-disable-line max-len - viewOut = new Float64Array( out.buffer, out.byteOffset+(out.BYTES_PER_ELEMENT*offsetOut), out.length-offsetOut ); // eslint-disable-line max-len + + viewX = offsetView( x, offsetX ); + viewOut = offsetView( out, offsetOut ); addon( N, viewX, strideX, viewOut, strideOut ); return out; } diff --git a/manifest.json b/manifest.json index 2e7c461..1159027 100644 --- a/manifest.json +++ b/manifest.json @@ -1,40 +1,76 @@ { - "options": {}, - "fields": [ - { - "field": "src", - "resolve": true, - "relative": true - }, - { - "field": "include", - "resolve": true, - "relative": true - }, - { - "field": "libraries", - "resolve": false, - "relative": false - }, - { - "field": "libpath", - "resolve": true, - "relative": false - } - ], - "confs": [ - { - "src": [ - "./src/dnannsumpw.c" - ], - "include": [ - "./include" - ], - "libraries": [ - "-lm" - ], - "libpath": [], - "dependencies": [] - } - ] + "options": { + "task": "build" + }, + "fields": [ + { + "field": "src", + "resolve": true, + "relative": true + }, + { + "field": "include", + "resolve": true, + "relative": true + }, + { + "field": "libraries", + "resolve": false, + "relative": false + }, + { + "field": "libpath", + "resolve": true, + "relative": false + } + ], + "confs": [ + { + "task": "build", + "src": [ + "./src/dnannsumpw.c" + ], + "include": [ + "./include" + ], + "libraries": [ + "-lm" + ], + "libpath": [], + "dependencies": [ + "@stdlib/napi-export", + "@stdlib/napi-argv", + "@stdlib/napi-argv-int64", + "@stdlib/napi-argv-strided-float64array" + ] + }, + { + "task": "benchmark", + "src": [ + "./src/dnannsumpw.c" + ], + "include": [ + "./include" + ], + "libraries": [ + "-lm" + ], + "libpath": [], + "dependencies": [] + }, + { + "task": "examples", + "src": [ + "./src/dnannsumpw.c" + ], + "include": [ + "./include" + ], + "libraries": [ + "-lm" + ], + "libpath": [], + "dependencies": [] + } + ] } diff --git a/package.json b/package.json index bfcd1c8..11929e9 100644 --- a/package.json +++ b/package.json @@ -44,16 +44,24 @@ "@stdlib/assert-is-error": "^0.2.1", "@stdlib/math-base-assert-is-nan": "^0.2.1", "@stdlib/math-base-special-floor": "^0.2.2", + "@stdlib/napi-argv": "^0.2.1", + "@stdlib/napi-argv-int64": "^0.2.1", + "@stdlib/napi-argv-strided-float64array": "^0.2.1", + "@stdlib/napi-export": "^0.2.1", "@stdlib/utils-define-nonenumerable-read-only-property": "^0.2.1", "@stdlib/utils-library-manifest": "^0.2.1", "@stdlib/utils-try-require": "^0.2.1" }, "devDependencies": { + "@stdlib/array-filled-by": "^0.2.1", "@stdlib/array-float64": "^0.2.1", "@stdlib/assert-is-browser": "^0.2.1", "@stdlib/math-base-special-pow": "^0.2.1", - "@stdlib/math-base-special-round": "^0.2.1", - "@stdlib/random-base-randu": "^0.2.1", + "@stdlib/random-base-bernoulli": "^0.2.1", + "@stdlib/random-base-discrete-uniform": "^0.2.1", + "@stdlib/random-base-uniform": "^0.2.1", + "@stdlib/strided-base-min-view-buffer-index": "^0.2.1", + "@stdlib/strided-base-offset-view": "^0.2.1", "proxyquire": "^2.0.0", "tape": "git+https://github.com/kgryte/tape.git#fix/globby", "istanbul": "^0.4.1", diff --git a/src/addon.c b/src/addon.c new file mode 100644 index 0000000..632de25 --- /dev/null +++ b/src/addon.c @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2020 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "stdlib/blas/ext/base/dnannsumpw.h" +#include "stdlib/napi/export.h" +#include "stdlib/napi/argv.h" +#include "stdlib/napi/argv_int64.h" +#include "stdlib/napi/argv_strided_float64array.h" +#include + +/** +* Receives JavaScript callback invocation data. +* +* @private +* @param env environment under which the function is invoked +* @param info callback data +* @return Node-API value +*/ +napi_value addon( napi_env env, napi_callback_info info ) { + STDLIB_NAPI_ARGV( env, info, argv, argc, 5 ) + STDLIB_NAPI_ARGV_INT64( env, N, argv, 0 ); + STDLIB_NAPI_ARGV_INT64( env, strideX, argv, 2 ); + STDLIB_NAPI_ARGV_INT64( env, strideOut, argv, 4 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, strideX, argv, 1 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, Out, 2, strideOut, argv, 3 ); + + int64_t io; + if ( strideOut < 0 ) { + io = -strideOut; + } + else { + io = 0; + } + + double *out = Out; + int64_t n; + out[ io ] = stdlib_strided_dnannsumpw( N, X, strideX, &n ); + out[ io + strideOut ] = (double)n; + + return NULL; +} + +STDLIB_NAPI_MODULE_EXPORT_FCN( addon ) diff --git a/src/addon.cpp b/src/addon.cpp deleted file mode 100644 index 50b98b5..0000000 --- a/src/addon.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2020 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "stdlib/blas/ext/base/dnannsumpw.h" -#include -#include -#include -#include -#include - -/** -* Add-on namespace. -*/ -namespace stdlib_blas_ext_base_dnannsumpw { - - /** - * Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation. - * - * ## Notes - * - * - When called from JavaScript, the function expects five arguments: - * - * - `N`: number of indexed elements - * - `X`: input array - * - `strideX`: `X` stride length - * - `Out`: output array - * - `strideOut`: `Out` stride length - */ - napi_value node_dnannsumpw( napi_env env, napi_callback_info info ) { - napi_status status; - - size_t argc = 5; - napi_value argv[ 5 ]; - status = napi_get_cb_info( env, info, &argc, argv, nullptr, nullptr ); - assert( status == napi_ok ); - - if ( argc < 5 ) { - napi_throw_error( env, nullptr, "invalid invocation. Must provide 5 arguments." ); - return nullptr; - } - - napi_valuetype vtype0; - status = napi_typeof( env, argv[ 0 ], &vtype0 ); - assert( status == napi_ok ); - if ( vtype0 != napi_number ) { - napi_throw_type_error( env, nullptr, "invalid argument. First argument must be a number." ); - return nullptr; - } - - bool res1; - status = napi_is_typedarray( env, argv[ 1 ], &res1 ); - assert( status == napi_ok ); - if ( res1 == false ) { - napi_throw_type_error( env, nullptr, "invalid argument. Second argument must be a Float64Array." ); - return nullptr; - } - - napi_valuetype vtype2; - status = napi_typeof( env, argv[ 2 ], &vtype2 ); - assert( status == napi_ok ); - if ( vtype2 != napi_number ) { - napi_throw_type_error( env, nullptr, "invalid argument. Third argument must be a number." ); - return nullptr; - } - - bool res3; - status = napi_is_typedarray( env, argv[ 3 ], &res3 ); - assert( status == napi_ok ); - if ( res3 == false ) { - napi_throw_type_error( env, nullptr, "invalid argument. Fourth argument must be a Float64Array." ); - return nullptr; - } - - napi_valuetype vtype4; - status = napi_typeof( env, argv[ 4 ], &vtype4 ); - assert( status == napi_ok ); - if ( vtype4 != napi_number ) { - napi_throw_type_error( env, nullptr, "invalid argument. Fifth argument must be a number." ); - return nullptr; - } - - int64_t N; - status = napi_get_value_int64( env, argv[ 0 ], &N ); - assert( status == napi_ok ); - - int64_t strideX; - status = napi_get_value_int64( env, argv[ 2 ], &strideX ); - assert( status == napi_ok ); - - int64_t strideOut; - status = napi_get_value_int64( env, argv[ 4 ], &strideOut ); - assert( status == napi_ok ); - - napi_typedarray_type vtype1; - size_t xlen; - void *X; - status = napi_get_typedarray_info( env, argv[ 1 ], &vtype1, &xlen, &X, nullptr, nullptr ); - assert( status == napi_ok ); - if ( vtype1 != napi_float64_array ) { - napi_throw_type_error( env, nullptr, "invalid argument. Second argument must be a Float64Array." ); - return nullptr; - } - if ( (N-1)*llabs(strideX) >= (int64_t)xlen ) { - napi_throw_range_error( env, nullptr, "invalid argument. Second argument has insufficient elements based on the associated stride and the number of indexed elements." ); - return nullptr; - } - - napi_typedarray_type vtype3; - size_t olen; - void *Out; - status = napi_get_typedarray_info( env, argv[ 3 ], &vtype3, &olen, &Out, nullptr, nullptr ); - assert( status == napi_ok ); - if ( vtype3 != napi_float64_array ) { - napi_throw_type_error( env, nullptr, "invalid argument. Fourth argument must be a Float64Array." ); - return nullptr; - } - if ( llabs(strideOut) > (int64_t)olen ) { - napi_throw_range_error( env, nullptr, "invalid argument. Fourth argument has insufficient elements based on the associated stride and the required number of output elements." ); - return nullptr; - } - - int64_t io; - if ( strideOut < 0 ) { - io = -strideOut; - } else { - io = 0; - } - - double *out = (double *)Out; - int64_t n; - out[ io ] = stdlib_strided_dnannsumpw( N, (double *)X, strideX, &n ); - out[ io+strideOut ] = (double)n; - - return nullptr; - - } - - napi_value Init( napi_env env, napi_value exports ) { - napi_status status; - napi_value fcn; - status = napi_create_function( env, "exports", NAPI_AUTO_LENGTH, node_dnannsumpw, NULL, &fcn ); - assert( status == napi_ok ); - return fcn; - } - - NAPI_MODULE( NODE_GYP_MODULE_NAME, Init ) -} // end namespace stdlib_blas_ext_base_dnannsumpw diff --git a/test/test.dnannsumpw.js b/test/test.dnannsumpw.js index caf44b4..6cace96 100644 --- a/test/test.dnannsumpw.js +++ b/test/test.dnannsumpw.js @@ -21,7 +21,6 @@ // MODULES // var tape = require( 'tape' ); -var floor = require( '@stdlib/math-base-special-floor' ); var Float64Array = require( '@stdlib/array-float64' ); var dnannsumpw = require( './../lib/dnannsumpw.js' ); @@ -35,7 +34,7 @@ tape( 'main export is a function', function test( t ) { }); tape( 'the function has an arity of 5', function test( t ) { - t.strictEqual( dnannsumpw.length, 5, 'has expected arity' ); + t.strictEqual( dnannsumpw.length, 5, 'returns expected value' ); t.end(); }); @@ -176,7 +175,6 @@ tape( 'if provided an `N` parameter equal to `1`, the function returns a sum equ tape( 'the function supports `stride` parameters', function test( t ) { var expected; var out; - var N; var x; var v; @@ -194,8 +192,7 @@ tape( 'the function supports `stride` parameters', function test( t ) { ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, 2, out, 2 ); + v = dnannsumpw( 5, x, 2, out, 2 ); expected = new Float64Array( [ 5.0, 0.0, 4.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -206,7 +203,6 @@ tape( 'the function supports `stride` parameters', function test( t ) { tape( 'the function supports negative `stride` parameters', function test( t ) { var expected; var out; - var N; var x; var v; @@ -224,8 +220,7 @@ tape( 'the function supports negative `stride` parameters', function test( t ) { ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, -2, out, -2 ); + v = dnannsumpw( 5, x, -2, out, -2 ); expected = new Float64Array( [ 4.0, 0.0, 5.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -257,7 +252,6 @@ tape( 'the function supports view offsets', function test( t ) { var out1; var x0; var x1; - var N; var v; x0 = new Float64Array([ @@ -277,9 +271,8 @@ tape( 'the function supports view offsets', function test( t ) { x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element out1 = new Float64Array( out0.buffer, out0.BYTES_PER_ELEMENT*2 ); // start at the 3rd element - N = floor(x1.length / 2); - v = dnannsumpw( N, x1, 2, out1, 1 ); + v = dnannsumpw( 5, x1, 2, out1, 1 ); expected0 = new Float64Array( [ 0.0, 0.0, 5.0, 4.0 ] ); expected1 = new Float64Array( [ 5.0, 4.0 ] ); diff --git a/test/test.dnannsumpw.native.js b/test/test.dnannsumpw.native.js index 2ee2654..9af4440 100644 --- a/test/test.dnannsumpw.native.js +++ b/test/test.dnannsumpw.native.js @@ -22,7 +22,6 @@ var resolve = require( 'path' ).resolve; var tape = require( 'tape' ); -var floor = require( '@stdlib/math-base-special-floor' ); var Float64Array = require( '@stdlib/array-float64' ); var tryRequire = require( '@stdlib/utils-try-require' ); @@ -44,7 +43,7 @@ tape( 'main export is a function', opts, function test( t ) { }); tape( 'the function has an arity of 5', opts, function test( t ) { - t.strictEqual( dnannsumpw.length, 5, 'has expected arity' ); + t.strictEqual( dnannsumpw.length, 5, 'returns expected value' ); t.end(); }); @@ -185,7 +184,6 @@ tape( 'if provided an `N` parameter equal to `1`, the function returns a sum equ tape( 'the function supports `stride` parameters', opts, function test( t ) { var expected; var out; - var N; var x; var v; @@ -203,8 +201,7 @@ tape( 'the function supports `stride` parameters', opts, function test( t ) { ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, 2, out, 2 ); + v = dnannsumpw( 5, x, 2, out, 2 ); expected = new Float64Array( [ 5.0, 0.0, 4.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -215,7 +212,6 @@ tape( 'the function supports `stride` parameters', opts, function test( t ) { tape( 'the function supports negative `stride` parameters', opts, function test( t ) { var expected; var out; - var N; var x; var v; @@ -233,8 +229,7 @@ tape( 'the function supports negative `stride` parameters', opts, function test( ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, -2, out, -2 ); + v = dnannsumpw( 5, x, -2, out, -2 ); expected = new Float64Array( [ 4.0, 0.0, 5.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -266,7 +261,6 @@ tape( 'the function supports view offsets', opts, function test( t ) { var out1; var x0; var x1; - var N; var v; x0 = new Float64Array([ @@ -286,9 +280,8 @@ tape( 'the function supports view offsets', opts, function test( t ) { x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element out1 = new Float64Array( out0.buffer, out0.BYTES_PER_ELEMENT*2 ); // start at the 3rd element - N = floor(x1.length / 2); - v = dnannsumpw( N, x1, 2, out1, 1 ); + v = dnannsumpw( 5, x1, 2, out1, 1 ); expected0 = new Float64Array( [ 0.0, 0.0, 5.0, 4.0 ] ); expected1 = new Float64Array( [ 5.0, 4.0 ] ); diff --git a/test/test.ndarray.js b/test/test.ndarray.js index aa888ec..9c8c855 100644 --- a/test/test.ndarray.js +++ b/test/test.ndarray.js @@ -21,7 +21,6 @@ // MODULES // var tape = require( 'tape' ); -var floor = require( '@stdlib/math-base-special-floor' ); var Float64Array = require( '@stdlib/array-float64' ); var dnannsumpw = require( './../lib/ndarray.js' ); @@ -35,7 +34,7 @@ tape( 'main export is a function', function test( t ) { }); tape( 'the function has an arity of 7', function test( t ) { - t.strictEqual( dnannsumpw.length, 7, 'has expected arity' ); + t.strictEqual( dnannsumpw.length, 7, 'returns expected value' ); t.end(); }); @@ -176,7 +175,6 @@ tape( 'if provided an `N` parameter equal to `1`, the function returns the first tape( 'the function supports a `stride` parameter', function test( t ) { var expected; var out; - var N; var x; var v; @@ -194,8 +192,7 @@ tape( 'the function supports a `stride` parameter', function test( t ) { ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, 2, 0, out, 2, 0 ); + v = dnannsumpw( 5, x, 2, 0, out, 2, 0 ); expected = new Float64Array( [ 5.0, 0.0, 4.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -206,7 +203,6 @@ tape( 'the function supports a `stride` parameter', function test( t ) { tape( 'the function supports a negative `stride` parameter', function test( t ) { var expected; var out; - var N; var x; var v; @@ -224,8 +220,7 @@ tape( 'the function supports a negative `stride` parameter', function test( t ) ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, -2, 8, out, -2, 2 ); + v = dnannsumpw( 5, x, -2, 8, out, -2, 2 ); expected = new Float64Array( [ 4.0, 0.0, 5.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -253,7 +248,6 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns the f tape( 'the function supports `offset` parameters', function test( t ) { var expected; var out; - var N; var x; var v; @@ -270,9 +264,8 @@ tape( 'the function supports `offset` parameters', function test( t ) { NaN // 4 ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, 2, 1, out, 2, 1 ); + v = dnannsumpw( 5, x, 2, 1, out, 2, 1 ); expected = new Float64Array( [ 0.0, 5.0, 0.0, 4.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); diff --git a/test/test.ndarray.native.js b/test/test.ndarray.native.js index 0618c9e..82045bf 100644 --- a/test/test.ndarray.native.js +++ b/test/test.ndarray.native.js @@ -22,7 +22,6 @@ var resolve = require( 'path' ).resolve; var tape = require( 'tape' ); -var floor = require( '@stdlib/math-base-special-floor' ); var Float64Array = require( '@stdlib/array-float64' ); var tryRequire = require( '@stdlib/utils-try-require' ); @@ -44,7 +43,7 @@ tape( 'main export is a function', opts, function test( t ) { }); tape( 'the function has an arity of 7', opts, function test( t ) { - t.strictEqual( dnannsumpw.length, 7, 'has expected arity' ); + t.strictEqual( dnannsumpw.length, 7, 'returns expected value' ); t.end(); }); @@ -185,7 +184,6 @@ tape( 'if provided an `N` parameter equal to `1`, the function returns the first tape( 'the function supports a `stride` parameter', opts, function test( t ) { var expected; var out; - var N; var x; var v; @@ -203,8 +201,7 @@ tape( 'the function supports a `stride` parameter', opts, function test( t ) { ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, 2, 0, out, 2, 0 ); + v = dnannsumpw( 5, x, 2, 0, out, 2, 0 ); expected = new Float64Array( [ 5.0, 0.0, 4.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -215,7 +212,6 @@ tape( 'the function supports a `stride` parameter', opts, function test( t ) { tape( 'the function supports a negative `stride` parameter', opts, function test( t ) { var expected; var out; - var N; var x; var v; @@ -233,8 +229,7 @@ tape( 'the function supports a negative `stride` parameter', opts, function test ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, -2, 8, out, -2, 2 ); + v = dnannsumpw( 5, x, -2, 8, out, -2, 2 ); expected = new Float64Array( [ 4.0, 0.0, 5.0, 0.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); @@ -262,7 +257,6 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns the f tape( 'the function supports `offset` parameters', opts, function test( t ) { var expected; var out; - var N; var x; var v; @@ -279,9 +273,8 @@ tape( 'the function supports `offset` parameters', opts, function test( t ) { NaN // 4 ]); out = new Float64Array( 4 ); - N = floor( x.length / 2 ); - v = dnannsumpw( N, x, 2, 1, out, 2, 1 ); + v = dnannsumpw( 5, x, 2, 1, out, 2, 1 ); expected = new Float64Array( [ 0.0, 5.0, 0.0, 4.0 ] ); t.deepEqual( v, expected, 'returns expected value' );