diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..7212d812 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,33 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2017 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. +#/ + +# Configuration file which assigns attributes to pathnames. +# +# [1]: https://git-scm.com/docs/gitattributes + +# Automatically normalize the line endings of any committed text files: +* text=auto + +# 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 + +# Override what is considered "documentation" by GitHub's linguist: +examples/** linguist-documentation=false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..3e6a00b9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ + + +We are excited about your pull request, but unfortunately we are not accepting pull requests against this repository, as all development happens on the [main project repository](https://github.com/stdlib-js/stdlib). We kindly request that you submit this pull request against the [respective directory](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray) of the main repository where we’ll review and provide feedback. + +If this is your first stdlib contribution, be sure to read the [contributing guide](https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md) which provides guidelines and instructions for submitting contributions. You may also consult the [development guide](https://github.com/stdlib-js/stdlib/blob/develop/docs/development.md) for help on developing stdlib. + +We look forward to receiving your contribution! :smiley: \ No newline at end of file diff --git a/.github/workflows/close_pull_requests.yml b/.github/workflows/close_pull_requests.yml new file mode 100644 index 00000000..0542842a --- /dev/null +++ b/.github/workflows/close_pull_requests.yml @@ -0,0 +1,23 @@ +name: Close Pull Requests + +on: + pull_request_target: + types: [opened] + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Thank you for submitting a pull request. :raised_hands: + + We greatly appreciate your willingness to submit a contribution. However, we are not accepting pull requests against this repository, as all development happens on the [main project repository](https://github.com/stdlib-js/stdlib). + + We kindly request that you submit this pull request against the [respective directory](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray) of the main repository where we’ll review and provide feedback. If this is your first stdlib contribution, be sure to read the [contributing guide](https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md) which provides guidelines and instructions for submitting contributions. + + Thank you again, and we look forward to receiving your contribution! :smiley: + + Best, + The stdlib team \ No newline at end of file diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml new file mode 100644 index 00000000..7668c70a --- /dev/null +++ b/.github/workflows/examples.yml @@ -0,0 +1,19 @@ +name: examples + +on: + workflow_dispatch: + +jobs: + examples: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Install production and development dependencies + run: | + npm install + - name: Run examples + run: | + npm run examples \ No newline at end of file diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml deleted file mode 100644 index 52d1665b..00000000 --- a/.github/workflows/npm-publish.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Publish Package to npm - -on: push - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: 10 - - name: Increment version - run: | - git config --local user.email "noreply@stdlib.io" - git config --local user.name "stdlib-bot" - npm version patch - git push --tags - - uses: JS-DevTools/npm-publish@v1 - with: - token: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..a5ece1cf --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,34 @@ +name: Publish Package + +on: push + +jobs: + publish: + runs-on: ubuntu-latest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Increment version + run: | + git config --local user.email "noreply@stdlib.io" + git config --local user.name "stdlib-bot" + npm version prerelease --preid=alpha + - name: Publish package to npm + uses: JS-DevTools/npm-publish@v1 + with: + token: ${{ secrets.NPM_TOKEN }} + access: public + - name: Push changes + run: | + git push origin main + git push --tags + - uses: act10ns/slack@v1 + with: + status: ${{ job.status }} + steps: ${{ toJson(steps) }} + channel: '#npm-ci' + if: failure() \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..72b66f4e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,29 @@ +name: build + +on: + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Install production and development dependencies + id: install + run: | + npm install + - name: Run tests + id: tests + run: | + npm test + - uses: act10ns/slack@v1 + with: + status: ${{ job.status }} + steps: ${{ toJson(steps) }} + channel: '#npm-ci' + if: failure() \ No newline at end of file diff --git a/.github/workflows/test_coverage.yml b/.github/workflows/test_coverage.yml new file mode 100644 index 00000000..debbfd56 --- /dev/null +++ b/.github/workflows/test_coverage.yml @@ -0,0 +1,24 @@ +name: coverage + +on: + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Install production and development dependencies + run: | + npm install + - name: Calculate test coverage + run: | + npm run test-cov + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + directory: reports/coverage + flags: unittests \ No newline at end of file diff --git a/.github/workflows/test_install.yml b/.github/workflows/test_install.yml new file mode 100644 index 00000000..039afb6e --- /dev/null +++ b/.github/workflows/test_install.yml @@ -0,0 +1,27 @@ +name: Test Installing Dependencies + +on: + workflow_run: + workflows: ["Publish Package"] + types: [completed] + +jobs: + on-success: + runs-on: ubuntu-latest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + if: ${{ github.event.workflow_run.conclusion == 'success' }} + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Install production dependencies via npm + run: | + npm install --only=prod + - uses: act10ns/slack@v1 + with: + status: ${{ job.status }} + steps: ${{ toJson(steps) }} + channel: '#npm-ci' + if: failure() \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..1475963a --- /dev/null +++ b/.gitignore @@ -0,0 +1,181 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2017 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. +#/ + +# Files # +######### +.postinstall.json + +# Directories # +############### +build/ +downloads/ +reports/ +tmp/ + +# Compiled source # +################### +*.com +*.class +*.dll +*.o +*.so +*.slo +*.lo +*.obj +*.dylib +*.lai +*.la +*.a +*.lib +*.ko +*.elf +*.node + +# Precompiled headers # +####################### +*.gch +*.pch + +# Executables # +############### +*.exe +*.out +*.app + +# Packages # +############ +# It is better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Make an exception for compressed distributable files: +!dist/*.gz + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db +Desktop.ini + +# Temporary files # +################### +*~ + +# Node.js # +########### +/node_modules/ +lib/node_modules/**/node_modules/ +docs/**/node_modules/ +pids +*.pid +*.seed + +# Typescript # +############## +*.tsbuildinfo +lib/node_modules/**/tsconfig.json +lib/node_modules/**/tslint.json + +# Matlab # +########## +*.asv +*.mex* + +# Fortran # +########### +*.mod + +# R # +##### +.Rhistory +.Rapp.history +.Rproj.user/ + +# Python # +########## +__pycache__/ +*.py[cod] +*$py.class +*.egg-info/ + +# TeX # +####### +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.dvi +*-converted-to.* +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.brf +*.run.xml +*.fdb_latexmk +*.synctex +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync +*.alg +*.loa +acs-*.bib +*.thm +*.nav +*.snm +*.vrb +*.acn +*.acr +*.glg +*.glo +*.gls +*-concordance.tex +*.tikz +*-tikzDictionary +*.idx +*.ilg +*.ind +*.ist + +# Visual Studio # +################# +.vscode/ +jsconfig.json diff --git a/.npmignore b/.npmignore index 642016ec..f4ed12c0 100644 --- a/.npmignore +++ b/.npmignore @@ -18,6 +18,9 @@ # Files # ######### +CODE_OF_CONDUCT.md +CONTRIBUTING.md +CONTRIBUTORS TODO.md ROADMAP.md .postinstall.json diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..abd0ae4e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +stdlib expects community participants to adhere to the project Code of Conduct. The [full text](https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md) is available in the main project repository. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..8b60dead --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contribution Guidelines + +Woot woot! If you are new to stdlib, welcome! And thanks for your interest! Guidelines for how to contribute to the project are [available](https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md) in the main project repository. \ No newline at end of file diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..f5374f67 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright (c) 2016-2021 The Stdlib Authors. diff --git a/README.md b/README.md index 14ddaa10..63fd1094 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,16 @@ limitations under the License. # ndarray +[![NPM version][npm-image]][npm-url] [![Build Status][test-image]][test-url] [![Coverage Status][coverage-image]][coverage-url] [![dependencies][dependencies-image]][dependencies-url] + > Multidimensional arrays.
## Installation -``` bash -$ npm install @stdlib/ndarray +```bash +npm install @stdlib/ndarray ```
@@ -122,21 +124,13 @@ console.log( objectKeys( ns ) );
-# stdlib-js - - -
- stdlib logo -
-
- ---- +* * * -> This package is part of [stdlib][stdlib], a standard library for JavaScript and Node.js. +## Notice -stdlib is a standard library for JavaScript and Node.js, with an emphasis on numerical and scientific computing. The library provides a collection of robust, high performance libraries for mathematics, statistics, streams, utilities, and more. +This package is part of [stdlib][stdlib], a standard library for JavaScript and Node.js, with an emphasis on numerical and scientific computing. The library provides a collection of robust, high performance libraries for mathematics, statistics, streams, utilities, and more. -For unit tests, benchmarks, and information on how to develop [stdlib][stdlib], see the main project [repository][stdlib]. +For more information on the project, filing bug reports and feature requests, and guidance on how to develop [stdlib][stdlib], see the main project [repository][stdlib]. --- @@ -147,7 +141,7 @@ See [LICENSE][stdlib-license]. ## Copyright -Copyright © 2016-2020. The Stdlib [Authors][stdlib-authors]. +Copyright © 2016-2021. The Stdlib [Authors][stdlib-authors].
@@ -157,6 +151,18 @@ Copyright © 2016-2020. The Stdlib [Authors][stdlib-authors]. diff --git a/array/benchmark/benchmark.js b/array/benchmark/benchmark.js new file mode 100644 index 00000000..f50ca13c --- /dev/null +++ b/array/benchmark/benchmark.js @@ -0,0 +1,1209 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var Float32Array = require( '@stdlib/array/float32' ); +var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' ); +var pkg = require( './../package.json' ).name; +var array = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::1d,instantiation,linear_buffer', function benchmark( b ) { + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation,shape', function benchmark( b ) { + var opts; + var out; + var i; + + opts = { + 'shape': [ 6 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation,ndarray', function benchmark( b ) { + var out; + var arr; + var i; + + arr = array( new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ) ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation,no_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float32' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation,default_cast', function benchmark( b ) { + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation,dtype_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float64' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation:copy=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': false + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation:copy=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': true + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation:dtype=generic', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation:dtype=generic,flatten=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'flatten': true + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d,instantiation:dtype=generic,flatten=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'flatten': false + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,linear_buffer', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,shape', function benchmark( b ) { + var opts; + var out; + var i; + + opts = { + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,ndarray', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'shape': [ 3, 2 ] + }; + arr = array( arr, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,no_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float32', + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,default_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,dtype_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float64', + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation:copy=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': false, + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation:copy=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': true, + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation:dtype=generic', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation:dtype=generic,flatten=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ]; + opts = { + 'dtype': 'generic', + 'flatten': true + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation:dtype=generic,flatten=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'flatten': false, + 'shape': [ 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,linear_buffer', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,shape', function benchmark( b ) { + var opts; + var out; + var i; + + opts = { + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,ndarray', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'shape': [ 1, 3, 2 ] + }; + arr = array( arr, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,no_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float32', + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,default_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,dtype_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float64', + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation:copy=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': false, + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation:copy=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': true, + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation:dtype=generic', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation:dtype=generic,flatten=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ [ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ] ]; + opts = { + 'dtype': 'generic', + 'flatten': true + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation:dtype=generic,flatten=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'flatten': false, + 'shape': [ 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,linear_buffer', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,shape', function benchmark( b ) { + var opts; + var out; + var i; + + opts = { + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,ndarray', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'shape': [ 1, 1, 3, 2 ] + }; + arr = array( arr, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,no_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float32', + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,default_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,dtype_cast', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'dtype': 'float64', + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation:copy=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': false, + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation:copy=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'copy': true, + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation:dtype=generic', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation:dtype=generic,flatten=true', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ [ [ [ 1.0, 2.0 ], [ 3.0, 4.0 ], [ 5.0, 6.0 ] ] ] ]; + opts = { + 'dtype': 'generic', + 'flatten': true + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation:dtype=generic,flatten=false', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + opts = { + 'dtype': 'generic', + 'flatten': false, + 'shape': [ 1, 1, 3, 2 ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d,instantiation:ndmin=5', function benchmark( b ) { + var opts; + var out; + var arr; + var i; + + arr = new Float32Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + opts = { + 'ndmin': 5 + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = array( arr, opts ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isndarrayLike( out ) ) { + b.fail( 'should return an ndarray' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/array/benchmark/python/numpy/benchmark.py b/array/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..2a561cee --- /dev/null +++ b/array/benchmark/python/numpy/benchmark.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.array.""" + +from __future__ import print_function +import timeit + +REPEATS = 3 +COUNT = [0] # use a list to allow modification within nested scopes + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(iterations, elapsed): + """Print benchmark results. + + # Arguments + + * `iterations`: number of iterations + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(100000, 0.131009101868) + ``` + """ + rate = iterations / elapsed + + print(" ---") + print(" iterations: " + str(iterations)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(name, setup, stmt, iterations): + """Run a benchmark and print benchmark results. + + # Arguments + + * `name`: benchmark name (suffix) + * `setup`: benchmark setup + * `stmt`: statement to benchmark + * `iterations`: number of iterations + + # Examples + + ``` python + python> benchmark("::random", "from random import random;", "y = random()", 1000000) + ``` + """ + t = timeit.Timer(stmt, setup=setup) + + i = 0 + while i < REPEATS: + print("# python::numpy" + name) + COUNT[0] += 1 + elapsed = t.timeit(number=iterations) + print_results(iterations, elapsed) + print("ok " + str(COUNT[0]) + " benchmark finished") + i += 1 + + +def main(): + """Run the benchmarks.""" + # pylint: disable=too-many-statements + print_version() + + name = "::1d,instantiation,linear_buffer" + setup = "import numpy as np; x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0];" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::1d,instantiation,ndarray" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::1d,instantiation,no_cast" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::1d,instantiation,default_cast" + setup = "import numpy as np; x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0];" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::1d,instantiation,dtype_cast" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], dtype='float32');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::1d,instantiation:copy=false" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);" + stmt = "y = np.array(x, copy=False)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::1d,instantiation:copy=true" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);" + stmt = "y = np.array(x, copy=True)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation,ndarray" + setup = "import numpy as np; x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]);" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation,no_cast" + setup = "import numpy as np; x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype='float64');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation,default_cast" + setup = "import numpy as np; x = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation,dtype_cast" + setup = "import numpy as np; x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype='float32');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation:copy=false" + setup = "import numpy as np; x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]);" + stmt = "y = np.array(x, copy=False)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation:copy=true" + setup = "import numpy as np; x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]);" + stmt = "y = np.array(x, copy=True)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::2d,instantiation:flatten=true" + setup = "import numpy as np; x = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation,ndarray" + setup = "import numpy as np; x = np.array([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]);" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation,no_cast" + setup = "import numpy as np; x = np.array([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]], dtype='float64');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation,default_cast" + setup = "import numpy as np; x = [[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]];" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation,dtype_cast" + setup = "import numpy as np; x = np.array([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]], dtype='float32');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation:copy=false" + setup = "import numpy as np; x = np.array([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]);" + stmt = "y = np.array(x, copy=False)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation:copy=true" + setup = "import numpy as np; x = np.array([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]);" + stmt = "y = np.array(x, copy=True)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::3d,instantiation:flatten=true" + setup = "import numpy as np; x = [[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]];" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation,ndarray" + setup = "import numpy as np; x = np.array([[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]]);" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation,no_cast" + setup = "import numpy as np; x = np.array([[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]], dtype='float64');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation,default_cast" + setup = "import numpy as np; x = [[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]];" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation,dtype_cast" + setup = "import numpy as np; x = np.array([[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]], dtype='float32');" + stmt = "y = np.array(x, dtype='float64')" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation:copy=false" + setup = "import numpy as np; x = np.array([[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]]);" + stmt = "y = np.array(x, copy=False)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation:copy=true" + setup = "import numpy as np; x = np.array([[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]]);" + stmt = "y = np.array(x, copy=True)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::4d,instantiation:flatten=true" + setup = "import numpy as np; x = [[[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]]];" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::5d,instantiation:ndmin=5" + setup = "import numpy as np; x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0];" + stmt = "y = np.array(x)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + print_summary(COUNT[0], COUNT[0]) + + +if __name__ == "__main__": + main() diff --git a/array/examples/index.js b/array/examples/index.js new file mode 100644 index 00000000..87be9058 --- /dev/null +++ b/array/examples/index.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var array = require( './../lib' ); + +// Create a 4-dimensional array containing single-precision floating-point numbers: +var arr = array({ + 'dtype': 'float32', + 'shape': [ 3, 3, 3, 3 ] +}); + +// Retrieve an array value: +var v = arr.get( 1, 2, 1, 2 ); +console.log( v ); +// => 0.0 + +// Set an array value: +arr.set( 1, 2, 1, 2, 10.0 ); + +// Retrieve the array value: +v = arr.get( 1, 2, 1, 2 ); +console.log( v ); +// => 10.0 + +// Serialize the array as a string: +console.log( arr.toString() ); +// => "ndarray( 'float32', new Float32Array( [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ), [ 3, 3, 3, 3 ], [ 27, 9, 3, 1 ], 0, 'row-major' )" + +// Serialize the array as JSON: +console.log( JSON.stringify( arr.toJSON() ) ); +// => '{"type":"ndarray","dtype":"float32","flags":{},"order":"row-major","shape":[3,3,3,3],"strides":[27,9,3,1],"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}' diff --git a/array/lib/is_array_like_object.js b/array/lib/is_array_like_object.js index 313538c3..d3abf961 100644 --- a/array/lib/is_array_like_object.js +++ b/array/lib/is_array_like_object.js @@ -20,7 +20,7 @@ // MODULES // -var PINF = require( '@stdlib/constants/math/float64-pinf' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); var isInteger = require( '@stdlib/math/base/assert/is-integer' ); diff --git a/array/test/test.js b/array/test/test.js new file mode 100644 index 00000000..ca4a494c --- /dev/null +++ b/array/test/test.js @@ -0,0 +1,126 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if provided an options argument which is not an object', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( value ); + }; + } +}); + +tape( 'the function throws an error if not provided either a `shape` or `buffer` option', function test( t ) { + t.throws( badValue( {} ), Error, 'throws an error when not provided either a `shape` or `buffer` option' ); + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( value ); + }; + } +}); + +tape( 'the function throws an error if provided an invalid option', function test( t ) { + var values; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var opts = { + 'shape': [ 3, 2 ], + 'dtype': value + }; + ndarray( opts ); + }; + } +}); + +tape( 'the function throws an error if provided a `shape` option which is incompatible with a provided buffer', function test( t ) { + var opts = { + 'dtype': 'generic', + 'shape': [ 3, 3 ], + 'buffer': [ 1, 2, 3, 4, 5, 6 ] + }; + t.throws( badValue( opts ), Error, 'throws an error when provided incompatible `shape` and `buffer` options' ); + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( value ); + }; + } +}); + +// TODO: tests diff --git a/base/assert/examples/index.js b/base/assert/examples/index.js new file mode 100644 index 00000000..c7e940d8 --- /dev/null +++ b/base/assert/examples/index.js @@ -0,0 +1,24 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var objectKeys = require( '@stdlib/utils/keys' ); +var ns = require( './../lib' ); + +console.log( objectKeys( ns ) ); diff --git a/base/assert/is-allowed-data-type-cast/benchmark/benchmark.js b/base/assert/is-allowed-data-type-cast/benchmark/benchmark.js new file mode 100644 index 00000000..3e3b34cf --- /dev/null +++ b/base/assert/is-allowed-data-type-cast/benchmark/benchmark.js @@ -0,0 +1,165 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var isAllowedCast = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// MAIN // + +bench( pkg+':casting=unsafe', function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isAllowedCast( DTYPES[ j ], DTYPES[ k ], 'unsafe' ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':casting=equiv', function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isAllowedCast( DTYPES[ j ], DTYPES[ k ], 'equiv' ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':casting=safe', function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isAllowedCast( DTYPES[ j ], DTYPES[ k ], 'safe' ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':casting=none', function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isAllowedCast( DTYPES[ j ], DTYPES[ k ], 'none' ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':casting=same-kind', function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isAllowedCast( DTYPES[ j ], DTYPES[ k ], 'same-kind' ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-allowed-data-type-cast/benchmark/c/Makefile b/base/assert/is-allowed-data-type-cast/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-allowed-data-type-cast/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-allowed-data-type-cast/benchmark/c/benchmark.c b/base/assert/is-allowed-data-type-cast/benchmark/c/benchmark.c new file mode 100644 index 00000000..9cab12f5 --- /dev/null +++ b/base/assert/is-allowed-data-type-cast/benchmark/c/benchmark.c @@ -0,0 +1,137 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_allowed_data_type_cast`. +*/ +#include "stdlib/ndarray/base/assert/is_allowed_data_type_cast.h" +#include "stdlib/ndarray/casting_modes.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-allowed-data-type-cast" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + b = stdlib_ndarray_is_allowed_data_type_cast( i%STDLIB_NDARRAY_NDTYPES, (i%STDLIB_NDARRAY_NDTYPES)+1, STDLIB_NDARRAY_SAME_KIND_CASTING ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-allowed-data-type-cast/examples/index.js b/base/assert/is-allowed-data-type-cast/examples/index.js new file mode 100644 index 00000000..f4992405 --- /dev/null +++ b/base/assert/is-allowed-data-type-cast/examples/index.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var modes = require( '@stdlib/ndarray/casting-modes' ); +var isAllowedCast = require( './../lib' ); + +var DTYPES; +var MODES; +var bool; +var dt1; +var dt2; +var i; +var j; +var k; + +// Get a list of supported ndarray data types and casting modes: +DTYPES = dtypes(); +MODES = modes(); + +// For each data type and mode, determine whether one can cast to another data type... +for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + for ( k = 0; k < MODES.length; k++ ) { + bool = isAllowedCast( dt1, dt2, MODES[ k ] ); + console.log( '%s => %s. %s: %s.', dt1, dt2, MODES[ k ], bool ); + } + } +} diff --git a/base/assert/is-allowed-data-type-cast/test/test.js b/base/assert/is-allowed-data-type-cast/test/test.js new file mode 100644 index 00000000..a5f8e4d6 --- /dev/null +++ b/base/assert/is-allowed-data-type-cast/test/test.js @@ -0,0 +1,150 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isSafeCast = require( '@stdlib/ndarray/base/assert/is-safe-data-type-cast' ); +var isSameKindCast = require( '@stdlib/ndarray/base/assert/is-same-kind-data-type-cast' ); +var isAllowedCast = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isAllowedCast, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be cast to another ndarray data type (casting=unsafe)', function test( t ) { + var expected; + var actual; + var dt1; + var dt2; + var i; + var j; + + expected = true; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + actual = isAllowedCast( dt1, dt2, 'unsafe' ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt1+'. to: '+dt2+'.' ); + } + } + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be cast to another ndarray data type (casting=safe)', function test( t ) { + var expected; + var actual; + var dt1; + var dt2; + var i; + var j; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + expected = isSafeCast( dt1, dt2 ); + actual = isAllowedCast( dt1, dt2, 'safe' ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt1+'. to: '+dt2+'.' ); + } + } + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be cast to another ndarray data type (casting=same-kind)', function test( t ) { + var expected; + var actual; + var dt1; + var dt2; + var i; + var j; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + expected = isSameKindCast( dt1, dt2 ); + actual = isAllowedCast( dt1, dt2, 'same-kind' ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt1+'. to: '+dt2+'.' ); + } + } + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be cast to another ndarray data type (casting=none)', function test( t ) { + var expected; + var actual; + var dt1; + var dt2; + var i; + var j; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + if ( dt1 === dt2 ) { + expected = true; + } else { + expected = false; + } + actual = isAllowedCast( dt1, dt2, 'none' ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt1+'. to: '+dt2+'.' ); + } + } + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be cast to another ndarray data type (casting=equiv)', function test( t ) { + var expected; + var actual; + var dt1; + var dt2; + var i; + var j; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + if ( dt1 === dt2 ) { + expected = true; + } else { + expected = false; + } + actual = isAllowedCast( dt1, dt2, 'equiv' ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt1+'. to: '+dt2+'.' ); + } + } + t.end(); +}); diff --git a/base/assert/is-buffer-length-compatible-shape/benchmark/benchmark.js b/base/assert/is-buffer-length-compatible-shape/benchmark/benchmark.js new file mode 100644 index 00000000..18a4deff --- /dev/null +++ b/base/assert/is-buffer-length-compatible-shape/benchmark/benchmark.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var floor = require( '@stdlib/math/base/special/floor' ); +var randu = require( '@stdlib/random/base/randu' ); +var pkg = require( './../package.json' ).name; +var isBufferLengthCompatibleShape = require( './../lib' ); // eslint-disable-line id-length + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var shape; + var len; + var out; + var i; + + shape = [ 10, 10, 10 ]; + len = 1500; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 2 ] = floor( randu()*20.0 ); + out = isBufferLengthCompatibleShape( len, shape ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-buffer-length-compatible-shape/benchmark/c/Makefile b/base/assert/is-buffer-length-compatible-shape/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-buffer-length-compatible-shape/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-buffer-length-compatible-shape/benchmark/c/benchmark.c b/base/assert/is-buffer-length-compatible-shape/benchmark/c/benchmark.c new file mode 100644 index 00000000..ba4aa5e1 --- /dev/null +++ b/base/assert/is-buffer-length-compatible-shape/benchmark/c/benchmark.c @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_buffer_length_compatible_shape`. +*/ +#include "stdlib/ndarray/base/assert/is_buffer_length_compatible_shape.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-buffer-length-compatible-shape" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + shape[ 0 ] = (int64_t)( rand_double()*10.0 ); + b = stdlib_ndarray_is_buffer_length_compatible_shape( 1500, ndims, shape ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-buffer-length-compatible-shape/examples/index.js b/base/assert/is-buffer-length-compatible-shape/examples/index.js new file mode 100644 index 00000000..afda86db --- /dev/null +++ b/base/assert/is-buffer-length-compatible-shape/examples/index.js @@ -0,0 +1,41 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isBufferLengthCompatibleShape = require( './../lib' ); // eslint-disable-line id-length + +var shape; +var bool; +var len; +var i; + +len = 500; // buffer length + +shape = [ 0, 0, 0 ]; +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Determine if the buffer length is compatible with the shape array: + bool = isBufferLengthCompatibleShape( len, shape ); + console.log( 'Buffer length: %d. Shape: %s. Compatible: %s.', len, shape.join( 'x' ), bool ); +} diff --git a/base/assert/is-buffer-length-compatible-shape/test/test.js b/base/assert/is-buffer-length-compatible-shape/test/test.js new file mode 100644 index 00000000..41daf99a --- /dev/null +++ b/base/assert/is-buffer-length-compatible-shape/test/test.js @@ -0,0 +1,77 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isBufferLengthCompatibleShape = require( './../lib' ); // eslint-disable-line id-length + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isBufferLengthCompatibleShape, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if a buffer length is compatible with a provided shape array', function test( t ) { + var shape; + var bool; + + shape = [ 3, 2 ]; + bool = isBufferLengthCompatibleShape( 10, shape ); + t.strictEqual( bool, true, 'returns expected value' ); + + bool = isBufferLengthCompatibleShape( 6, shape ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + bool = isBufferLengthCompatibleShape( 2, shape ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + bool = isBufferLengthCompatibleShape( 60, shape ); + t.strictEqual( bool, true, 'returns expected value' ); + + bool = isBufferLengthCompatibleShape( 100, shape ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if a buffer length is incompatible with a provided shape array', function test( t ) { + var shape; + var bool; + + shape = [ 1, 1, 1, 2 ]; + bool = isBufferLengthCompatibleShape( 1, shape ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 10 ]; + bool = isBufferLengthCompatibleShape( 9, shape ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + bool = isBufferLengthCompatibleShape( 3, shape ); + t.strictEqual( bool, false, 'returns expected value' ); + + t.end(); +}); diff --git a/base/assert/is-buffer-length-compatible/benchmark/benchmark.js b/base/assert/is-buffer-length-compatible/benchmark/benchmark.js new file mode 100644 index 00000000..7adb1fb8 --- /dev/null +++ b/base/assert/is-buffer-length-compatible/benchmark/benchmark.js @@ -0,0 +1,62 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var pkg = require( './../package.json' ).name; +var isBufferLengthCompatible = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var offset; + var shape; + var len; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + strides[ 2 ] *= -1; + offset = strides2offset( shape, strides ); + + len = 1e6; // buffer length + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + offset += i; + out = isBufferLengthCompatible( len, shape, strides, offset ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-buffer-length-compatible/benchmark/c/Makefile b/base/assert/is-buffer-length-compatible/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-buffer-length-compatible/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-buffer-length-compatible/benchmark/c/benchmark.c b/base/assert/is-buffer-length-compatible/benchmark/c/benchmark.c new file mode 100644 index 00000000..69afd6f3 --- /dev/null +++ b/base/assert/is-buffer-length-compatible/benchmark/c/benchmark.c @@ -0,0 +1,142 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_buffer_length_compatible`. +*/ +#include "stdlib/ndarray/base/assert/is_buffer_length_compatible.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-buffer-length-compatible" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, -1 }; + int64_t offset = 0; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + offset += 1; + b = stdlib_ndarray_is_buffer_length_compatible( STDLIB_NDARRAY_UINT8, 1e6, ndims, shape, strides, offset ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-buffer-length-compatible/examples/index.js b/base/assert/is-buffer-length-compatible/examples/index.js new file mode 100644 index 00000000..1d331d93 --- /dev/null +++ b/base/assert/is-buffer-length-compatible/examples/index.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var isBufferLengthCompatible = require( './../lib' ); + +var strides; +var offset; +var shape; +var bool; +var len; +var i; +var j; + +len = 500; // buffer length +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + // Compute the index offset: + offset = strides2offset( shape, strides ) + discreteUniform( 0, 200 ); + + // Determine if a buffer length is compatible with generated meta data: + bool = isBufferLengthCompatible( len, shape, strides, offset ); + console.log( 'Buffer length: %d. Shape: %s. Strides: %s. Offset: %d. Compatible: %s.', len, shape.join( 'x' ), strides.join( ',' ), offset, bool ); +} diff --git a/base/assert/is-buffer-length-compatible/test/test.js b/base/assert/is-buffer-length-compatible/test/test.js new file mode 100644 index 00000000..00dda06e --- /dev/null +++ b/base/assert/is-buffer-length-compatible/test/test.js @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var isBufferLengthCompatible = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isBufferLengthCompatible, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if a buffer length is compatible with provided ndarray meta data', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 0; + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, 1 ]; + offset = 99999; + bool = isBufferLengthCompatible( 1e6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, 3 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -1, 3 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, -3 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -1, -3 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 1 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 2, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, 10, 1 ]; + offset = 99999; + bool = isBufferLengthCompatible( 1e6, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, -10, 1 ]; + offset = strides2offset( shape, strides ); + bool = isBufferLengthCompatible( 60, shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if a buffer length is incompatible with provided ndarray meta data', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 2 ]; + offset = 0; + bool = isBufferLengthCompatible( 2, shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 10 ]; + strides = [ 3 ]; + offset = 0; + bool = isBufferLengthCompatible( 20, shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, 2 ]; + offset = 0; + bool = isBufferLengthCompatible( 4, shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 1; + bool = isBufferLengthCompatible( 4, shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + t.end(); +}); diff --git a/base/assert/is-casting-mode/benchmark/benchmark.js b/base/assert/is-casting-mode/benchmark/benchmark.js new file mode 100644 index 00000000..fe66b0d7 --- /dev/null +++ b/base/assert/is-casting-mode/benchmark/benchmark.js @@ -0,0 +1,66 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var isCastingMode = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var v; + var i; + + values = [ + 'none', + 'equiv', + 'safe', + 'same-kind', + 'unsafe', + 'foo', + 'bar', + '', + 'beep', + 'boop' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = values[ floor( randu()*values.length ) ]; + out = isCastingMode( v ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-casting-mode/examples/index.js b/base/assert/is-casting-mode/examples/index.js new file mode 100644 index 00000000..d3c614f9 --- /dev/null +++ b/base/assert/is-casting-mode/examples/index.js @@ -0,0 +1,49 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var isCastingMode = require( './../lib' ); + +var bool = isCastingMode( 'none' ); +console.log( bool ); +// => true + +bool = isCastingMode( 'equiv' ); +console.log( bool ); +// => true + +bool = isCastingMode( 'safe' ); +console.log( bool ); +// => true + +bool = isCastingMode( 'same-kind' ); +console.log( bool ); +// => true + +bool = isCastingMode( 'unsafe' ); +console.log( bool ); +// => true + +bool = isCastingMode( '' ); +console.log( bool ); +// => false + +bool = isCastingMode( 'foo' ); +console.log( bool ); +// => false diff --git a/base/assert/is-casting-mode/test/test.js b/base/assert/is-casting-mode/test/test.js new file mode 100644 index 00000000..6fdce037 --- /dev/null +++ b/base/assert/is-casting-mode/test/test.js @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isCastingMode = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isCastingMode, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if provided a supported ndarray casting mode', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'none', + 'equiv', + 'safe', + 'same-kind', + 'unsafe' + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isCastingMode( values[ i ] ); + t.strictEqual( bool, true, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); + +tape( 'the function returns `false` if not provided a supported ndarray casting mode', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'never', + 'all-the-time', + 'always', + 'throw', + 'wrap', + 'clamp', + 'throws', + 'wraps', + 'clamps', + 'clip', + 'clips', + '', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isCastingMode( values[ i ] ); + t.strictEqual( bool, false, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/base/assert/is-column-major-contiguous/benchmark/benchmark.js b/base/assert/is-column-major-contiguous/benchmark/benchmark.js new file mode 100644 index 00000000..de09fa48 --- /dev/null +++ b/base/assert/is-column-major-contiguous/benchmark/benchmark.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var pkg = require( './../package.json' ).name; +var isColumnMajorContiguous = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var offset; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'column-major' ); + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + offset += i; + out = isColumnMajorContiguous( shape, strides, offset ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-column-major-contiguous/benchmark/c/Makefile b/base/assert/is-column-major-contiguous/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-column-major-contiguous/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-column-major-contiguous/benchmark/c/benchmark.c b/base/assert/is-column-major-contiguous/benchmark/c/benchmark.c new file mode 100644 index 00000000..7f93833d --- /dev/null +++ b/base/assert/is-column-major-contiguous/benchmark/c/benchmark.c @@ -0,0 +1,142 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_column_major_contiguous`. +*/ +#include "stdlib/ndarray/base/assert/is_column_major_contiguous.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-column-major-contiguous" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + offset += 1; + b = stdlib_ndarray_is_column_major_contiguous( STDLIB_NDARRAY_UINT8, ndims, shape, strides, offset ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-column-major-contiguous/examples/index.js b/base/assert/is-column-major-contiguous/examples/index.js new file mode 100644 index 00000000..71176306 --- /dev/null +++ b/base/assert/is-column-major-contiguous/examples/index.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var isColumnMajorContiguous = require( './../lib' ); + +var strides; +var offset; +var shape; +var bool; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + strides[ 0 ] *= discreteUniform( 1, 2 ); // if scaled by 1, then single segment + + // Compute the index offset: + offset = strides2offset( shape, strides ) + 25; // include a view offset + + // Determine if the array is column-major contiguous: + bool = isColumnMajorContiguous( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Contiguous: %s.', shape.join( 'x' ), strides.join( ',' ), offset, bool ); +} diff --git a/base/assert/is-column-major-contiguous/test/test.js b/base/assert/is-column-major-contiguous/test/test.js new file mode 100644 index 00000000..01db97f9 --- /dev/null +++ b/base/assert/is-column-major-contiguous/test/test.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isColumnMajorContiguous = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isColumnMajorContiguous, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if an array is column-major contiguous', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 3, 2 ]; + strides = [ 1, 3 ]; + offset = 0; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 1, 3 ]; + offset = 999999; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -1, -3 ]; + offset = 4; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 1, 1, 1 ]; + strides = [ 1, 2, 2, 2 ]; + offset = 0; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 1, 2, 6 ]; + offset = 99999; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array is not column-major contiguous', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 99999; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, -1 ]; + offset = 1; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ -1, 3 ]; + offset = 1; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 1, -3 ]; + offset = 3; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 2 ]; + offset = 0; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 1, -2, 6 ]; + offset = 4; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 10 ]; + strides = [ 3 ]; + offset = 0; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, 2 ]; + offset = 0; + bool = isColumnMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array has 0 elements', function test( t ) { + var bool = isColumnMajorContiguous( [ 2, 0 ], [ 0, 2 ], 0 ); + t.strictEqual( bool, false, 'returns expected value' ); + t.end(); +}); diff --git a/base/assert/is-column-major/benchmark/benchmark.js b/base/assert/is-column-major/benchmark/benchmark.js new file mode 100644 index 00000000..27d75d3b --- /dev/null +++ b/base/assert/is-column-major/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var isColumnMajor = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + strides = shape2strides( shape, 'column-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = isColumnMajor( strides ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-column-major/benchmark/c/Makefile b/base/assert/is-column-major/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-column-major/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-column-major/benchmark/c/benchmark.c b/base/assert/is-column-major/benchmark/c/benchmark.c new file mode 100644 index 00000000..deaa5e1a --- /dev/null +++ b/base/assert/is-column-major/benchmark/c/benchmark.c @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_column_major`. +*/ +#include "stdlib/ndarray/base/assert/is_column_major.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-column-major" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t ndims = 3; + int64_t strides[] = { 1, 10, 100 }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 2 ] *= ( rand_double() < 0.5 ) ? -1 : 1; + b = stdlib_ndarray_is_column_major( ndims, strides ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-column-major/examples/index.js b/base/assert/is-column-major/examples/index.js new file mode 100644 index 00000000..ffeeffac --- /dev/null +++ b/base/assert/is-column-major/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var isColumnMajor = require( './../lib' ); + +var shape = [ 10, 10, 10 ]; + +var strides = shape2strides( shape, 'column-major' ); +console.log( 'Strides: %s', strides.join( ',' ) ); +// => Strides: 1,10,100 + +var bool = isColumnMajor( strides ); +console.log( bool ); +// => true + +strides = shape2strides( shape, 'row-major' ); +console.log( 'Strides: %s', strides.join( ',' ) ); +// => Strides: 100,10,1 + +bool = isColumnMajor( strides ); +console.log( bool ); +// => false diff --git a/base/assert/is-column-major/test/test.js b/base/assert/is-column-major/test/test.js new file mode 100644 index 00000000..e0d1cf99 --- /dev/null +++ b/base/assert/is-column-major/test/test.js @@ -0,0 +1,94 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isColumnMajor = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isColumnMajor, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a boolean indicating if an array is column-major based on a provided stride array', function test( t ) { + var strides; + var bool; + + strides = [ 2, 1 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ -2, 1 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ 2, -1 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ -2, -1 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ 1, 3 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -1, 3 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, -3 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -1, -3 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, 2, 2, 2 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, 2, 2, 2 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, 10, 30 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, -10, 30 ]; + bool = isColumnMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if provided an empty stride array', function test( t ) { + var bool = isColumnMajor( [] ); + t.strictEqual( bool, false, 'returns expected value' ); + t.end(); +}); diff --git a/base/assert/is-contiguous/benchmark/benchmark.js b/base/assert/is-contiguous/benchmark/benchmark.js new file mode 100644 index 00000000..03adc244 --- /dev/null +++ b/base/assert/is-contiguous/benchmark/benchmark.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var pkg = require( './../package.json' ).name; +var isContiguous = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var offset; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + offset += i; + out = isContiguous( shape, strides, offset ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-contiguous/benchmark/c/Makefile b/base/assert/is-contiguous/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-contiguous/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-contiguous/benchmark/c/benchmark.c b/base/assert/is-contiguous/benchmark/c/benchmark.c new file mode 100644 index 00000000..346293b4 --- /dev/null +++ b/base/assert/is-contiguous/benchmark/c/benchmark.c @@ -0,0 +1,142 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_contiguous`. +*/ +#include "stdlib/ndarray/base/assert/is_contiguous.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-contiguous" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + offset += 1; + b = stdlib_ndarray_is_contiguous( STDLIB_NDARRAY_UINT8, ndims, shape, strides, offset ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-contiguous/examples/index.js b/base/assert/is-contiguous/examples/index.js new file mode 100644 index 00000000..103c0916 --- /dev/null +++ b/base/assert/is-contiguous/examples/index.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var isContiguous = require( './../lib' ); + +var strides; +var offset; +var shape; +var bool; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + strides[ 0 ] *= discreteUniform( 1, 2 ); // if scaled by 1, then single segment + + // Compute the index offset: + offset = strides2offset( shape, strides ) + 25; // include a view offset + + // Determine if the array is contiguous: + bool = isContiguous( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Contiguous: %s.', shape.join( 'x' ), strides.join( ',' ), offset, bool ); +} diff --git a/base/assert/is-contiguous/examples/types/test.ts b/base/assert/is-contiguous/examples/types/test.ts new file mode 100644 index 00000000..dc4ac08f --- /dev/null +++ b/base/assert/is-contiguous/examples/types/test.ts @@ -0,0 +1,76 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +import maxViewBufferIndex = require( '@stdlib/ndarray/base/assert/is-contiguous/docs/types' ); + + +// TESTS // + +// The function returns a number... +{ + maxViewBufferIndex( [ 10, 10 ], [ 10, 1 ], 10 ); // $ExpectType number +} + +// The function does not compile if provided a first argument which is not an array-like object containing numbers... +{ + const strides = [ 10, 1 ]; + const offset = 10; + maxViewBufferIndex( true, strides, offset ); // $ExpectError + maxViewBufferIndex( false, strides, offset ); // $ExpectError + maxViewBufferIndex( null, strides, offset ); // $ExpectError + maxViewBufferIndex( undefined, strides, offset ); // $ExpectError + maxViewBufferIndex( '5', strides, offset ); // $ExpectError + maxViewBufferIndex( [ '1', '2' ], strides, offset ); // $ExpectError + maxViewBufferIndex( {}, strides, offset ); // $ExpectError + maxViewBufferIndex( ( x: number ): number => x, strides, offset ); // $ExpectError +} + +// The function does not compile if provided a second argument which is not an array-like object containing numbers... +{ + const shape = [ 10, 10 ]; + const offset = 10; + maxViewBufferIndex( shape, true, offset ); // $ExpectError + maxViewBufferIndex( shape, false, offset ); // $ExpectError + maxViewBufferIndex( shape, null, offset ); // $ExpectError + maxViewBufferIndex( shape, undefined, offset ); // $ExpectError + maxViewBufferIndex( shape, '5', offset ); // $ExpectError + maxViewBufferIndex( shape, [ '1', '2' ], offset ); // $ExpectError + maxViewBufferIndex( shape, {}, offset ); // $ExpectError + maxViewBufferIndex( shape, ( x: number ): number => x, offset ); // $ExpectError +} + +// The function does not compile if provided a third argument which is not a number... +{ + const shape = [ 10, 10 ]; + const strides = [ 10, 1 ]; + maxViewBufferIndex( shape, strides, true ); // $ExpectError + maxViewBufferIndex( shape, strides, false ); // $ExpectError + maxViewBufferIndex( shape, strides, null ); // $ExpectError + maxViewBufferIndex( shape, strides, undefined ); // $ExpectError + maxViewBufferIndex( shape, strides, '5' ); // $ExpectError + maxViewBufferIndex( shape, strides, [ '1', '2' ] ); // $ExpectError + maxViewBufferIndex( shape, strides, {} ); // $ExpectError + maxViewBufferIndex( shape, strides, ( x: number ): number => x ); // $ExpectError +} + +// The function does not compile if provided insufficient arguments... +{ + maxViewBufferIndex(); // $ExpectError + maxViewBufferIndex( [ 10, 10 ] ); // $ExpectError + maxViewBufferIndex( [ 10, 10 ], [ 10, 1 ] ); // $ExpectError +} diff --git a/base/assert/is-contiguous/test/test.js b/base/assert/is-contiguous/test/test.js new file mode 100644 index 00000000..39156044 --- /dev/null +++ b/base/assert/is-contiguous/test/test.js @@ -0,0 +1,147 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isContiguous = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isContiguous, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if an array is contiguous', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 99999; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 1, 3 ]; + offset = 0; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -1, -3 ]; + offset = 4; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 1 ]; + offset = 0; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, 10, 1 ]; + offset = 99999; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array is not contiguous', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, -1 ]; + offset = 1; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ -1, 3 ]; + offset = 1; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 1, -3 ]; + offset = 3; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 2 ]; + offset = 0; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, -10, 1 ]; + offset = 20; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 10 ]; + strides = [ 3 ]; + offset = 0; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, 2 ]; + offset = 0; + bool = isContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array has 0 elements', function test( t ) { + var bool = isContiguous( [ 2, 0 ], [ 2, 0 ], 0 ); + t.strictEqual( bool, false, 'returns expected value' ); + t.end(); +}); diff --git a/base/assert/is-data-type/benchmark/benchmark.js b/base/assert/is-data-type/benchmark/benchmark.js new file mode 100644 index 00000000..fd3dfb60 --- /dev/null +++ b/base/assert/is-data-type/benchmark/benchmark.js @@ -0,0 +1,72 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var isDataType = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var v; + var i; + + values = [ + 'binary', + 'float32', + 'float64', + 'generic', + 'int16', + 'int32', + 'int8', + 'uint16', + 'uint32', + 'uint8', + 'uint8c', + 'foo', + 'bar', + '', + 'beep', + 'boop' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = values[ floor( randu()*values.length ) ]; + out = isDataType( v ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-data-type/examples/index.js b/base/assert/is-data-type/examples/index.js new file mode 100644 index 00000000..18058a9c --- /dev/null +++ b/base/assert/is-data-type/examples/index.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var isDataType = require( './../lib' ); + +var bool = isDataType( 'binary' ); +console.log( bool ); +// => true + +bool = isDataType( 'float32' ); +console.log( bool ); +// => true + +bool = isDataType( 'float64' ); +console.log( bool ); +// => true + +bool = isDataType( 'generic' ); +console.log( bool ); +// => true + +bool = isDataType( 'int16' ); +console.log( bool ); +// => true + +bool = isDataType( 'int32' ); +console.log( bool ); +// => true + +bool = isDataType( 'int8' ); +console.log( bool ); +// => true + +bool = isDataType( 'uint16' ); +console.log( bool ); +// => true + +bool = isDataType( 'uint32' ); +console.log( bool ); +// => true + +bool = isDataType( 'uint8' ); +console.log( bool ); +// => true + +bool = isDataType( 'uint8c' ); +console.log( bool ); +// => true + +bool = isDataType( '' ); +console.log( bool ); +// => false + +bool = isDataType( 'foo' ); +console.log( bool ); +// => false diff --git a/base/assert/is-data-type/test/test.js b/base/assert/is-data-type/test/test.js new file mode 100644 index 00000000..7cee6760 --- /dev/null +++ b/base/assert/is-data-type/test/test.js @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isDataType = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isDataType, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if provided a supported ndarray data type', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'binary', + 'complex64', + 'complex128', + 'float32', + 'float64', + 'generic', + 'int16', + 'int32', + 'int8', + 'uint16', + 'uint32', + 'uint8', + 'uint8c' + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isDataType( values[ i ] ); + t.strictEqual( bool, true, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); + +tape( 'the function returns `false` if not provided a supported ndarray data type', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'float', + 'int', + 'bin', + '', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isDataType( values[ i ] ); + t.strictEqual( bool, false, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/base/assert/is-index-mode/benchmark/benchmark.js b/base/assert/is-index-mode/benchmark/benchmark.js new file mode 100644 index 00000000..59663de7 --- /dev/null +++ b/base/assert/is-index-mode/benchmark/benchmark.js @@ -0,0 +1,64 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var isIndexMode = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var v; + var i; + + values = [ + 'throw', + 'wrap', + 'clamp', + 'foo', + 'bar', + '', + 'beep', + 'boop' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = values[ floor( randu()*values.length ) ]; + out = isIndexMode( v ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-index-mode/examples/index.js b/base/assert/is-index-mode/examples/index.js new file mode 100644 index 00000000..1bce8b6a --- /dev/null +++ b/base/assert/is-index-mode/examples/index.js @@ -0,0 +1,41 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var isIndexMode = require( './../lib' ); + +var bool = isIndexMode( 'throw' ); +console.log( bool ); +// => true + +bool = isIndexMode( 'wrap' ); +console.log( bool ); +// => true + +bool = isIndexMode( 'clamp' ); +console.log( bool ); +// => true + +bool = isIndexMode( '' ); +console.log( bool ); +// => false + +bool = isIndexMode( 'foo' ); +console.log( bool ); +// => false diff --git a/base/assert/is-index-mode/test/test.js b/base/assert/is-index-mode/test/test.js new file mode 100644 index 00000000..9aef569d --- /dev/null +++ b/base/assert/is-index-mode/test/test.js @@ -0,0 +1,83 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isIndexMode = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isIndexMode, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if provided a supported ndarray index mode', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'throw', + 'wrap', + 'clamp' + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isIndexMode( values[ i ] ); + t.strictEqual( bool, true, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); + +tape( 'the function returns `false` if not provided a supported ndarray index mode', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'throws', + 'wraps', + 'clamps', + 'clip', + 'clips', + '', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isIndexMode( values[ i ] ); + t.strictEqual( bool, false, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/base/assert/is-order/benchmark/benchmark.js b/base/assert/is-order/benchmark/benchmark.js new file mode 100644 index 00000000..9dce62a9 --- /dev/null +++ b/base/assert/is-order/benchmark/benchmark.js @@ -0,0 +1,65 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var isOrder = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var v; + var i; + + values = [ + 'row-major', + 'column-major', + 'c', + 'fortran', + 'foo', + 'bar', + '', + 'beep', + 'boop' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = values[ floor( randu()*values.length ) ]; + out = isOrder( v ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-order/examples/index.js b/base/assert/is-order/examples/index.js new file mode 100644 index 00000000..463f5b8f --- /dev/null +++ b/base/assert/is-order/examples/index.js @@ -0,0 +1,37 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var isOrder = require( './../lib' ); + +var bool = isOrder( 'row-major' ); +console.log( bool ); +// => true + +bool = isOrder( 'column-major' ); +console.log( bool ); +// => true + +bool = isOrder( '' ); +console.log( bool ); +// => false + +bool = isOrder( 'foo' ); +console.log( bool ); +// => false diff --git a/base/assert/is-order/test/test.js b/base/assert/is-order/test/test.js new file mode 100644 index 00000000..3a74f1f0 --- /dev/null +++ b/base/assert/is-order/test/test.js @@ -0,0 +1,81 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isOrder = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isOrder, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if provided an ndarray order', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'row-major', + 'column-major' + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isOrder( values[ i ] ); + t.strictEqual( bool, true, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); + +tape( 'the function returns `false` if not provided an ndarray order', function test( t ) { + var values; + var bool; + var i; + + values = [ + 'c', + 'fortran', + 'c-style', + 'fortran-style', + '', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + bool = isOrder( values[ i ] ); + t.strictEqual( bool, false, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/base/assert/is-row-major-contiguous/benchmark/benchmark.js b/base/assert/is-row-major-contiguous/benchmark/benchmark.js new file mode 100644 index 00000000..562f5ac2 --- /dev/null +++ b/base/assert/is-row-major-contiguous/benchmark/benchmark.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var pkg = require( './../package.json' ).name; +var isRowMajorContiguous = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var offset; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + offset += i; + out = isRowMajorContiguous( shape, strides, offset ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-row-major-contiguous/benchmark/c/Makefile b/base/assert/is-row-major-contiguous/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-row-major-contiguous/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-row-major-contiguous/benchmark/c/benchmark.c b/base/assert/is-row-major-contiguous/benchmark/c/benchmark.c new file mode 100644 index 00000000..8df7af67 --- /dev/null +++ b/base/assert/is-row-major-contiguous/benchmark/c/benchmark.c @@ -0,0 +1,142 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_row_major_contiguous`. +*/ +#include "stdlib/ndarray/base/assert/is_row_major_contiguous.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-row-major-contiguous" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + offset += 1; + b = stdlib_ndarray_is_row_major_contiguous( STDLIB_NDARRAY_UINT8, ndims, shape, strides, offset ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-row-major-contiguous/examples/index.js b/base/assert/is-row-major-contiguous/examples/index.js new file mode 100644 index 00000000..872e20a6 --- /dev/null +++ b/base/assert/is-row-major-contiguous/examples/index.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var isRowMajorContiguous = require( './../lib' ); + +var strides; +var offset; +var shape; +var bool; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + strides[ 0 ] *= discreteUniform( 1, 2 ); // if scaled by 1, then single segment + + // Compute the index offset: + offset = strides2offset( shape, strides ) + 25; // include a view offset + + // Determine if the array is row-major contiguous: + bool = isRowMajorContiguous( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Contiguous: %s.', shape.join( 'x' ), strides.join( ',' ), offset, bool ); +} diff --git a/base/assert/is-row-major-contiguous/test/test.js b/base/assert/is-row-major-contiguous/test/test.js new file mode 100644 index 00000000..8c173db1 --- /dev/null +++ b/base/assert/is-row-major-contiguous/test/test.js @@ -0,0 +1,147 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isRowMajorContiguous = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isRowMajorContiguous, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if an array is row-major contiguous', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 99999; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 1 ]; + offset = 0; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, 10, 1 ]; + offset = 99999; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array is not row-major contiguous', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, -1 ]; + offset = 1; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 1, 3 ]; + offset = 0; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -1, -3 ]; + offset = 4; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ -1, 3 ]; + offset = 1; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 1, -3 ]; + offset = 3; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 2 ]; + offset = 0; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, -10, 1 ]; + offset = 20; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 10 ]; + strides = [ 3 ]; + offset = 0; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, 2 ]; + offset = 0; + bool = isRowMajorContiguous( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array has 0 elements', function test( t ) { + var bool = isRowMajorContiguous( [ 2, 0 ], [ 2, 0 ], 0 ); + t.strictEqual( bool, false, 'returns expected value' ); + t.end(); +}); diff --git a/base/assert/is-row-major/benchmark/benchmark.js b/base/assert/is-row-major/benchmark/benchmark.js new file mode 100644 index 00000000..6326e032 --- /dev/null +++ b/base/assert/is-row-major/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var isRowMajor = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = isRowMajor( strides ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-row-major/benchmark/c/Makefile b/base/assert/is-row-major/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-row-major/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-row-major/benchmark/c/benchmark.c b/base/assert/is-row-major/benchmark/c/benchmark.c new file mode 100644 index 00000000..090dd37a --- /dev/null +++ b/base/assert/is-row-major/benchmark/c/benchmark.c @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_row_major`. +*/ +#include "stdlib/ndarray/base/assert/is_row_major.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-row-major" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t ndims = 3; + int64_t strides[] = { 100, 10, 1 }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 2 ] *= ( rand_double() < 0.5 ) ? -1 : 1; + b = stdlib_ndarray_is_row_major( ndims, strides ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-row-major/examples/index.js b/base/assert/is-row-major/examples/index.js new file mode 100644 index 00000000..13e6c0bc --- /dev/null +++ b/base/assert/is-row-major/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var isRowMajor = require( './../lib' ); + +var shape = [ 10, 10, 10 ]; + +var strides = shape2strides( shape, 'row-major' ); +console.log( 'Strides: %s', strides.join( ',' ) ); +// => Strides: 100,10,1 + +var bool = isRowMajor( strides ); +console.log( bool ); +// => true + +strides = shape2strides( shape, 'column-major' ); +console.log( 'Strides: %s', strides.join( ',' ) ); +// => Strides: 1,10,100 + +bool = isRowMajor( strides ); +console.log( bool ); +// => false diff --git a/base/assert/is-row-major/test/test.js b/base/assert/is-row-major/test/test.js new file mode 100644 index 00000000..b2d2ede6 --- /dev/null +++ b/base/assert/is-row-major/test/test.js @@ -0,0 +1,94 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isRowMajor = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isRowMajor, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a boolean indicating if an array is row-major based on a provided stride array', function test( t ) { + var strides; + var bool; + + strides = [ 2, 1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -2, 1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, -1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -2, -1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, 3 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ -1, 3 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ 1, -3 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ -1, -3 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, false, 'returns expected value' ); + + strides = [ 2, 2, 2, 1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, 2, 2, 2 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 30, 10, 1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 30, -10, 1 ]; + bool = isRowMajor( strides ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if provided an empty stride array', function test( t ) { + var bool = isRowMajor( [] ); + t.strictEqual( bool, false, 'returns expected value' ); + t.end(); +}); diff --git a/base/assert/is-safe-data-type-cast/benchmark/benchmark.js b/base/assert/is-safe-data-type-cast/benchmark/benchmark.js new file mode 100644 index 00000000..a9dd46c0 --- /dev/null +++ b/base/assert/is-safe-data-type-cast/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var isSafeCast = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isSafeCast( DTYPES[ j ], DTYPES[ k ] ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-safe-data-type-cast/benchmark/c/Makefile b/base/assert/is-safe-data-type-cast/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-safe-data-type-cast/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-safe-data-type-cast/benchmark/c/benchmark.c b/base/assert/is-safe-data-type-cast/benchmark/c/benchmark.c new file mode 100644 index 00000000..99a6cb52 --- /dev/null +++ b/base/assert/is-safe-data-type-cast/benchmark/c/benchmark.c @@ -0,0 +1,136 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_safe_data_type_cast`. +*/ +#include "stdlib/ndarray/base/assert/is_safe_data_type_cast.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-safe-data-type-cast" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + b = stdlib_ndarray_is_safe_data_type_cast( i%STDLIB_NDARRAY_NDTYPES, (i%STDLIB_NDARRAY_NDTYPES)+1 ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-safe-data-type-cast/examples/index.js b/base/assert/is-safe-data-type-cast/examples/index.js new file mode 100644 index 00000000..f5153a4e --- /dev/null +++ b/base/assert/is-safe-data-type-cast/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isSafeCast = require( './../lib' ); + +var DTYPES; +var bool; +var dt; +var i; +var j; + +// Get a list of supported ndarray data types: +DTYPES = dtypes(); + +// For each data type, determine whether one can safely cast to another data type... +for ( i = 0; i < DTYPES.length; i++ ) { + dt = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + bool = isSafeCast( dt, DTYPES[ j ] ); + console.log( '%s => %s. Safe? %s.', dt, DTYPES[ j ], bool ); + } +} diff --git a/base/assert/is-safe-data-type-cast/test/test.js b/base/assert/is-safe-data-type-cast/test/test.js new file mode 100644 index 00000000..cb56a95b --- /dev/null +++ b/base/assert/is-safe-data-type-cast/test/test.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var safeCasts = require( '@stdlib/ndarray/safe-casts' ); +var isSafeCast = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); +var SAFE_CASTS = safeCasts(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isSafeCast, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be safely cast to another ndarray data type', function test( t ) { + var expected; + var actual; + var dt; + var i; + var j; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + expected = ( SAFE_CASTS[ dt ][ DTYPES[j] ] > 0 ); + actual = isSafeCast( dt, DTYPES[ j ] ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt+'. to: '+DTYPES[j]+'.' ); + } + } + t.end(); +}); diff --git a/base/assert/is-same-kind-data-type-cast/benchmark/benchmark.js b/base/assert/is-same-kind-data-type-cast/benchmark/benchmark.js new file mode 100644 index 00000000..a8e2cf7b --- /dev/null +++ b/base/assert/is-same-kind-data-type-cast/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var isSameKindCast = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var N; + var i; + var j; + var k; + + N = DTYPES.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = isSameKindCast( DTYPES[ j ], DTYPES[ k ] ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-same-kind-data-type-cast/benchmark/c/Makefile b/base/assert/is-same-kind-data-type-cast/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-same-kind-data-type-cast/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-same-kind-data-type-cast/benchmark/c/benchmark.c b/base/assert/is-same-kind-data-type-cast/benchmark/c/benchmark.c new file mode 100644 index 00000000..14830927 --- /dev/null +++ b/base/assert/is-same-kind-data-type-cast/benchmark/c/benchmark.c @@ -0,0 +1,136 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_same_kind_data_type_cast`. +*/ +#include "stdlib/ndarray/base/assert/is_same_kind_data_type_cast.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-same-kind-data-type-cast" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + b = stdlib_ndarray_is_same_kind_data_type_cast( i%STDLIB_NDARRAY_NDTYPES, (i%STDLIB_NDARRAY_NDTYPES)+1 ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-same-kind-data-type-cast/examples/index.js b/base/assert/is-same-kind-data-type-cast/examples/index.js new file mode 100644 index 00000000..a11cab50 --- /dev/null +++ b/base/assert/is-same-kind-data-type-cast/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isSameKindCast = require( './../lib' ); + +var DTYPES; +var bool; +var dt; +var i; +var j; + +// Get a list of supported ndarray data types: +DTYPES = dtypes(); + +// For each data type, determine whether one can cast to another data type... +for ( i = 0; i < DTYPES.length; i++ ) { + dt = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + bool = isSameKindCast( dt, DTYPES[ j ] ); + console.log( '%s => %s. Allowed cast? %s.', dt, DTYPES[ j ], bool ); + } +} diff --git a/base/assert/is-same-kind-data-type-cast/test/test.js b/base/assert/is-same-kind-data-type-cast/test/test.js new file mode 100644 index 00000000..3966031a --- /dev/null +++ b/base/assert/is-same-kind-data-type-cast/test/test.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var sameKindCasts = require( '@stdlib/ndarray/same-kind-casts' ); +var isSameKindCast = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); +var SAME_KIND_CASTS = sameKindCasts(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isSameKindCast, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a boolean indicating if an ndarray data type can be cast to another ndarray data type', function test( t ) { + var expected; + var actual; + var dt; + var i; + var j; + + for ( i = 0; i < DTYPES.length; i++ ) { + dt = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + expected = ( SAME_KIND_CASTS[ dt ][ DTYPES[j] ] > 0 ); + actual = isSameKindCast( dt, DTYPES[ j ] ); + t.strictEqual( actual, expected, 'returns expected value. from: '+dt+'. to: '+DTYPES[j]+'.' ); + } + } + t.end(); +}); diff --git a/base/assert/is-single-segment-compatible/benchmark/benchmark.js b/base/assert/is-single-segment-compatible/benchmark/benchmark.js new file mode 100644 index 00000000..088511e8 --- /dev/null +++ b/base/assert/is-single-segment-compatible/benchmark/benchmark.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var pkg = require( './../package.json' ).name; +var isSingleSegmentCompatible = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var offset; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + strides[ 2 ] *= -1; + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + offset += i; + out = isSingleSegmentCompatible( shape, strides, offset ); + if ( typeof out !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( out ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/assert/is-single-segment-compatible/benchmark/c/Makefile b/base/assert/is-single-segment-compatible/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/assert/is-single-segment-compatible/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/assert/is-single-segment-compatible/benchmark/c/benchmark.c b/base/assert/is-single-segment-compatible/benchmark/c/benchmark.c new file mode 100644 index 00000000..0ded46a4 --- /dev/null +++ b/base/assert/is-single-segment-compatible/benchmark/c/benchmark.c @@ -0,0 +1,142 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `is_single_segment_compatible`. +*/ +#include "stdlib/ndarray/base/assert/is_single_segment_compatible.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "is-single-segment-compatible" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t b; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + offset += 1; + b = stdlib_ndarray_is_single_segment_compatible( STDLIB_NDARRAY_UINT8, ndims, shape, strides, offset ); + if ( b != 0 && b!= 1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( b != 0 && b != 1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/assert/is-single-segment-compatible/examples/index.js b/base/assert/is-single-segment-compatible/examples/index.js new file mode 100644 index 00000000..5f836c44 --- /dev/null +++ b/base/assert/is-single-segment-compatible/examples/index.js @@ -0,0 +1,59 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var isSingleSegmentCompatible = require( './../lib' ); + +var strides; +var offset; +var shape; +var bool; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + strides[ 0 ] *= discreteUniform( 1, 4 ); // if scaled by 1, then single segment + + // Compute the index offset: + offset = strides2offset( shape, strides ); + + // Determine if the array is compatible with a single memory segment: + bool = isSingleSegmentCompatible( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Single segment compatible: %s.', shape.join( 'x' ), strides.join( ',' ), offset, bool ); +} diff --git a/base/assert/is-single-segment-compatible/test/test.js b/base/assert/is-single-segment-compatible/test/test.js new file mode 100644 index 00000000..559df1a5 --- /dev/null +++ b/base/assert/is-single-segment-compatible/test/test.js @@ -0,0 +1,140 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isSingleSegmentCompatible = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isSingleSegmentCompatible, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `true` if an array is compatible with a single memory segment', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 0; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, 1 ]; + offset = 99999; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 4; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 1; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 5; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, 3 ]; + offset = 0; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -1, 3 ]; + offset = 2; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ 1, -3 ]; + offset = 3; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + strides = [ -1, -3 ]; + offset = 5; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 1 ]; + offset = 0; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, 10, 1 ]; + offset = 99999; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, -10, 1 ]; + offset = 20; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array is incompatible with a single memory segment', function test( t ) { + var strides; + var offset; + var shape; + var bool; + + shape = [ 1, 1, 1, 2 ]; + strides = [ 2, 2, 2, 2 ]; + offset = 0; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 10 ]; + strides = [ 3 ]; + offset = 0; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + shape = [ 2, 2 ]; + strides = [ 2, 2 ]; + offset = 0; + bool = isSingleSegmentCompatible( shape, strides, offset ); + t.strictEqual( bool, false, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns `false` if an array has 0 elements', function test( t ) { + var bool = isSingleSegmentCompatible( [ 2, 0 ], [ 2, 0 ], 0 ); + t.strictEqual( bool, false, 'returns expected value' ); + t.end(); +}); diff --git a/base/assert/test/test.js b/base/assert/test/test.js new file mode 100644 index 00000000..14dda1f7 --- /dev/null +++ b/base/assert/test/test.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var objectKeys = require( '@stdlib/utils/keys' ); +var ns = require( './../lib' ); + + +// TESTS // + +tape( 'main export is an object', function test( t ) { + t.ok( true, __filename ); + t.equal( typeof ns, 'object', 'main export is an object' ); + t.end(); +}); + +tape( 'the exported object contains key-value pairs', function test( t ) { + var keys = objectKeys( ns ); + t.equal( keys.length > 0, true, 'has keys' ); + t.end(); +}); diff --git a/base/bind2vind/benchmark/benchmark.js b/base/bind2vind/benchmark/benchmark.js new file mode 100644 index 00000000..4a352394 --- /dev/null +++ b/base/bind2vind/benchmark/benchmark.js @@ -0,0 +1,424 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var pkg = require( './../package.json' ).name; +var bind2vind = require( './../lib' ); + + +// MAIN // + +bench( pkg+':mode=throw,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = bind2vind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = bind2vind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,offset=0,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = bind2vind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,offset=0,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = bind2vind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,offset=0,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,offset=0,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,offset=0,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,offset=0,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = bind2vind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/bind2vind/benchmark/c/Makefile b/base/bind2vind/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/bind2vind/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/bind2vind/benchmark/c/benchmark.c b/base/bind2vind/benchmark/c/benchmark.c new file mode 100644 index 00000000..ec1106df --- /dev/null +++ b/base/bind2vind/benchmark/c/benchmark.c @@ -0,0 +1,600 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `bind2vind`. +*/ +#include "stdlib/ndarray/base/bind2vind.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/index_modes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "bind2vind" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark3() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark4() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark5() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark6() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark7() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark8() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark9() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark10() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark11() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark12() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_bind2vind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=row-major\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=column-major\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=row-major,offset=0\n", NAME ); + elapsed = benchmark3(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=column-major,offset=0\n", NAME ); + elapsed = benchmark4(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=row-major\n", NAME ); + elapsed = benchmark5(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=column-major\n", NAME ); + elapsed = benchmark6(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=row-major,offset=0\n", NAME ); + elapsed = benchmark7(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=column-major,offset=0\n", NAME ); + elapsed = benchmark8(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=row-major\n", NAME ); + elapsed = benchmark9(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=column-major\n", NAME ); + elapsed = benchmark10(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=row-major,offset=0\n", NAME ); + elapsed = benchmark11(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=column-major,offset=0\n", NAME ); + elapsed = benchmark12(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/bind2vind/examples/index.js b/base/bind2vind/examples/index.js new file mode 100644 index 00000000..c120573a --- /dev/null +++ b/base/bind2vind/examples/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var randu = require( '@stdlib/random/base/randu' ); +var bind2vind = require( './../lib' ); + +// Specify array meta data: +var shape = [ 3, 3, 3 ]; +var order = 'row-major'; + +// Compute array meta data: +var len = numel( shape ); +var strides = shape2strides( shape, order ); + +// Randomly flip the sign of strides... +var i; +for ( i = 0; i < shape.length; i++ ) { + if ( randu() < 0.5 ) { + strides[ i ] *= -1; + } +} + +// Compute the underlying data buffer index offset: +var offset = strides2offset( shape, strides ); + +// Print array info: +console.log( 'Dims: %s', shape.join( 'x' ) ); +console.log( 'Strides: %s', strides.join( ',' ) ); +console.log( 'Offset: %d', offset ); + +// For each underlying data buffer index, determine the corresponding index into an array view... +var ind; +for ( i = 0; i < len; i++ ) { + ind = bind2vind( shape, strides, offset, order, i, 'throw' ); + console.log( 'buffer[%d] => view[%d]', i, ind ); +} diff --git a/base/bind2vind/test/test.js b/base/bind2vind/test/test.js new file mode 100644 index 00000000..ec4f7a71 --- /dev/null +++ b/base/bind2vind/test/test.js @@ -0,0 +1,577 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var bind2vind = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof bind2vind, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index in an underlying data buffer to a linear index in an array view (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + idx = bind2vind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + t.throws( foo, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + bind2vind( shape, strides, offset, order, 999999, 'throw' ); + } +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + t.throws( foo, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + bind2vind( shape, strides, offset, order, 999999, 'throw' ); + } +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (offset=0,order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + idx = bind2vind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + idx = bind2vind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (offset=0,order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + idx = bind2vind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + idx = bind2vind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (offset=0,order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + idx = bind2vind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + idx = bind2vind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (offset=0,order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + idx = bind2vind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + idx = bind2vind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = bind2vind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); diff --git a/base/broadcast-shapes/README.md b/base/broadcast-shapes/README.md new file mode 100644 index 00000000..2889701b --- /dev/null +++ b/base/broadcast-shapes/README.md @@ -0,0 +1,397 @@ + + +# broadcastShapes + +> Broadcast array shapes to a single shape. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var broadcastShapes = require( '@stdlib/ndarray/base/broadcast-shapes' ); +``` + +#### broadcastShapes( shapes ) + +Broadcasts array shapes to a single shape. + +```javascript +var sh1 = [ 8, 1, 6, 1 ]; +var sh2 = [ 7, 1, 5 ]; + +var sh = broadcastShapes( [ sh1, sh2 ] ); +// returns [ 8, 7, 6, 5 ] +``` + +
+ + + + + +
+ +## Notes + +- When operating on two arrays, the function compares their shapes element-wise, beginning with the trailing (i.e., rightmost) dimension. The following are examples of compatible shapes and their corresponding broadcasted shape: + + ```text + A (4d array): 8 x 1 x 6 x 1 + B (3d array): 7 x 1 x 5 + --------------------------------- + Result (4d array): 8 x 7 x 6 x 5 + + A (2d array): 5 x 4 + B (1d array): 1 + ------------------------- + Result (2d array): 5 x 4 + + A (2d array): 5 x 4 + B (1d array): 4 + ------------------------- + Result (2d array): 5 x 4 + + A (3d array): 15 x 3 x 5 + B (3d array): 15 x 1 x 5 + ------------------------------ + Result (3d array): 15 x 3 x 5 + + A (3d array): 15 x 3 x 5 + B (2d array): 3 x 5 + ------------------------------ + Result (3d array): 15 x 3 x 5 + + A (3d array): 15 x 3 x 5 + B (2d array): 3 x 1 + ------------------------------ + Result (3d array): 15 x 3 x 5 + + A (5d array): 8 x 1 x 1 x 6 x 1 + B (4d array): 1 x 7 x 1 x 5 + C (5d array): 8 x 4 x 1 x 6 x 5 + ------------------------------------- + Result (5d array): 8 x 4 x 7 x 6 x 5 + + A (5d array): 8 x 1 x 1 x 6 x 1 + B (1d array): 0 + ------------------------------------- + Result (5d array): 8 x 1 x 1 x 6 x 0 + + A (5d array): 8 x 0 x 1 x 6 x 1 + B (2d array): 6 x 5 + ------------------------------------- + Result (5d array): 8 x 0 x 1 x 6 x 5 + + A (5d array): 8 x 1 x 1 x 6 x 1 + B (5d array): 8 x 0 x 1 x 6 x 1 + ------------------------------------- + Result (5d array): 8 x 0 x 1 x 6 x 1 + + A (3d array): 3 x 2 x 1 + B (0d array): + ----------------------------- + Result (3d array): 3 x 2 x 1 + + A (0d array): + B (3d array): 3 x 2 x 1 + ----------------------------- + Result (3d array): 3 x 2 x 1 + ``` + + As demonstrated above, arrays are not required to have the same number of dimensions in order to be broadcast compatible. Array shapes with fewer dimensions are implicitly prepended with singleton dimensions (i.e., dimensions equal to `1`). Accordingly, the following example + + ```text + A (2d array): 5 x 4 + B (1d array): 4 + ------------------------- + Result (2d array): 5 x 4 + ``` + + is equivalent to + + ```text + A (2d array): 5 x 4 + B (2d array): 1 x 4 + ------------------------- + Result (2d array): 5 x 4 + ``` + + Similarly, a zero-dimensional array is expanded (by prepending singleton dimensions) from + + ```text + A (3d array): 3 x 2 x 1 + B (0d array): + ----------------------------- + Result (3d array): 3 x 2 x 1 + ``` + + to + + ```text + A (3d array): 3 x 2 x 1 + B (3d array): 1 x 1 x 1 + ----------------------------- + Result (3d array): 3 x 2 x 1 + ``` + + Stated otherwise, every array has implicit leading dimensions of size `1`. During broadcasting, a `3 x 4` matrix is the same as a `3 x 4 x 1 x 1 x 1` multidimensional array. + +- Two respective dimensions in two shape arrays are compatible if + + 1. the dimensions are equal. + 2. one dimension is `1`. + + The two aforementioned rules apply to empty arrays or arrays that have a dimension of size `0`. For unequal dimensions, the size of the dimension which is not `1` determines the size of the output shape dimension. + + Accordingly, dimensions of size `0` must be paired with a dimension of size `0` or `1`. In such cases, by the rules above, the size of the corresponding output shape dimension is `0`. + +- The function returns `null` if provided incompatible shapes (i.e., shapes which cannot be broadcast one another). + + ```javascript + var sh1 = [ 3, 2 ]; + var sh2 = [ 2, 3 ]; + + var sh = broadcastShapes( [ sh1, sh2 ] ); + // returns null + ``` + + The following are examples of array shapes which are **not** compatible and do **not** broadcast: + + ```text + A (1d array): 3 + B (1d array): 4 # dimension does not match + + A (2d array): 2 x 1 + B (3d array): 8 x 4 x 3 # second dimension does not match + + A (3d array): 15 x 3 x 5 + B (2d array): 15 x 3 # singleton dimensions can only be prepended, not appended + + A (5d array): 8 x 8 x 1 x 6 x 1 + B (5d array): 8 x 0 x 1 x 6 x 1 # second dimension does not match + ``` + +
+ + + + + +
+ +## Examples + + + +```javascript +var lpad = require( '@stdlib/string/left-pad' ); +var broadcastShapes = require( '@stdlib/ndarray/base/broadcast-shapes' ); + +var shapes; +var out; +var sh; +var i; +var j; + +function shape2string( shape ) { + return lpad( shape.join( ' x ' ), 20, ' ' ); +} + +shapes = [ + [ [ 1, 2 ], [ 2 ] ], + [ [ 1, 1 ], [ 3, 4 ] ], + [ [ 6, 7 ], [ 5, 6, 1 ], [ 7 ], [ 5, 1, 7 ] ], + [ [ 1, 3 ], [ 3, 1 ] ], + [ [ 1 ], [ 3 ] ], + [ [ 2 ], [ 3, 2 ] ], + [ [ 2, 3 ], [ 2, 3 ], [ 2, 3 ], [ 2, 3 ] ], + [ [ 1, 2 ], [ 1, 2 ] ] +]; + +for ( i = 0; i < shapes.length; i++ ) { + sh = shapes[ i ]; + for ( j = 0; j < sh.length; j++ ) { + console.log( shape2string( sh[ j ] ) ); + } + console.log( lpad( '', 20, '-' ) ); + + out = broadcastShapes( sh ); + console.log( shape2string( out )+'\n' ); +} +``` + +
+ + + + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/ndarray/base/broadcast_shapes.h" +``` + +#### stdlib_ndarray_broadcast_shapes( M, \*\*shapes, \*ndims, \*out ) + +Broadcasts array shapes to a single shape. + +```c +#include "stdlib/ndarray/base/broadcast_shapes.h" +#include + +int64_t N1 = 4; +int64_t sh1[] = { 8, 1, 6, 1 }; + +int64_t N2 = 3; +int64_t sh2[] = { 7, 1, 5 }; + +int64_t ndims[] = { N1, N2 }; +int64_t *shapes[] = { sh1, sh2 }; + +int64_t out[] = { 0, 0, 0, 0 }; +int8_t status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out ); +if ( status != 0 ) { + // Handle error... +} +``` + +The function accepts the following arguments: + +- **M**: `[in] int64_t` number of shape arrays. +- **shapes**: `[in] int64_t**` array of shape arrays (dimensions). +- **ndims**: `[in] int64_t*` number of dimensions for each respective shape array. +- **out**: `[out] int64_t*` output shape array. + +```c +int8_t stdlib_ndarray_broadcast_shapes( int64_t M, int64_t *shapes[], int64_t ndims[], int64_t *out ); +``` + +If successful, the function returns `0`; otherwise, the function returns `-1` (e.g., due to incompatible shapes). + +
+ + + + + +
+ +### Notes + +- Even if the function is unsuccessful, the function may still overwrite elements in the output array before returning. In other words, do not assume that providing incompatible shapes is a no-op with regard to the output array. + +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/ndarray/base/broadcast_shapes.h" +#include +#include + +int main() { + int64_t N1 = 4; + int64_t sh1[] = { 8, 1, 6, 1 }; + + int64_t N2 = 3; + int64_t sh2[] = { 7, 1, 5 }; + + int64_t ndims[] = { N1, N2 }; + int64_t *shapes[] = { sh1, sh2 }; + + int64_t out[] = { 0, 0, 0, 0 }; + int8_t status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out ); + if ( status != 0 ) { + printf( "incompatible shapes\n" ); + return 1; + } + int64_t i; + printf( "shape = ( " ); + for ( i = 0; i < N1; i++ ) { + printf( "%lli", out[ i ] ); + if ( i < N1-1 ) { + printf( ", " ); + } + } + printf( " )\n" ); + return 0; +} +``` + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + diff --git a/base/broadcast-shapes/benchmark/benchmark.js b/base/broadcast-shapes/benchmark/benchmark.js new file mode 100644 index 00000000..fa610dc6 --- /dev/null +++ b/base/broadcast-shapes/benchmark/benchmark.js @@ -0,0 +1,112 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pkg = require( './../package.json' ).name; +var broadcastShapes = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::two_shapes', function benchmark( b ) { + var values; + var out; + var i; + + values = [ + [ [ 8, 1, 6, 1 ], [ 7, 1, 5 ] ], + [ [ 3, 2 ], [ 3, 1 ] ], + [ [ 1, 1 ], [ 2, 2 ] ], + [ [ 1 ], [ 7 ] ], + [ [ 1, 1, 1, 1, 1 ], [ 5, 5, 5, 5, 5 ] ] + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = broadcastShapes( values[ i%values.length ] ); + if ( out === null || out[ out.length-1 ] !== out[ out.length-1 ] ) { + b.fail( 'something went wrong' ); + } + } + b.toc(); + if ( out === null || out[ out.length-1 ] !== out[ out.length-1 ] ) { + b.fail( 'something went wrong' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::three_shapes', function benchmark( b ) { + var values; + var out; + var i; + + values = [ + [ [ 8, 1, 6, 1 ], [ 7, 1, 5 ], [ 1, 1 ] ], + [ [ 3, 2 ], [ 3, 1 ], [ 3, 2 ] ], + [ [ 1, 1 ], [ 2, 2 ], [ 2, 1, 2 ] ], + [ [ 1 ], [ 7 ], [ 7 ] ], + [ [ 1, 1, 1, 1, 1 ], [ 5, 5, 5, 5, 5 ], [ 5 ] ] + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = broadcastShapes( values[ i%values.length ] ); + if ( out === null || out[ out.length-1 ] !== out[ out.length-1 ] ) { + b.fail( 'something went wrong' ); + } + } + b.toc(); + if ( out === null || out[ out.length-1 ] !== out[ out.length-1 ] ) { + b.fail( 'something went wrong' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::four_shapes', function benchmark( b ) { + var values; + var out; + var i; + + values = [ + [ [ 8, 1, 6, 1 ], [ 7, 1, 5 ], [ 1, 1 ], [ 8, 1, 1, 1 ] ], + [ [ 3, 2 ], [ 3, 1 ], [ 3, 2 ], [ 1, 3, 2 ] ], + [ [ 1, 1 ], [ 2, 2 ], [ 2, 1, 2 ], [ 1, 1, 2, 2 ] ], + [ [ 1 ], [ 7 ], [ 7 ], [ 1 ] ], + [ [ 1, 1, 1, 1, 1 ], [ 5, 5, 5, 5, 5 ], [ 5 ], [ 5, 1, 5 ] ] + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = broadcastShapes( values[ i%values.length ] ); + if ( out === null || out[ out.length-1 ] !== out[ out.length-1 ] ) { + b.fail( 'something went wrong' ); + } + } + b.toc(); + if ( out === null || out[ out.length-1 ] !== out[ out.length-1 ] ) { + b.fail( 'something went wrong' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/broadcast-shapes/benchmark/c/Makefile b/base/broadcast-shapes/benchmark/c/Makefile new file mode 100644 index 00000000..5dc545c4 --- /dev/null +++ b/base/broadcast-shapes/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/broadcast-shapes/benchmark/c/benchmark.c b/base/broadcast-shapes/benchmark/c/benchmark.c new file mode 100644 index 00000000..be62cd57 --- /dev/null +++ b/base/broadcast-shapes/benchmark/c/benchmark.c @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/** +* Benchmark `broadcast_shapes`. +*/ +#include "stdlib/ndarray/base/broadcast_shapes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "broadcast-shapes" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t status; + double t; + int i; + + int64_t sh1[] = { 8, 1, 6, 1 }; + int64_t sh2[] = { 7, 1, 5 }; + + int64_t ndims[] = { 4, 3 }; + int64_t *shapes[] = { sh1, sh2 }; + + int64_t out[] = { 0, 0, 0, 0 }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out ); + if ( status != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( out[ 0 ] != 8 ) { + printf( "unexpected result\n" ); + } + if ( out[ 1 ] != 7 ) { + printf( "unexpected result\n" ); + } + if ( out[ 2 ] != 6 ) { + printf( "unexpected result\n" ); + } + if ( out[ 3 ] != 5 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s::two_arrays\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/broadcast-shapes/docs/repl.txt b/base/broadcast-shapes/docs/repl.txt new file mode 100644 index 00000000..30a81c49 --- /dev/null +++ b/base/broadcast-shapes/docs/repl.txt @@ -0,0 +1,39 @@ + +{{alias}}( shapes ) + Broadcasts array shapes to a single shape. + + Two respective dimensions in two shape arrays are compatible if + + 1. the dimensions are equal. + 2. one dimension is `1`. + + The function returns `null` if provided incompatible shapes (i.e., shapes + which cannot be broadcast one another). + + Parameters + ---------- + shapes: Array + Array of shape arrays. + + Returns + ------- + out: Array + Broadcast shape. + + Examples + -------- + // Compatible shapes: + > var sh1 = [ 8, 1, 6, 1 ]; + > var sh2 = [ 7, 1, 5 ]; + > var sh = {{alias}}( [ sh1, sh2 ] ) + [ 8, 7, 6, 5 ] + + // Incompatible shapes: + > sh1 = [ 3, 2 ]; + > sh1 = [ 2, 3 ]; + > sh = {{alias}}( [ sh1, sh2 ] ) + null + + See Also + -------- + diff --git a/base/broadcast-shapes/docs/types/index.d.ts b/base/broadcast-shapes/docs/types/index.d.ts new file mode 100644 index 00000000..ae9ee0fa --- /dev/null +++ b/base/broadcast-shapes/docs/types/index.d.ts @@ -0,0 +1,177 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +// TypeScript Version: 2.0 + +/// + +import { ArrayLike } from '@stdlib/types/array'; + +/** +* Broadcasts array shapes to a single shape. +* +* ## Notes +* +* - Two respective dimensions in two shape arrays are compatible if +* +* 1. the dimensions are equal. +* 2. one dimension is `1`. +* +* - The function returns `null` if provided incompatible shapes (i.e., shapes which cannot be broadcast one another). +* +* @param shapes - array shapes +* @returns broadcast shape +* +* @example +* var shapes = [ +* [ 8, 1, 6, 1 ], +* [ 7, 1, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 7, 6, 5 ] +* +* @example +* var shapes = [ +* [ 5, 4 ], +* [ 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 5, 4 ] +* +* @example +* var shapes = [ +* [ 5, 4 ], +* [ 4 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 5, 4 ] +* +* @example +* var shapes = [ +* [ 15, 3, 5 ], +* [ 15, 1, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 15, 3, 5 ] +* +* @example +* var shapes = [ +* [ 15, 3, 5 ], +* [ 3, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 15, 3, 5 ] +* +* @example +* var shapes = [ +* [ 15, 3, 5 ], +* [ 3, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 15, 3, 5 ] +* +* @example +* var shapes = [ +* [ 8, 1, 1, 6, 1 ], +* [ 1, 7, 1, 5 ], +* [ 8, 4, 1, 6, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 4, 7, 6, 5 ] +* +* @example +* var shapes = [ +* [ 8, 1, 1, 6, 1 ], +* [ 0 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 1, 1, 6, 0 ] +* +* @example +* var shapes = [ +* [ 8, 1, 1, 6, 1 ], +* [ 8, 0, 1, 6, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 0, 1, 6, 1 ] +* +* @example +* var shapes = [ +* [ 8, 8, 1, 6, 1 ], +* [ 8, 0, 1, 6, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns null +* +* @example +* var shapes = [ +* [] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [] +* +* @example +* var shapes = [ +* [], +* [] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [] +* +* @example +* var shapes = []; +* +* var out = broadcastShapes( shapes ); +* // returns [] +* +* @example +* var shapes = [ +* [ 3, 2, 1 ], +* [] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 3, 2, 1 ] +* +* @example +* var shapes = [ +* [], +* [ 3, 2, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 3, 2, 1 ] +*/ +declare function broadcastShapes( shapes: ArrayLike> ): ArrayLike; // tslint:disable-line:max-line-length + + +// EXPORTS // + +export = broadcastShapes; diff --git a/base/broadcast-shapes/docs/types/test.ts b/base/broadcast-shapes/docs/types/test.ts new file mode 100644 index 00000000..28865397 --- /dev/null +++ b/base/broadcast-shapes/docs/types/test.ts @@ -0,0 +1,45 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +import broadcastShapes = require( './index' ); + + +// TESTS // + +// The function returns an array of numbers... +{ + broadcastShapes( [ [ 1, 2 ], [ 2, 2 ] ] ); // $ExpectType ArrayLike +} + +// The compiler throws an error if the function is not provided an array-like object containing array-like objects containing numbers... +{ + broadcastShapes( '5' ); // $ExpectError + broadcastShapes( 5 ); // $ExpectError + broadcastShapes( true ); // $ExpectError + broadcastShapes( false ); // $ExpectError + broadcastShapes( null ); // $ExpectError + broadcastShapes( {} ); // $ExpectError + broadcastShapes( [ '5' ] ); // $ExpectError + broadcastShapes( ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + broadcastShapes(); // $ExpectError + broadcastShapes( [ [ 1, 2, 3 ] ], [ 2, 3 ] ); // $ExpectError +} diff --git a/base/broadcast-shapes/examples/c/Makefile b/base/broadcast-shapes/examples/c/Makefile new file mode 100644 index 00000000..70c91f4e --- /dev/null +++ b/base/broadcast-shapes/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/broadcast-shapes/examples/c/example.c b/base/broadcast-shapes/examples/c/example.c new file mode 100644 index 00000000..abb751d0 --- /dev/null +++ b/base/broadcast-shapes/examples/c/example.c @@ -0,0 +1,49 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/broadcast_shapes.h" +#include +#include + +int main() { + int64_t N1 = 4; + int64_t sh1[] = { 8, 1, 6, 1 }; + + int64_t N2 = 3; + int64_t sh2[] = { 7, 1, 5 }; + + int64_t ndims[] = { N1, N2 }; + int64_t *shapes[] = { sh1, sh2 }; + + int64_t out[] = { 0, 0, 0, 0 }; + int8_t status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out ); + if ( status != 0 ) { + printf( "incompatible shapes\n" ); + return 1; + } + int64_t i; + printf( "shape = ( " ); + for ( i = 0; i < N1; i++ ) { + printf( "%lli", out[ i ] ); + if ( i < N1-1 ) { + printf( ", " ); + } + } + printf( " )\n" ); + return 0; +} diff --git a/base/broadcast-shapes/examples/index.js b/base/broadcast-shapes/examples/index.js new file mode 100644 index 00000000..e038004f --- /dev/null +++ b/base/broadcast-shapes/examples/index.js @@ -0,0 +1,54 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var lpad = require( '@stdlib/string/left-pad' ); +var broadcastShapes = require( './../lib' ); + +var shapes; +var out; +var sh; +var i; +var j; + +function shape2string( shape ) { + return lpad( shape.join( ' x ' ), 20, ' ' ); +} + +shapes = [ + [ [ 1, 2 ], [ 2 ] ], + [ [ 1, 1 ], [ 3, 4 ] ], + [ [ 6, 7 ], [ 5, 6, 1 ], [ 7 ], [ 5, 1, 7 ] ], + [ [ 1, 3 ], [ 3, 1 ] ], + [ [ 1 ], [ 3 ] ], + [ [ 2 ], [ 3, 2 ] ], + [ [ 2, 3 ], [ 2, 3 ], [ 2, 3 ], [ 2, 3 ] ], + [ [ 1, 2 ], [ 1, 2 ] ] +]; + +for ( i = 0; i < shapes.length; i++ ) { + sh = shapes[ i ]; + for ( j = 0; j < sh.length; j++ ) { + console.log( shape2string( sh[ j ] ) ); + } + console.log( lpad( '', 20, '-' ) ); + + out = broadcastShapes( sh ); + console.log( shape2string( out )+'\n' ); +} diff --git a/base/broadcast-shapes/include/stdlib/ndarray/base/broadcast_shapes.h b/base/broadcast-shapes/include/stdlib/ndarray/base/broadcast_shapes.h new file mode 100644 index 00000000..e23dce1d --- /dev/null +++ b/base/broadcast-shapes/include/stdlib/ndarray/base/broadcast_shapes.h @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +#ifndef STDLIB_NDARRAY_BASE_BROADCAST_SHAPES_H +#define STDLIB_NDARRAY_BASE_BROADCAST_SHAPES_H + +#include + +/* +* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +/** +* Broadcasts array shapes to a single shape. +*/ +int8_t stdlib_ndarray_broadcast_shapes( int64_t M, int64_t *shapes[], int64_t ndims[], int64_t *out ); + +#ifdef __cplusplus +} +#endif + +#endif // !STDLIB_NDARRAY_BASE_BROADCAST_SHAPES_H diff --git a/base/broadcast-shapes/lib/index.js b/base/broadcast-shapes/lib/index.js new file mode 100644 index 00000000..3572477c --- /dev/null +++ b/base/broadcast-shapes/lib/index.js @@ -0,0 +1,45 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Broadcast array shapes to a single shape. +* +* @module @stdlib/ndarray/base/broadcast-shapes +* +* @example +* var broadcastShapes = require( '@stdlib/ndarray/base/broadcast-shapes' ); +* +* var shapes = [ +* [ 8, 1, 6, 1 ], +* [ 7, 1, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 7, 6, 5 ] +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/base/broadcast-shapes/lib/main.js b/base/broadcast-shapes/lib/main.js new file mode 100644 index 00000000..5529ebbe --- /dev/null +++ b/base/broadcast-shapes/lib/main.js @@ -0,0 +1,256 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Broadcasts array shapes to a single shape. +* +* ## Notes +* +* - Two respective dimensions in two shape arrays are compatible if +* +* 1. the dimensions are equal. +* 2. one dimension is `1`. +* +* - The function returns `null` if provided incompatible shapes (i.e., shapes which cannot be broadcast one another). +* +* @param {Array} shapes - array of shape arrays +* @returns {(NonNegativeIntegerArray|null)} broadcast shape (or `null`) +* +* @example +* var shapes = [ +* [ 8, 1, 6, 1 ], +* [ 7, 1, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 7, 6, 5 ] +* +* @example +* var shapes = [ +* [ 5, 4 ], +* [ 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 5, 4 ] +* +* @example +* var shapes = [ +* [ 5, 4 ], +* [ 4 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 5, 4 ] +* +* @example +* var shapes = [ +* [ 15, 3, 5 ], +* [ 15, 1, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 15, 3, 5 ] +* +* @example +* var shapes = [ +* [ 15, 3, 5 ], +* [ 3, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 15, 3, 5 ] +* +* @example +* var shapes = [ +* [ 15, 3, 5 ], +* [ 3, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 15, 3, 5 ] +* +* @example +* var shapes = [ +* [ 8, 1, 1, 6, 1 ], +* [ 1, 7, 1, 5 ], +* [ 8, 4, 1, 6, 5 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 4, 7, 6, 5 ] +* +* @example +* var shapes = [ +* [ 8, 1, 1, 6, 1 ], +* [ 0 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 1, 1, 6, 0 ] +* +* @example +* var shapes = [ +* [ 8, 1, 1, 6, 1 ], +* [ 8, 0, 1, 6, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 8, 0, 1, 6, 1 ] +* +* @example +* var shapes = [ +* [ 8, 8, 1, 6, 1 ], +* [ 8, 0, 1, 6, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns null +* +* @example +* var shapes = [ +* [ 8, 0, 1, 6, 1 ], +* [ 8, 8, 1, 6, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns null +* +* @example +* var shapes = [ +* [] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [] +* +* @example +* var shapes = [ +* [], +* [] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [] +* +* @example +* var shapes = []; +* +* var out = broadcastShapes( shapes ); +* // returns [] +* +* @example +* var shapes = [ +* [ 3, 2, 1 ], +* [] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 3, 2, 1 ] +* +* @example +* var shapes = [ +* [], +* [ 3, 2, 1 ] +* ]; +* +* var out = broadcastShapes( shapes ); +* // returns [ 3, 2, 1 ] +*/ +function broadcastShapes( shapes ) { + var ndims; + var out; + var dim; + var sh; + var n1; + var n2; + var d; + var M; + var N; + var i; + var j; + + M = shapes.length; + out = []; + if ( M === 0 ) { + return out; + } + sh = shapes[ 0 ]; + N = sh.length; + + // If provided a single input shape array, then the broadcast shape is input shape... + if ( M === 1 ) { + // Need to manually copy to output shape, as shapes could be array-like objects... + for ( i = 0; i < N; i++ ) { + out.push( sh[ i ] ); + } + return out; + } + // Determine the maximum dimensionality... + ndims = [ N ]; + for ( i = 1; i < M; i++ ) { + ndims.push( shapes[ i ].length ); + if ( ndims[ i ] > N ) { + N = ndims[ i ]; + } + } + // Initialize the output array... + for ( i = 0; i < N; i++ ) { + out.push( 0 ); + } + // Compute the broadcast shape... + i = N - 1; + while ( i >= 0 ) { + n1 = ndims[ 0 ] - N + i; + if ( n1 >= 0 ) { + dim = sh[ n1 ]; + } else { + dim = 1; + } + for ( j = 1; j < M; j++ ) { + n2 = ndims[ j ] - N + i; + if ( n2 >= 0 ) { + d = shapes[ j ][ n2 ]; + } else { + d = 1; + } + if ( dim === 1 ) { + dim = d; + continue; + } + if ( d === 1 || dim === d ) { + // When either `d` is `1` or `d` equals the current output shape dimension, the current output shape dimension remains the same... + continue; + } + // The current shape cannot be broadcast against one of the other shapes... + return null; + } + out[ i ] = dim; + i -= 1; + } + return out; +} + + +// EXPORTS // + +module.exports = broadcastShapes; diff --git a/base/broadcast-shapes/manifest.json b/base/broadcast-shapes/manifest.json new file mode 100644 index 00000000..890a937a --- /dev/null +++ b/base/broadcast-shapes/manifest.json @@ -0,0 +1,38 @@ +{ + "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/main.c" + ], + "include": [ + "./include" + ], + "libraries": [], + "libpath": [], + "dependencies": [] + } + ] +} diff --git a/base/broadcast-shapes/package.json b/base/broadcast-shapes/package.json new file mode 100644 index 00000000..bd1e099e --- /dev/null +++ b/base/broadcast-shapes/package.json @@ -0,0 +1,69 @@ +{ + "name": "@stdlib/ndarray/base/broadcast-shapes", + "version": "0.0.0", + "description": "Broadcast array shapes to a single shape.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "include": "./include", + "lib": "./lib", + "src": "./src", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdtypes", + "types", + "base", + "ndarray", + "broadcast", + "broadcasting", + "multidimensional", + "array", + "utilities", + "utility", + "utils", + "util" + ], + "__stdlib__": {} +} diff --git a/base/broadcast-shapes/src/main.c b/base/broadcast-shapes/src/main.c new file mode 100644 index 00000000..35a36540 --- /dev/null +++ b/base/broadcast-shapes/src/main.c @@ -0,0 +1,118 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/broadcast_shapes.h" +#include + +/** +* Broadcasts array shapes to a single shape. +* +* ## Notes +* +* - Two respective dimensions in two shape arrays are compatible if +* +* 1. the dimensions are equal. +* 2. one dimension is `1`. +* +* - If successful, the function returns `0`; otherwise, the function returns `-1` (e.g., due to incompatible shapes). +* +* - Even if the function is unsuccessful, the function may still overwrite elements in the output array before returning. In other words, do not assume that providing incompatible shapes is a no-op with regard to the output array. +* +* @param M number of array shapes +* @param shapes pointer to an array containing shape arrays +* @param ndims array containing the number of dimensions for (i.e., length of) each respective shape array +* @param out pointer to output array +* @return status +* +* @example +* #include "stdlib/ndarray/base/broadcast_shapes.h" +* #include +* +* int64_t N1 = 4; +* int64_t sh1[] = { 8, 1, 6, 1 }; +* +* int64_t N2 = 3; +* int64_t sh2[] = { 7, 1, 5 }; +* +* int64_t ndims[] = { N1, N2 }; +* int64_t *shapes[] = { sh1, sh2 }; +* +* int64_t out[] = { 0, 0, 0, 0 }; +* int8_t status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out ); +*/ +int8_t stdlib_ndarray_broadcast_shapes( int64_t M, int64_t *shapes[], int64_t ndims[], int64_t *out ) { + int64_t dim; + int64_t *sh; + int64_t n1; + int64_t n2; + int64_t d; + int64_t N; + int64_t i; + int64_t j; + + if ( M == 0 ) { + return 0; + } + sh = shapes[ 0 ]; + N = ndims[ 0 ]; + + // If provided a single input shape array, then the broadcast shape is input shape... + if ( M == 1 ) { + for ( i = 0; i < N; i++ ) { + out[ i ] = sh[ i ]; + } + return 0; + } + // Determine the maximum dimensionality... + for ( i = 1; i < M; i++ ) { + if ( ndims[ i ] > N ) { + N = ndims[ i ]; + } + } + // Compute the broadcast shape... + i = N - 1; + while ( i >= 0 ) { + n1 = ndims[ 0 ] - N + i; + if ( n1 >= 0 ) { + dim = sh[ n1 ]; + } else { + dim = 1; + } + for ( j = 1; j < M; j++ ) { + n2 = ndims[ j ] - N + i; + if ( n2 >= 0 ) { + d = shapes[ j ][ n2 ]; + } else { + d = 1; + } + if ( dim == 1 ) { + dim = d; + continue; + } + if ( d == 1 || dim == d ) { + // When either `d` is `1` or `d` equals the current output shape dimension, the current output shape dimension remains the same... + continue; + } + // The current shape cannot be broadcast against one of the other shapes... + return -1; + } + out[ i ] = dim; + i -= 1; + } + return 0; +} diff --git a/base/broadcast-shapes/test/test.js b/base/broadcast-shapes/test/test.js new file mode 100644 index 00000000..63f703cb --- /dev/null +++ b/base/broadcast-shapes/test/test.js @@ -0,0 +1,230 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var broadcastShapes = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof broadcastShapes, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function broadcasts array shapes to a single shape', function test( t ) { + var expected; + var actual; + var values; + var i; + + values = [ + [ [ 1, 2 ], [ 2 ] ], + [ [ 1, 1 ], [ 3, 4 ] ], + [ [ 6, 7 ], [ 5, 6, 1 ], [ 7 ], [ 5, 1, 7 ] ], + [ [ 1, 3 ], [ 3, 1 ] ], + [ [ 1 ], [ 3 ] ], + [ [ 2 ], [ 3, 2 ] ], + [ [ 2, 3 ], [ 2, 3 ], [ 2, 3 ], [ 2, 3 ] ], + [ [ 1, 2 ], [ 1, 2 ] ] + ]; + + expected = [ + [ 1, 2 ], + [ 3, 4 ], + [ 5, 6, 7 ], + [ 3, 3 ], + [ 3 ], + [ 3, 2 ], + [ 2, 3 ], + [ 1, 2 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + actual = broadcastShapes( values[ i ] ); + t.deepEqual( actual, expected[ i ], 'returns expected value. Actual: ('+actual.join( ',' )+'). Expected: ('+expected[ i ].join( ',' )+').' ); + } + t.end(); +}); + +tape( 'the function broadcasts array shapes to a single shape (empty dims)', function test( t ) { + var expected; + var actual; + var values; + var i; + + values = [ + [ [ 1, 0 ], [ 0, 0 ] ], + [ [ 0, 1 ], [ 0, 0 ] ], + [ [ 1, 0 ], [ 0, 1 ] ], + [ [ 1, 1 ], [ 0, 0 ] ], + [ [ 1, 1 ], [ 1, 0 ] ], + [ [ 1, 1 ], [ 0, 1 ] ], + [ [ 0 ], [ 0, 0 ] ], + [ [ 0 ], [ 0, 1 ] ], + [ [ 1 ], [ 0, 0 ] ], + [ [ 1, 1 ], [ 0 ] ], + [ [ 1 ], [ 0, 1 ] ], + [ [ 1 ], [ 1, 0 ] ], + [ [ 1 ], [ 8, 0 ] ], + [ [ 8, 1, 6, 1 ], [ 0, 1, 5 ] ], + [ [ 8, 0, 6, 1 ], [ 1, 5 ] ] + ]; + + expected = [ + [ 0, 0 ], + [ 0, 0 ], + [ 0, 0 ], + [ 0, 0 ], + [ 1, 0 ], + [ 0, 1 ], + [ 0, 0 ], + [ 0, 0 ], + [ 0, 0 ], + [ 1, 0 ], + [ 0, 1 ], + [ 1, 0 ], + [ 8, 0 ], + [ 8, 0, 6, 5 ], + [ 8, 0, 6, 5 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + actual = broadcastShapes( values[ i ] ); + t.deepEqual( actual, expected[ i ], 'returns expected value. Actual: ('+actual.join( ',' )+'). Expected: ('+expected[ i ].join( ',' )+').' ); + } + t.end(); +}); + +tape( 'the function broadcasts array shapes to a single shape (no shapes)', function test( t ) { + var expected; + var actual; + var values; + var i; + + values = [ + [] + ]; + + expected = [ + [] + ]; + + for ( i = 0; i < values.length; i++ ) { + actual = broadcastShapes( values[ i ] ); + t.deepEqual( actual, expected[ i ], 'returns expected value. Actual: ('+actual.join( ',' )+'). Expected: ('+expected[ i ].join( ',' )+').' ); + } + t.end(); +}); + +tape( 'the function broadcasts array shapes to a single shape (empty shapes (i.e., zero-dimensional array broadcasting))', function test( t ) { + var expected; + var actual; + var values; + var i; + + values = [ + [ [] ], + [ [], [] ], + [ [], [], [] ], + [ [], [ 0 ] ], + [ [ 0 ], [] ], + [ [], [ 0, 0 ] ], + [ [ 0, 0 ], [] ], + [ [], [ 1, 0 ] ], + [ [], [ 0, 1 ] ], + [ [], [ 3, 3 ] ], + [ [], [ 3, 3 ], [] ] + ]; + + expected = [ + [], + [], + [], + [ 0 ], + [ 0 ], + [ 0, 0 ], + [ 0, 0 ], + [ 1, 0 ], + [ 0, 1 ], + [ 3, 3 ], + [ 3, 3 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + actual = broadcastShapes( values[ i ] ); + t.deepEqual( actual, expected[ i ], 'returns expected value. Actual: ('+actual.join( ',' )+'). Expected: ('+expected[ i ].join( ',' )+').' ); + } + t.end(); +}); + +tape( 'the function broadcasts array shapes to a single shape (single shape)', function test( t ) { + var expected; + var actual; + var values; + var i; + + values = [ + [ [ 7 ] ], + [ [ 1, 1 ] ], + [ [ 5, 6, 1 ] ] + ]; + + expected = [ + [ 7 ], + [ 1, 1 ], + [ 5, 6, 1 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + actual = broadcastShapes( values[ i ] ); + t.deepEqual( actual, expected[ i ], 'returns expected value. Actual: ('+actual.join( ',' )+'). Expected: ('+expected[ i ].join( ',' )+').' ); + } + t.end(); +}); + +tape( 'the function returns `null` if provided incompatible shapes', function test( t ) { + var actual; + var values; + var i; + + values = [ + [ [ 3 ], [ 4 ] ], + [ [ 2, 3 ], [ 2 ] ], + [ [ 3 ], [ 3 ], [ 4 ] ], + [ [ 1, 3, 4 ], [ 2, 3, 3 ] ], + [ [ 1, 2 ], [ 3, 1 ], [ 3, 2 ], [ 10, 5 ] ], + [ [ 2 ], [ 2, 3 ] ], + [ [ 2 ], [ 2 ], [ 2 ], [ 2 ], [ 3 ], [ 3 ], [ 3 ], [ 3 ] ], + [ [ 9, 0, 9 ], [ 0, 9, 0 ] ], + [ [ 9, 9, 9 ], [ 0, 9, 9 ] ], + [ [ 9, 0, 9 ], [ 9, 9, 9 ] ], + [ [ 9, 9, 9 ], [ 9, 9, 0 ] ] + ]; + + for ( i = 0; i < values.length; i++ ) { + actual = broadcastShapes( values[ i ] ); + t.strictEqual( actual, null, 'returns expected value. i: '+i+'.' ); + } + t.end(); +}); diff --git a/base/buffer-ctors/benchmark/benchmark.js b/base/buffer-ctors/benchmark/benchmark.js new file mode 100644 index 00000000..3b2e1dcc --- /dev/null +++ b/base/buffer-ctors/benchmark/benchmark.js @@ -0,0 +1,54 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var pkg = require( './../package.json' ).name; +var ctors = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var ctor; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + ctor = ctors( DTYPES[ i%DTYPES.length ] ); + if ( typeof ctor !== 'function' ) { + b.fail( 'should return a function' ); + } + } + b.toc(); + if ( !isFunction( ctor ) ) { + b.fail( 'should return a function' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/buffer-ctors/examples/index.js b/base/buffer-ctors/examples/index.js new file mode 100644 index 00000000..da5b2c88 --- /dev/null +++ b/base/buffer-ctors/examples/index.js @@ -0,0 +1,31 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var ctors = require( './../lib' ); + +var DTYPES = dtypes(); +var ctor; +var i; + +for ( i = 0; i < DTYPES.length; i++ ) { + ctor = ctors( DTYPES[ i ] ); + console.log( ctor ); +} diff --git a/base/buffer-ctors/test/test.js b/base/buffer-ctors/test/test.js new file mode 100644 index 00000000..e2f9c80f --- /dev/null +++ b/base/buffer-ctors/test/test.js @@ -0,0 +1,128 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var Buffer = require( '@stdlib/buffer/ctor' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var Int16Array = require( '@stdlib/array/int16' ); +var Int32Array = require( '@stdlib/array/int32' ); +var Int8Array = require( '@stdlib/array/int8' ); +var Uint16Array = require( '@stdlib/array/uint16' ); +var Uint32Array = require( '@stdlib/array/uint32' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var Uint8ClampedArray = require( '@stdlib/array/uint8c' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var Complex128Array = require( '@stdlib/array/complex128' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ctors = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ctors, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns ndarray data buffer constructors', function test( t ) { + var expected; + var dtypes; + var ctor; + var i; + + dtypes = [ + 'binary', + 'float64', + 'float32', + 'generic', + 'int16', + 'int32', + 'int8', + 'uint16', + 'uint32', + 'uint8', + 'uint8c', + 'complex64', + 'complex128' + ]; + expected = [ + Buffer, + Float64Array, + Float32Array, + Array, // TODO: explicitly require + Int16Array, + Int32Array, + Int8Array, + Uint16Array, + Uint32Array, + Uint8Array, + Uint8ClampedArray, + Complex64Array, + Complex128Array + ]; + for ( i = 0; i < dtypes.length; i++ ) { + ctor = ctors( dtypes[ i ] ); + t.strictEqual( ctor, expected[ i ], 'returns expected value for ' + dtypes[ i ] ); + } + t.end(); +}); + +tape( 'the function returns a constructor for each supported ndarray data type', function test( t ) { + var DTYPES; + var ctor; + var i; + + DTYPES = dtypes(); + for ( i = 0; i < DTYPES.length; i++ ) { + ctor = ctors( DTYPES[ i ] ); + + // Note: this is a weak test for a "constructor" + t.strictEqual( isFunction( ctor ), true, 'returns a function for ' + DTYPES[ i ] ); + } + t.end(); +}); + +tape( 'if provided an unknown/unsupported data type, the function returns `null`', function test( t ) { + var dtypes; + var i; + + dtypes = [ + 'buffer', + 'buf', + 'float', + 'double', + 'single', + 'int', + 'integer', + 'uint', + 'uinteger', + 'byte', + 'bits' + ]; + for ( i = 0; i < dtypes.length; i++ ) { + t.strictEqual( ctors( dtypes[i] ), null, 'returns expected value for ' + dtypes[ i ] ); + } + t.end(); +}); diff --git a/base/buffer-dtype-enum/benchmark/benchmark.js b/base/buffer-dtype-enum/benchmark/benchmark.js new file mode 100644 index 00000000..ea05506b --- /dev/null +++ b/base/buffer-dtype-enum/benchmark/benchmark.js @@ -0,0 +1,67 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var isFunction = require( '@stdlib/assert/is-function' ); +var pkg = require( './../package.json' ).name; +var dtypeEnum = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var buffers; + var ctor; + var dt; + var i; + + buffers = []; + for ( i = 0; i < DTYPES.length; i++ ) { + ctor = bufferCtors( DTYPES[ i ] ); + if ( DTYPES[ i ] === 'binary' && isFunction( ctor.alloc ) ) { + buffers.push( ctor.alloc( 10 ) ); + } else { + buffers.push( new ctor( 10 ) ); + } + } + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + dt = dtypeEnum( buffers[ i%buffers.length ] ); + if ( typeof dt !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isNumber( dt ) ) { + b.fail( 'should return a number' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/buffer-dtype-enum/examples/index.js b/base/buffer-dtype-enum/examples/index.js new file mode 100644 index 00000000..9caf962e --- /dev/null +++ b/base/buffer-dtype-enum/examples/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var dtypeEnum = require( './../lib' ); + +var DTYPES; +var ctor; +var buf; +var len; +var c; +var i; + +// Get a list of supported ndarray buffer data types: +DTYPES = dtypes(); + +// Buffer length: +len = 10; + +// For each supported data type, create a buffer and retrieve its data type enumeration constant... +for ( i = 0; i < DTYPES.length; i++ ) { + ctor = bufferCtors( DTYPES[ i ] ); + if ( DTYPES[ i ] === 'binary' && isFunction( ctor.alloc ) ) { + buf = ctor.alloc( len ); + } else { + buf = new ctor( len ); + } + c = dtypeEnum( buf ); + console.log( '%s => %d', DTYPES[ i ], c ); +} + +// Try an array-like object... +buf = { + 'length': 10 +}; +c = dtypeEnum( buf ); +console.log( '%s => %s', 'generic', c ); diff --git a/base/buffer-dtype-enum/test/test.js b/base/buffer-dtype-enum/test/test.js new file mode 100644 index 00000000..08cdd757 --- /dev/null +++ b/base/buffer-dtype-enum/test/test.js @@ -0,0 +1,93 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var dtypeEnum = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); +var TABLE = dtypes.enum(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dtypeEnum, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the data type enumeration constant for ndarray data buffers', function test( t ) { + var ctor; + var buf; + var dt; + var i; + + for ( i = 0; i < DTYPES.length; i++ ) { + ctor = bufferCtors( DTYPES[ i ] ); + if ( DTYPES[ i ] === 'binary' && isFunction( ctor.alloc ) ) { + buf = ctor.alloc( 10 ); + } else { + buf = new ctor( 10 ); + } + dt = dtypeEnum( buf ); + t.strictEqual( dt, TABLE[ DTYPES[ i ] ], 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function supports generic objects', function test( t ) { + var buf; + var dt; + + buf = { + 'length': 10 + }; + dt = dtypeEnum( buf ); + t.strictEqual( dt, TABLE[ 'generic' ], 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an ndarray data buffer having an unknown/unsupported data type, the function returns `null`', function test( t ) { + var buffers; + var i; + + buffers = [ + 'beep', + 5, + NaN, + null, + void 0, + true, + false, + function noop() {} + ]; + for ( i = 0; i < buffers.length; i++ ) { + t.strictEqual( dtypeEnum( buffers[i] ), null, 'returns expected value for ' + buffers[ i ] ); + } + t.end(); +}); diff --git a/base/buffer-dtype/benchmark/benchmark.js b/base/buffer-dtype/benchmark/benchmark.js new file mode 100644 index 00000000..c36d5f20 --- /dev/null +++ b/base/buffer-dtype/benchmark/benchmark.js @@ -0,0 +1,67 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var isFunction = require( '@stdlib/assert/is-function' ); +var pkg = require( './../package.json' ).name; +var dtype = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var buffers; + var ctor; + var dt; + var i; + + buffers = []; + for ( i = 0; i < DTYPES.length; i++ ) { + ctor = bufferCtors( DTYPES[ i ] ); + if ( DTYPES[ i ] === 'binary' && isFunction( ctor.alloc ) ) { + buffers.push( ctor.alloc( 10 ) ); + } else { + buffers.push( new ctor( 10 ) ); + } + } + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + dt = dtype( buffers[ i%buffers.length ] ); + if ( typeof dt !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( dt ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/buffer-dtype/examples/index.js b/base/buffer-dtype/examples/index.js new file mode 100644 index 00000000..460826b8 --- /dev/null +++ b/base/buffer-dtype/examples/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var dtype = require( './../lib' ); + +var DTYPES; +var ctor; +var buf; +var len; +var dt; +var i; + +// Get a list of supported ndarray buffer data types: +DTYPES = dtypes(); + +// Buffer length: +len = 10; + +// For each supported data type, create a buffer and confirm its data type... +for ( i = 0; i < DTYPES.length; i++ ) { + ctor = bufferCtors( DTYPES[ i ] ); + if ( DTYPES[ i ] === 'binary' && isFunction( ctor.alloc ) ) { + buf = ctor.alloc( len ); + } else { + buf = new ctor( len ); + } + dt = dtype( buf ); + console.log( '%s == %s => %s', DTYPES[ i ], dt, DTYPES[ i ] === dt ); +} + +// Try an array-like object... +buf = { + 'length': 10 +}; +dt = dtype( buf ); +console.log( '%s == %s => %s', 'generic', dt, dt === 'generic' ); diff --git a/base/buffer-dtype/test/test.js b/base/buffer-dtype/test/test.js new file mode 100644 index 00000000..bef85818 --- /dev/null +++ b/base/buffer-dtype/test/test.js @@ -0,0 +1,90 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var dtype = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dtype, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the data type for ndarray data buffers', function test( t ) { + var DTYPES; + var ctor; + var buf; + var dt; + var i; + + DTYPES = dtypes(); + + for ( i = 0; i < DTYPES.length; i++ ) { + ctor = bufferCtors( DTYPES[ i ] ); + if ( DTYPES[ i ] === 'binary' && isFunction( ctor.alloc ) ) { + buf = ctor.alloc( 10 ); + } else { + buf = new ctor( 10 ); + } + dt = dtype( buf ); + t.strictEqual( dt, DTYPES[ i ], 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function supports generic objects', function test( t ) { + var buf; + var dt; + + buf = { + 'length': 10 + }; + dt = dtype( buf ); + t.strictEqual( dt, 'generic', 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an ndarray data buffer having an unknown/unsupported data type, the function returns `null`', function test( t ) { + var buffers; + var i; + + buffers = [ + 'beep', + 5, + NaN, + null, + void 0, + true, + false, + function noop() {} + ]; + for ( i = 0; i < buffers.length; i++ ) { + t.strictEqual( dtype( buffers[i] ), null, 'returns expected value for ' + buffers[ i ] ); + } + t.end(); +}); diff --git a/base/buffer/benchmark/benchmark.js b/base/buffer/benchmark/benchmark.js new file mode 100644 index 00000000..f4366644 --- /dev/null +++ b/base/buffer/benchmark/benchmark.js @@ -0,0 +1,238 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isCollection = require( '@stdlib/assert/is-collection' ); +var pkg = require( './../package.json' ).name; +var buffer = require( './../lib' ); + + +// MAIN // + +bench( pkg+':dtype=binary', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'binary', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=float64', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'float64', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=float32', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'float32', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=generic', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'generic', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=int16', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'int16', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=int32', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'int32', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=int8', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'int8', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=uint16', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'uint16', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=uint32', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'uint32', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=uint8', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'uint8', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':dtype=uint8c', function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( 'uint8c', 10 ); + if ( out.length !== 10 ) { + b.fail( 'should have length 10' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/buffer/benchmark/benchmark.length.js b/base/buffer/benchmark/benchmark.length.js new file mode 100644 index 00000000..f0d908a8 --- /dev/null +++ b/base/buffer/benchmark/benchmark.length.js @@ -0,0 +1,125 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var isCollection = require( '@stdlib/assert/is-collection' ); +var pkg = require( './../package.json' ).name; +var buffer = require( './../lib' ); + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {string} dtype - data type +* @param {PositiveInteger} len - buffer length +* @returns {Function} benchmark function +*/ +function createBenchmark( dtype, len ) { + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = buffer( dtype, len ); + if ( out.length !== len ) { + b.fail( 'unexpected length' ); + } + } + b.toc(); + if ( !isCollection( out ) ) { + b.fail( 'should return an array-like object' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var f; + var i; + + min = 1; // 10^min + max = 6; // 10^max + + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + f = createBenchmark( 'binary', len ); + bench( pkg+':len='+len+',dtype=binary', f ); + + f = createBenchmark( 'float64', len ); + bench( pkg+':len='+len+',dtype=float64', f ); + + f = createBenchmark( 'float32', len ); + bench( pkg+':len='+len+',dtype=float32', f ); + + f = createBenchmark( 'generic', len ); + bench( pkg+':len='+len+',dtype=generic', f ); + + f = createBenchmark( 'int16', len ); + bench( pkg+':len='+len+',dtype=int16', f ); + + f = createBenchmark( 'int32', len ); + bench( pkg+':len='+len+',dtype=int32', f ); + + f = createBenchmark( 'int8', len ); + bench( pkg+':len='+len+',dtype=int8', f ); + + f = createBenchmark( 'uint16', len ); + bench( pkg+':len='+len+',dtype=uint16', f ); + + f = createBenchmark( 'uint32', len ); + bench( pkg+':len='+len+',dtype=uint32', f ); + + f = createBenchmark( 'uint8', len ); + bench( pkg+':len='+len+',dtype=uint8', f ); + + f = createBenchmark( 'uint8c', len ); + bench( pkg+':len='+len+',dtype=uint8c', f ); + } +} + +main(); diff --git a/base/buffer/examples/index.js b/base/buffer/examples/index.js new file mode 100644 index 00000000..4db1b24b --- /dev/null +++ b/base/buffer/examples/index.js @@ -0,0 +1,31 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var buffer = require( './../lib' ); + +var DTYPES = dtypes(); +var buf; +var i; + +for ( i = 0; i < DTYPES.length; i++ ) { + buf = buffer( DTYPES[ i ], 10 ); + console.log( buf ); +} diff --git a/base/buffer/test/test.js b/base/buffer/test/test.js new file mode 100644 index 00000000..14af9508 --- /dev/null +++ b/base/buffer/test/test.js @@ -0,0 +1,178 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var array2buffer = require( '@stdlib/buffer/from-array' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var Int16Array = require( '@stdlib/array/int16' ); +var Int32Array = require( '@stdlib/array/int32' ); +var Int8Array = require( '@stdlib/array/int8' ); +var Uint16Array = require( '@stdlib/array/uint16' ); +var Uint32Array = require( '@stdlib/array/uint32' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var Uint8ClampedArray = require( '@stdlib/array/uint8c' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var Complex128Array = require( '@stdlib/array/complex128' ); +var isBuffer = require( '@stdlib/assert/is-buffer' ); +var isArray = require( '@stdlib/assert/is-array' ); +var isFloat64Array = require( '@stdlib/assert/is-float64array' ); +var isFloat32Array = require( '@stdlib/assert/is-float32array' ); +var isInt16Array = require( '@stdlib/assert/is-int16array' ); +var isInt32Array = require( '@stdlib/assert/is-int32array' ); +var isInt8Array = require( '@stdlib/assert/is-int8array' ); +var isUint16Array = require( '@stdlib/assert/is-uint16array' ); +var isUint32Array = require( '@stdlib/assert/is-uint32array' ); +var isUint8Array = require( '@stdlib/assert/is-uint8array' ); +var isUint8ClampedArray = require( '@stdlib/assert/is-uint8clampedarray' ); +var isComplex64Array = require( '@stdlib/assert/is-complex64array' ); +var isComplex128Array = require( '@stdlib/assert/is-complex128array' ); +var buffer = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof buffer, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns zero-filled contiguous ndarray data buffers', function test( t ) { + var expected; + var dtypes; + var vals; + var buf; + var i; + var j; + + dtypes = [ + 'binary', + 'complex64', + 'complex128', + 'float64', + 'float32', + 'generic', + 'int16', + 'int32', + 'int8', + 'uint16', + 'uint32', + 'uint8', + 'uint8c' + ]; + vals = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + expected = [ + [ array2buffer( vals ), isBuffer ], + [ new Complex64Array( vals ), isComplex64Array ], + [ new Complex128Array( vals ), isComplex128Array ], + [ new Float64Array( vals ), isFloat64Array ], + [ new Float32Array( vals ), isFloat32Array ], + [ vals, isArray ], + [ new Int16Array( vals ), isInt16Array ], + [ new Int32Array( vals ), isInt32Array ], + [ new Int8Array( vals ), isInt8Array ], + [ new Uint16Array( vals ), isUint16Array ], + [ new Uint32Array( vals ), isUint32Array ], + [ new Uint8Array( vals ), isUint8Array ], + [ new Uint8ClampedArray( vals ), isUint8ClampedArray ] + ]; + for ( i = 0; i < dtypes.length; i++ ) { + buf = buffer( dtypes[ i ], vals.length ); + t.strictEqual( expected[ i ][ 1 ]( buf ), true, 'returns expected value type for ' + dtypes[ i ] ); + for ( j = 0; j < buf.length; j++ ) { + t.strictEqual( buf[ j ], expected[ i ][ 0 ][ j ], 'returns expected element ' + j + ' for ' + dtypes[ i ] ); + } + } + t.end(); +}); + +tape( 'the function returns ndarray data buffers (large allocations)', function test( t ) { + var expected; + var dtypes; + var vals; + var buf; + var i; + + dtypes = [ + 'binary', + 'complex64', + 'complex128', + 'float64', + 'float32', + 'generic', + 'int16', + 'int32', + 'int8', + 'uint16', + 'uint32', + 'uint8', + 'uint8c' + ]; + vals = []; + for ( i = 0; i < 1e6; i++ ) { + vals.push( 0 ); + } + expected = [ + isBuffer, + isComplex64Array, + isComplex128Array, + isFloat64Array, + isFloat32Array, + isArray, + isInt16Array, + isInt32Array, + isInt8Array, + isUint16Array, + isUint32Array, + isUint8Array, + isUint8ClampedArray + ]; + for ( i = 0; i < dtypes.length; i++ ) { + buf = buffer( dtypes[ i ], vals.length ); + t.strictEqual( expected[ i ]( buf ), true, 'returns expected value type for ' + dtypes[ i ] ); + } + t.end(); +}); + +tape( 'if provided an unknown/unsupported data type, the function returns `null`', function test( t ) { + var dtypes; + var i; + + dtypes = [ + 'buffer', + 'buf', + 'float', + 'double', + 'single', + 'int', + 'integer', + 'uint', + 'uinteger', + 'byte', + 'bits' + ]; + for ( i = 0; i < dtypes.length; i++ ) { + t.strictEqual( buffer( dtypes[ i ], 10 ), null, 'returns expected value for ' + dtypes[ i ] ); + } + t.end(); +}); diff --git a/base/bytes-per-element/benchmark/benchmark.js b/base/bytes-per-element/benchmark/benchmark.js new file mode 100644 index 00000000..8b2eb68d --- /dev/null +++ b/base/bytes-per-element/benchmark/benchmark.js @@ -0,0 +1,65 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pkg = require( './../package.json' ).name; +var bytesPerElement = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var dtypes; + var dtype; + var out; + var i; + + dtypes = [ + 'float64', + 'float32', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'binary', + 'generic', + 'foobar' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + dtype = dtypes[ i%dtypes.length ]; + out = bytesPerElement( dtype ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/bytes-per-element/benchmark/c/Makefile b/base/bytes-per-element/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/bytes-per-element/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/bytes-per-element/benchmark/c/benchmark.c b/base/bytes-per-element/benchmark/c/benchmark.c new file mode 100644 index 00000000..ac19d827 --- /dev/null +++ b/base/bytes-per-element/benchmark/c/benchmark.c @@ -0,0 +1,149 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `bytes_per_element`. +*/ +#include "stdlib/ndarray/base/bytes_per_element.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "bytes-per-element" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t nbytes; + double t; + int i; + + int dtypes[ 8 ] = { + STDLIB_NDARRAY_INT8, + STDLIB_NDARRAY_UINT8, + STDLIB_NDARRAY_INT16, + STDLIB_NDARRAY_UINT16, + STDLIB_NDARRAY_INT32, + STDLIB_NDARRAY_UINT32, + STDLIB_NDARRAY_FLOAT32, + STDLIB_NDARRAY_FLOAT64 + }; + enum STDLIB_NDARRAY_DTYPE dtype; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + dtype = dtypes[ (int)(i%8) ]; + nbytes = stdlib_ndarray_bytes_per_element( dtype ); + if ( nbytes > 250e6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( nbytes > 250e6 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/bytes-per-element/examples/index.js b/base/bytes-per-element/examples/index.js new file mode 100644 index 00000000..40a76bcc --- /dev/null +++ b/base/bytes-per-element/examples/index.js @@ -0,0 +1,46 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var bytesPerElement = require( './../lib' ); + +var dtypes; +var nbytes; +var i; + +dtypes = [ + 'float64', + 'float32', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'binary', + 'generic', + 'foobar' +]; + +for ( i = 0; i < dtypes.length; i++ ) { + nbytes = bytesPerElement( dtypes[ i ] ); + nbytes = ( nbytes ) ? nbytes+' bytes' : 'null'; + console.log( '%s => %s', dtypes[ i ], nbytes ); +} diff --git a/base/bytes-per-element/test/test.js b/base/bytes-per-element/test/test.js new file mode 100644 index 00000000..027f0ce9 --- /dev/null +++ b/base/bytes-per-element/test/test.js @@ -0,0 +1,89 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var bytesPerElement = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof bytesPerElement, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the number of bytes per element provided an underlying array data type', function test( t ) { + var expected; + var values; + var nbytes; + var i; + + values = [ + 'float64', + 'float32', + 'float16', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'int64', + 'uint64', + 'binary', + 'complex64', + 'complex128', + 'generic' + ]; + + expected = [ + 8, + 4, + 2, + 1, + 1, + 1, + 2, + 2, + 4, + 4, + 8, + 8, + 1, + 8, + 16, + null + ]; + for ( i = 0; i < values.length; i++ ) { + nbytes = bytesPerElement( values[ i ] ); + t.strictEqual( nbytes, expected[ i ], 'returns '+expected[i]+' when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns `null` if provided an unknown/unsupported data type', function test( t ) { + var nbytes = bytesPerElement( 'foobar' ); + t.strictEqual( nbytes, null, 'returns expected value' ); + t.end(); +}); diff --git a/base/clamp-index/benchmark/benchmark.js b/base/clamp-index/benchmark/benchmark.js new file mode 100644 index 00000000..c0343a02 --- /dev/null +++ b/base/clamp-index/benchmark/benchmark.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var clampIndex = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var idx; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*40.0 ) - 20.0; + out = clampIndex( idx, 10 ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/clamp-index/benchmark/c/Makefile b/base/clamp-index/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/clamp-index/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/clamp-index/benchmark/c/benchmark.c b/base/clamp-index/benchmark/c/benchmark.c new file mode 100644 index 00000000..d1dd152a --- /dev/null +++ b/base/clamp-index/benchmark/c/benchmark.c @@ -0,0 +1,138 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `clamp_index`. +*/ +#include "stdlib/ndarray/base/clamp_index.h" +#include +#include +#include +#include +#include +#include + +#define NAME "clamp-index" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t idx; + int64_t max; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*100.0 ); + max = (int64_t)( rand_double()*100.0 ); + idx = stdlib_ndarray_clamp_index( idx, max ); + if ( idx < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < 0 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/clamp-index/examples/index.js b/base/clamp-index/examples/index.js new file mode 100644 index 00000000..61c395d2 --- /dev/null +++ b/base/clamp-index/examples/index.js @@ -0,0 +1,32 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var clampIndex = require( './../lib' ); + +var idx; +var out; +var i; + +for ( i = 0; i < 100; i++ ) { + idx = discreteUniform( -20, 20 ); + out = clampIndex( idx, 10 ); + console.log( '%d => [%d,%d] => %d', idx, 0, 10, out ); +} diff --git a/base/clamp-index/test/test.js b/base/clamp-index/test/test.js new file mode 100644 index 00000000..6c95c867 --- /dev/null +++ b/base/clamp-index/test/test.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var clampIndex = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof clampIndex, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function restricts an index to the interval `[0,max]`', function test( t ) { + t.strictEqual( clampIndex( 2, 10 ), 2, 'returns expected value' ); + t.strictEqual( clampIndex( -5, 10 ), 0, 'returns expected value' ); + t.strictEqual( clampIndex( 15, 10 ), 10, 'returns expected value' ); + t.end(); +}); diff --git a/base/ctor/README.md b/base/ctor/README.md index 717f0396..f268c1b1 100644 --- a/base/ctor/README.md +++ b/base/ctor/README.md @@ -647,9 +647,9 @@ str = JSON.stringify( arr.toJSON() ); [@stdlib/ndarray/dtypes]: https://github.com/stdlib-js/ndarray/tree/main/dtypes -[@stdlib/array/complex64]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/complex64 +[@stdlib/array/complex64]: https://github.com/stdlib-js/array-complex64 -[@stdlib/array/complex128]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/complex128 +[@stdlib/array/complex128]: https://github.com/stdlib-js/array-complex128 diff --git a/base/ctor/benchmark/benchmark.js b/base/ctor/benchmark/benchmark.js new file mode 100644 index 00000000..bb80f01d --- /dev/null +++ b/base/ctor/benchmark/benchmark.js @@ -0,0 +1,1278 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var pkg = require( './../package.json' ).name; +var ndarray = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::instantiation', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,new', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = new ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:byteLength', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.byteLength; + if ( v !== null ) { + b.fail( 'should return null' ); + } + } + b.toc(); + if ( v !== null ) { + b.fail( 'should return null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_byteLength', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._byteLength; // eslint-disable-line no-underscore-dangle + if ( v !== null ) { + b.fail( 'should return null' ); + } + } + b.toc(); + if ( v !== null ) { + b.fail( 'should return null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:BYTES_PER_ELEMENT', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.BYTES_PER_ELEMENT; + if ( v !== null ) { + b.fail( 'should return null' ); + } + } + b.toc(); + if ( v !== null ) { + b.fail( 'should return null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:data', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.data; + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_buffer', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._buffer; // eslint-disable-line no-underscore-dangle + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:dtype', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.dtype; + if ( v !== 'generic' ) { + b.fail( 'should return expected data type' ); + } + } + b.toc(); + if ( v !== 'generic' ) { + b.fail( 'should return expected data type' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:flags', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.flags; + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_flags', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._flags; // eslint-disable-line no-underscore-dangle + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:length', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.length; + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_length', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._length; // eslint-disable-line no-underscore-dangle + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:ndims', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.ndims; + if ( v !== shape.length ) { + b.fail( 'should return expected number of dimensions' ); + } + } + b.toc(); + if ( v !== shape.length ) { + b.fail( 'should return expected number of dimensions' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:offset', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.offset; + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + } + b.toc(); + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_offset', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._offset; // eslint-disable-line no-underscore-dangle + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + } + b.toc(); + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:order', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.order; + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + } + b.toc(); + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_order', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._order; // eslint-disable-line no-underscore-dangle + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + } + b.toc(); + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:shape', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.shape; + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_shape', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._shape; // eslint-disable-line no-underscore-dangle + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:strides', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.strides; + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_strides', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._strides; // eslint-disable-line no-underscore-dangle + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':get', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*3.0 ), 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_positive_strides:iget:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*4.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_positive_strides:iget:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*4.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_negative_strides:iget:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*4.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_negative_strides:iget:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*4.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::mixed_sign_strides:iget:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*4.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::mixed_sign_strides:iget:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*4.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':set', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*3.0 ); + out.set( j, 1, v ); + if ( buffer[ (2*j) + (1*1) ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ (2*j) + 1 ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_positive_strides:iset:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*4.0 ); + out.iset( j, v ); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_positive_strides:iset:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*4.0 ); + out.iset( j, v ); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_negative_strides:iset:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*4.0 ); + out.iset( j, v ); + if ( buffer[ 3-j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ 3-j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::all_negative_strides:iset:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*4.0 ); + out.iset( j, v ); + if ( buffer[ 3-j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ 3-j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::mixed_sign_strides:iset:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*4.0 ); + out.iset( j, v ); + if ( buffer[ 0 ] !== buffer[ 0 ] ) { + b.fail( 'should not be NaN' ); + } + } + b.toc(); + if ( out.iget( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::mixed_sign_strides:iset:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*4.0 ); + out.iset( j, v ); + if ( buffer[ 0 ] !== buffer[ 0 ] ) { + b.fail( 'should not be NaN' ); + } + } + b.toc(); + if ( out.iget( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':toJSON', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.toJSON(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':toString', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.toString(); + if ( typeof v !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( typeof v !== 'string' ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/ctor/benchmark/python/numpy/benchmark.py b/base/ctor/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..07b8b378 --- /dev/null +++ b/base/ctor/benchmark/python/numpy/benchmark.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.ndarray.""" + +from __future__ import print_function +import timeit + +REPEATS = 3 +COUNT = [0] # use a list to allow modification within nested scopes + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(iterations, elapsed): + """Print benchmark results. + + # Arguments + + * `iterations`: number of iterations + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(100000, 0.131009101868) + ``` + """ + rate = iterations / elapsed + + print(" ---") + print(" iterations: " + str(iterations)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(name, setup, stmt, iterations): + """Run a benchmark and print benchmark results. + + # Arguments + + * `name`: benchmark name (suffix) + * `setup`: benchmark setup + * `stmt`: statement to benchmark + * `iterations`: number of iterations + + # Examples + + ``` python + python> benchmark("::random", "from random import random;", "y = random()", 1000000) + ``` + """ + t = timeit.Timer(stmt, setup=setup) + + i = 0 + while i < REPEATS: + print("# python::numpy" + name) + COUNT[0] += 1 + elapsed = t.timeit(number=iterations) + print_results(iterations, elapsed) + print("ok " + str(COUNT[0]) + " benchmark finished") + i += 1 + + +def main(): + """Run the benchmarks.""" + print_version() + + name = "::instantiation" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], dtype='float64'); shape = [3, 2]; strides = [2, 1]; offset = 0; order = 'C';" + stmt = "y = np.ndarray(buffer=x, shape=shape, strides=strides, offset=offset, order=order)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::get:data" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.data" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:dtype" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.dtype" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:flags" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.flags" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:length" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.size" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:BYTES_PER_ELEMENT" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.itemsize" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:byteLength" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.nbytes" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:ndims" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.ndim" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:shape" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.shape" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:strides" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.strides" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = ":get" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y[int(floor(random()*3.0)), 1]" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = ":set" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y[int(floor(random()*3.0)), 1] = random()" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = ":iget" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y.item(int(floor(random()*4.0)))" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = ":iset" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y.itemset(int(floor(random()*4.0)), random())" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + print_summary(COUNT[0], COUNT[0]) + + +if __name__ == "__main__": + main() diff --git a/base/ctor/docs/types/index.d.ts b/base/ctor/docs/types/index.d.ts index eee4e73f..d4becb7e 100644 --- a/base/ctor/docs/types/index.d.ts +++ b/base/ctor/docs/types/index.d.ts @@ -19,36 +19,119 @@ // TypeScript Version: 2.0 /// -/// import { ArrayLike } from '@stdlib/types/array'; -import { ndarray, Order } from '@stdlib/types/ndarray'; +import { ndarray, DataType, Order } from '@stdlib/types/ndarray'; import { Buffer } from 'buffer'; +/** +* Interface defining a ndarray constructor which is both "newable" and "callable". +*/ +interface Constructor { + /** + * ndarray constructor. + * + * ## Notes + * + * - To create a zero-dimensional array, + * + * ```javascript + * var buffer = [ 1 ]; + * var shape = []; + * var strides = [ 0 ]; + * var offset = 0; + * + * var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + * ``` + * + * @param dtype - data type + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @returns ndarray instance + * + * @example + * var buffer = [ 1, 2, 3, 4, 5, 6 ]; + * var shape = [ 3, 2 ]; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = new ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + */ + new( dtype: DataType, buffer: ArrayLike | Buffer, shape: ArrayLike, strides: ArrayLike, offset: number, order: Order ): ndarray; // tslint-disable-line max-line-length + + /** + * ndarray constructor. + * + * ## Notes + * + * - To create a zero-dimensional array, + * + * ```javascript + * var buffer = [ 1 ]; + * var shape = []; + * var strides = [ 0 ]; + * var offset = 0; + * + * var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + * ``` + * + * @param dtype - data type + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @returns ndarray instance + * + * @example + * var buffer = [ 1, 2, 3, 4, 5, 6 ]; + * var shape = [ 3, 2 ]; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + */ + ( dtype: DataType, buffer: ArrayLike | Buffer, shape: ArrayLike, strides: ArrayLike, offset: number, order: Order ): ndarray; // tslint-disable-line max-line-length +} /** -* Converts an ndarray buffer to a generic array (which may include nested arrays). +* ndarray constructor. +* +* ## Notes +* +* - To create a zero-dimensional array, +* +* ```javascript +* var buffer = [ 1 ]; +* var shape = []; +* var strides = [ 0 ]; +* var offset = 0; +* +* var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); +* ``` * +* @param dtype - data type * @param buffer - data buffer * @param shape - array shape * @param strides - array strides * @param offset - index offset * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) -* @returns array (which may include nested arrays) +* @returns ndarray instance * * @example -* var buffer = [ 1, 2, 3, 4 ]; -* var shape = [ 2, 2 ]; -* var order = 'row-major'; +* var buffer = [ 1, 2, 3, 4, 5, 6 ]; +* var shape = [ 3, 2 ]; * var strides = [ 2, 1 ]; * var offset = 0; * -* var out = ndarray2array( buffer, shape, strides, offset, order ); -* // returns [ [ 1, 2 ], [ 3, 4 ] ] +* var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); */ -declare function ndarray2array( buffer: ArrayLike | Buffer, shape: ArrayLike, strides: ArrayLike, offset: number, order: Order ): Array; // tslint-disable-line max-line-length +declare var ctor: Constructor; // EXPORTS // -export = ndarray2array; +export = ctor; diff --git a/base/ctor/docs/types/test.ts b/base/ctor/docs/types/test.ts index 725e37e3..f3c5b4e3 100644 --- a/base/ctor/docs/types/test.ts +++ b/base/ctor/docs/types/test.ts @@ -16,92 +16,114 @@ * limitations under the License. */ -import ndarray2array = require( './index' ); +// tslint:disable:no-unused-expression + +import ndarray = require( './index' ); // TESTS // -// The function returns an array... +// The function returns an ndarray... { - ndarray2array( [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'row-major' ); // $ExpectType any[] - ndarray2array( [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'column-major' ); // $ExpectType any[] + ndarray( 'float64', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'row-major' ); // $ExpectType ndarray + new ndarray( 'float64', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'row-major' ); // $ExpectType ndarray + + const buffer = new Int32Array( [ 1, 2, 3 ] ); + ndarray( 'int32', buffer, [ 2, 2 ], [ 2, 1 ], 0, 'column-major' ); // $ExpectType ndarray + new ndarray( 'int32', buffer, [ 2, 2 ], [ 2, 1 ], 0, 'column-major' ); // $ExpectType ndarray } -// The function does not compile if provided a first argument which is not an array-like object or buffer... +// The function does not compile if provided a first argument which is not a recognized data type... { + const buffer = [ 1, 2, 3, 4 ]; const shape = [ 2, 2 ]; const strides = [ 2, 1 ]; const offset = 0; const order = 'row-major'; - ndarray2array( 123, shape, strides, offset, order ); // $ExpectError - ndarray2array( true, shape, strides, offset, order ); // $ExpectError - ndarray2array( false, shape, strides, offset, order ); // $ExpectError - ndarray2array( null, shape, strides, offset, order ); // $ExpectError - ndarray2array( undefined, shape, strides, offset, order ); // $ExpectError + + ndarray( 'abc', buffer, shape, strides, offset, order ); // $ExpectError + ndarray( 123, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( true, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( false, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( null, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( undefined, buffer, shape, strides, offset, order ); // $ExpectError } -// The function does not compile if provided a second argument which is not an array-like object containing numbers... +// The function does not compile if provided a second argument which is not an array-like object or buffer... { - const buffer = [ 1, 2, 3, 4 ]; + const shape = [ 2, 2 ]; const strides = [ 2, 1 ]; const offset = 0; const order = 'row-major'; - ndarray2array( buffer, true, strides, offset, order ); // $ExpectError - ndarray2array( buffer, false, strides, offset, order ); // $ExpectError - ndarray2array( buffer, null, strides, offset, order ); // $ExpectError - ndarray2array( buffer, undefined, strides, offset, order ); // $ExpectError - ndarray2array( buffer, '5', strides, offset, order ); // $ExpectError - ndarray2array( buffer, [ '1', '2' ], strides, offset, order ); // $ExpectError - ndarray2array( buffer, {}, strides, offset, order ); // $ExpectError - ndarray2array( buffer, ( x: number ): number => x, strides, offset, order ); // $ExpectError + ndarray( 'float64', 123, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', true, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', false, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', null, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', undefined, shape, strides, offset, order ); // $ExpectError } // The function does not compile if provided a third argument which is not an array-like object containing numbers... +{ + const buffer = [ 1, 2, 3, 4 ]; + const strides = [ 2, 1 ]; + const offset = 0; + const order = 'row-major'; + ndarray( 'float64', buffer, true, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, false, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, null, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, undefined, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, '5', strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, [ '1', '2' ], strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, {}, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, ( x: number ): number => x, strides, offset, order ); // $ExpectError +} + +// The function does not compile if provided a fourth argument which is not an array-like object containing numbers... { const buffer = [ 1, 2, 3, 4 ]; const shape = [ 2, 2 ]; const offset = 0; const order = 'row-major'; - ndarray2array( buffer, shape, true, offset, order ); // $ExpectError - ndarray2array( buffer, shape, false, offset, order ); // $ExpectError - ndarray2array( buffer, shape, null, offset, order ); // $ExpectError - ndarray2array( buffer, shape, undefined, offset, order ); // $ExpectError - ndarray2array( buffer, shape, '5', offset, order ); // $ExpectError - ndarray2array( buffer, shape, [ '1', '2' ], offset, order ); // $ExpectError - ndarray2array( buffer, shape, {}, offset, order ); // $ExpectError - ndarray2array( buffer, shape, ( x: number ): number => x, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, true, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, false, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, null, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, undefined, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, '5', offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, [ '1', '2' ], offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, {}, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, ( x: number ): number => x, offset, order ); // $ExpectError } -// The function does not compile if provided a fourth argument which is not a number... +// The function does not compile if provided a fifth argument which is not a number... { const buffer = [ 1, 2, 3, 4 ]; const shape = [ 2, 2 ]; const strides = [ 2, 1 ]; const order = 'row-major'; - ndarray2array( buffer, shape, strides, true, order ); // $ExpectError - ndarray2array( buffer, shape, strides, false, order ); // $ExpectError - ndarray2array( buffer, shape, strides, null, order ); // $ExpectError - ndarray2array( buffer, shape, strides, undefined, order ); // $ExpectError - ndarray2array( buffer, shape, strides, '5', order ); // $ExpectError - ndarray2array( buffer, shape, strides, [ '1', '2' ], order ); // $ExpectError - ndarray2array( buffer, shape, strides, {}, order ); // $ExpectError - ndarray2array( buffer, shape, strides, ( x: number ): number => x, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, true, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, false, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, null, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, undefined, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, '5', order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, [ '1', '2' ], order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, {}, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, ( x: number ): number => x, order ); // $ExpectError } -// The function does not compile if provided a fifth argument which is not a known array order... +// The function does not compile if provided a sixth argument which is not a known array order... { const buffer = [ 1, 2, 3, 4 ]; const shape = [ 2, 2 ]; const strides = [ 2, 1 ]; const offset = 0; - ndarray2array( buffer, shape, strides, offset, true ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, false ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, null ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, undefined ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, '5' ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, [ '1', '2' ] ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, {} ); // $ExpectError - ndarray2array( buffer, shape, strides, offset, ( x: number ): number => x ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, true ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, false ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, null ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, undefined ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, '5' ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, [ '1', '2' ] ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, {} ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, ( x: number ): number => x ); // $ExpectError } // The function does not compile if provided insufficient arguments... @@ -110,9 +132,10 @@ import ndarray2array = require( './index' ); const shape = [ 2, 2 ]; const strides = [ 2, 1 ]; const offset = 0; - ndarray2array(); // $ExpectError - ndarray2array( buffer ); // $ExpectError - ndarray2array( buffer, shape ); // $ExpectError - ndarray2array( buffer, shape, strides ); // $ExpectError - ndarray2array( buffer, shape, strides, offset ); // $ExpectError + ndarray(); // $ExpectError + ndarray( 'uint32' ); // $ExpectError + ndarray( 'int8', buffer ); // $ExpectError + ndarray( 'uint8c', buffer, shape ); // $ExpectError + ndarray( 'uint8', buffer, shape, strides ); // $ExpectError + ndarray( 'uint16', buffer, shape, strides, offset ); // $ExpectError } diff --git a/base/ctor/examples/index.js b/base/ctor/examples/index.js new file mode 100644 index 00000000..7fa08fe7 --- /dev/null +++ b/base/ctor/examples/index.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var Float32Array = require( '@stdlib/array/float32' ); +var ndarray = require( './../lib' ); + +// Create a data buffer: +var buffer = new Float32Array( (3*3*3*3) + 100 ); + +// Specify the array shape: +var shape = [ 3, 3, 3, 3 ]; + +// Specify the array strides: +var strides = [ 27, 9, 3, 1 ]; + +// Specify the index offset: +var offset = 4; + +// Specify the order: +var order = 'row-major'; // C-style + +// Create a new ndarray: +var arr = ndarray( 'float32', buffer, shape, strides, offset, order ); + +// Retrieve an array value: +var v = arr.get( 1, 2, 1, 2 ); +console.log( v ); +// => 0.0 + +// Set an array value: +arr.set( 1, 2, 1, 2, 10.0 ); + +// Retrieve the array value: +v = arr.get( 1, 2, 1, 2 ); +console.log( v ); +// => 10.0 + +// Serialize the array as a string: +console.log( arr.toString() ); +// => "ndarray( new Float32Array( 'float32', [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ), [ 3, 3, 3, 3 ], [ 27, 9, 3, 1 ], 0, 'row-major' )" + +// Serialize the array as JSON: +console.log( JSON.stringify( arr.toJSON() ) ); +// => '{"type":"ndarray","dtype":"float32","flags":{},"order":"row-major","shape":[3,3,3,3],"strides":[27,9,3,1],"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}' diff --git a/base/ctor/test/test.js b/base/ctor/test/test.js new file mode 100644 index 00000000..8a5991fe --- /dev/null +++ b/base/ctor/test/test.js @@ -0,0 +1,4018 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var proxyquire = require( 'proxyquire' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var Complex128Array = require( '@stdlib/array/complex128' ); +var Complex64 = require( '@stdlib/complex/float32' ); +var Complex128 = require( '@stdlib/complex/float64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var instanceOf = require( '@stdlib/assert/instance-of' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive; +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var isPlainObject = require( '@stdlib/assert/is-plain-object' ); +var isDataView = require( '@stdlib/assert/is-dataview' ); +var IS_LITTLE_ENDIAN = require( '@stdlib/assert/is-little-endian' ); +var real = require( '@stdlib/complex/real' ); +var imag = require( '@stdlib/complex/imag' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ).enum; +var modes = require( '@stdlib/ndarray/index-modes' ).enum; +var orders = require( '@stdlib/ndarray/orders' ).enum; +var ndarray = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); +var MODES = modes(); +var ORDERS = orders(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor does not require the `new` keyword', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the function supports creating zero-dimensional ndarrays', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'an ndarray has a `byteLength` property specifying the size (in bytes) of the array (typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `byteLength` property specifying the size (in bytes) of the array (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `byteLength` property specifying the size (in bytes) of the array (typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `byteLength` property specifying the size (in bytes) of the array (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `byteLength` property specifying the size (in bytes) of an array (generic)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( arr.byteLength, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `byteLength` property specifying the size (in bytes) of an array (generic; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( arr.byteLength, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (generic)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (generic; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `data` property pointing to the underlying data buffer', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `data` property pointing to the underlying data buffer (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `data` property pointing to the underlying data buffer (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `dtype` property specifying the underlying data type', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `dtype` property specifying the underlying data type (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `dtype` property specifying the underlying data type (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `flags` property providing information regarding the memory layout of the array (row-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `flags` property providing information regarding the memory layout of the array (column-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `flags` property providing information regarding the memory layout of the array (row-major and column-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `flags` property providing information regarding the memory layout of the array (row-major and column-major contiguous; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `flags` property providing information regarding the memory layout the array (neither row-major nor column-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + shape = [ 2, 2, 2 ]; + order = 'column-major'; + strides = [ 4, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `length` property specifying the number of array elements', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `length` property specifying the number of array elements (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `length` property specifying the number of array elements (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `ndims` property specifying the number of array dimensions', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'ndims' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'ndims' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.ndims ), true, 'is a positive integer' ); + t.strictEqual( arr.ndims, shape.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `ndims` property specifying the number of array dimensions (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'ndims' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'ndims' ), true, 'has property' ); + t.strictEqual( arr.ndims, shape.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `offset` property specifying the location of the first indexed element', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `offset` property specifying the location of the first indexed element (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ] ); // eslint-disable-line max-len + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `offset` property specifying the location of the first indexed element (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `order` property specifying the array order (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `order` property specifying the array order (row-major; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `order` property specifying the array order (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has an `order` property specifying the array order (column-major; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `shape` property specifying the array shape (dimensions)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'shape' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'shape' ), true, 'has property' ); + t.notEqual( arr.shape, shape, 'returns a copy' ); + t.deepEqual( arr.shape, shape, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `shape` property specifying the array shape (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'shape' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'shape' ), true, 'has property' ); + t.notEqual( arr.shape, shape, 'returns a copy' ); + t.deepEqual( arr.shape, shape, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `strides` property specifying how to access array elements along corresponding dimensions', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'strides' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'strides' ), true, 'has property' ); + t.notEqual( arr.strides, strides, 'returns a copy' ); + t.deepEqual( arr.strides, strides, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `strides` property specifying how to access array elements along corresponding dimensions (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'strides' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'strides' ), true, 'has property' ); + t.notEqual( arr.strides, strides, 'returns a copy' ); + t.deepEqual( arr.strides, strides, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (row-major; complex dtype)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + v = arr.get( 0, 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.get( 0, 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.get( 1, 0 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( 1, 1 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get( 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (column-major; complex dtype)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + v = arr.get( 0, 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.get( 0, 1 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( 1, 0 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.get( 1, 1 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `get` method for retrieving an array element using subscripts (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + + t.strictEqual( arr.get(), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major; noncontiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (row-major; noncontiguous; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ] ); // eslint-disable-line max-len + shape = [ 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major; noncontiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 4, 8 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (column-major; noncontiguous; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ] ); // eslint-disable-line max-len + shape = [ 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 4, 8 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.strictEqual( arr.iget(), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has an `iget` method for retrieving an array element using a linear index (0d; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + v = arr.iget(); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, new Complex64( 9.0, 10.0 ) ); + arr.set( 0, 1, new Complex64( 11.0, 12.0 ) ); + arr.set( 1, 0, new Complex64( 13.0, 14.0 ) ); + arr.set( 1, 1, new Complex64( 15.0, 16.0 ) ); + + v = arr.get( 0, 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.get( 0, 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.get( 1, 0 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.get( 1, 1 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 5.0, 8.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 8.0, 5.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 6.0, 7.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 0, 0, new Complex64( 9.0, 10.0 ) ); + arr.set( 0, 1, new Complex64( 11.0, 12.0 ) ); + arr.set( 1, 0, new Complex64( 13.0, 14.0 ) ); + arr.set( 1, 1, new Complex64( 15.0, 16.0 ) ); + + v = arr.get( 0, 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.get( 0, 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.get( 1, 0 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.get( 1, 1 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 9.0, 10.0, 13.0, 14.0, 11.0, 12.0, 15.0, 16.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a `set` method for setting an array element using subscripts (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + + arr.set( 5.0 ); + + t.strictEqual( arr.get(), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 5.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major; noncontiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ]; + shape = [ 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, -5.0 ); + arr.iset( 1, -6.0 ); + arr.iset( 2, -7.0 ); + arr.iset( 3, -8.0 ); + + t.strictEqual( arr.iget( 0 ), -5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), -6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), -7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), -8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ -5.0, -6.0, 3.0, 4.0, -7.0, -8.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( 9.0, 10.0 ) ); + arr.iset( 1, new Complex64( 11.0, 12.0 ) ); + arr.iset( 2, new Complex64( 13.0, 14.0 ) ); + arr.iset( 3, new Complex64( 15.0, 16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( 9.0, 10.0 ) ); + arr.iset( 1, new Complex64( 11.0, 12.0 ) ); + arr.iset( 2, new Complex64( 13.0, 14.0 ) ); + arr.iset( 3, new Complex64( 15.0, 16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 13.0, 14.0, 15.0, 16.0, 9.0, 10.0, 11.0, 12.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( 9.0, 10.0 ) ); + arr.iset( 1, new Complex64( 11.0, 12.0 ) ); + arr.iset( 2, new Complex64( 13.0, 14.0 ) ); + arr.iset( 3, new Complex64( 15.0, 16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 15.0, 16.0, 13.0, 14.0, 11.0, 12.0, 9.0, 10.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (row-major; noncontiguous; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 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 ] ); // eslint-disable-line max-len + shape = [ 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( -9.0, -10.0 ) ); + arr.iset( 1, new Complex64( -11.0, -12.0 ) ); + arr.iset( 2, new Complex64( -13.0, -14.0 ) ); + arr.iset( 3, new Complex64( -15.0, -16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), -9.0, 'returns expected value' ); + t.strictEqual( imag( v ), -10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), -11.0, 'returns expected value' ); + t.strictEqual( imag( v ), -12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), -13.0, 'returns expected value' ); + t.strictEqual( imag( v ), -14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), -15.0, 'returns expected value' ); + t.strictEqual( imag( v ), -16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ -9.0, -10.0, 3.0, 4.0, -11.0, -12.0, 7.0, 8.0, -13.0, -14.0, 11.0, 12.0, -15.0, -16.0, 15.0, 16.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7, 8, 5, 6 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major; noncontiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ]; + shape = [ 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 4, 8 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, -5.0 ); + arr.iset( 1, -6.0 ); + arr.iset( 2, -7.0 ); + arr.iset( 3, -8.0 ); + + t.strictEqual( arr.iget( 0 ), -5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), -6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), -7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), -8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ -5.0, -6.0, 3.0, 4.0, -7.0, -8.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( 9.0, 10.0 ) ); + arr.iset( 1, new Complex64( 11.0, 12.0 ) ); + arr.iset( 2, new Complex64( 13.0, 14.0 ) ); + arr.iset( 3, new Complex64( 15.0, 16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( 9.0, 10.0 ) ); + arr.iset( 1, new Complex64( 11.0, 12.0 ) ); + arr.iset( 2, new Complex64( 13.0, 14.0 ) ); + arr.iset( 3, new Complex64( 15.0, 16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 13.0, 14.0, 15.0, 16.0, 9.0, 10.0, 11.0, 12.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( 9.0, 10.0 ) ); + arr.iset( 1, new Complex64( 11.0, 12.0 ) ); + arr.iset( 2, new Complex64( 13.0, 14.0 ) ); + arr.iset( 3, new Complex64( 15.0, 16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), 9.0, 'returns expected value' ); + t.strictEqual( imag( v ), 10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), 11.0, 'returns expected value' ); + t.strictEqual( imag( v ), 12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), 13.0, 'returns expected value' ); + t.strictEqual( imag( v ), 14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), 15.0, 'returns expected value' ); + t.strictEqual( imag( v ), 16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 15.0, 16.0, 13.0, 14.0, 11.0, 12.0, 9.0, 10.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (column-major; noncontiguous; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 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 ] ); // eslint-disable-line max-len + shape = [ 2, 2, 1 ]; + order = 'column-major'; + strides = [ 4, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( 0, new Complex64( -9.0, -10.0 ) ); + arr.iset( 1, new Complex64( -11.0, -12.0 ) ); + arr.iset( 2, new Complex64( -13.0, -14.0 ) ); + arr.iset( 3, new Complex64( -15.0, -16.0 ) ); + + v = arr.iget( 0 ); + t.strictEqual( real( v ), -9.0, 'returns expected value' ); + t.strictEqual( imag( v ), -10.0, 'returns expected value' ); + v = arr.iget( 1 ); + t.strictEqual( real( v ), -11.0, 'returns expected value' ); + t.strictEqual( imag( v ), -12.0, 'returns expected value' ); + v = arr.iget( 2 ); + t.strictEqual( real( v ), -13.0, 'returns expected value' ); + t.strictEqual( imag( v ), -14.0, 'returns expected value' ); + v = arr.iget( 3 ); + t.strictEqual( real( v ), -15.0, 'returns expected value' ); + t.strictEqual( imag( v ), -16.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ -9.0, -10.0, 3.0, 4.0, -11.0, -12.0, 7.0, 8.0, -13.0, -14.0, 11.0, 12.0, -15.0, -16.0, 15.0, 16.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( -5.0 ); + + t.strictEqual( arr.iget(), -5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, -5.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has an `iset` method for setting an array element using a linear index (0d; complex type)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + arr.iset( new Complex64( -5.0, -6.0 ) ); + + v = arr.iget(); + t.strictEqual( real( v ), -5.0, 'returns expected value' ); + t.strictEqual( imag( v ), -6.0, 'returns expected value' ); + + t.deepEqual( buffer, new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, -5.0, -6.0, 7.0, 8.0 ] ), 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (row-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 3, 4, 5, 6 ], [ 2, 2 ], [ 2, 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (column-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 4, 3, 2, 1 ], [ 2, 2 ], [ 1, 2 ], 0, \'column-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex64\', new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ), [ 2, 2 ], [ 2, 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex128'; + buffer = new Complex128Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex128\', new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ), [ 2, 2 ], [ 2, 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (0d)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 4 ], [], [ 0 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (large array)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = new Array( 1e4 ); + shape = [ buffer.length ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + buffer[ 0 ] = 1.0; + buffer[ 1 ] = 2.0; + buffer[ 2 ] = 3.0; + buffer[ buffer.length-3 ] = 4.0; + buffer[ buffer.length-2 ] = 5.0; + buffer[ buffer.length-1 ] = 6.0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 1, 2, 3, ..., 4, 5, 6 ], [ 10000 ], [ 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (large array; complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( 1e4 ); + shape = [ buffer.length ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + buffer.set( new Complex64( 1.0, 1.0 ), 0 ); + buffer.set( new Complex64( 2.0, 2.0 ), 1 ); + buffer.set( new Complex64( 3.0, 3.0 ), 2 ); + buffer.set( new Complex64( 4.0, 4.0 ), buffer.length-3 ); + buffer.set( new Complex64( 5.0, 5.0 ), buffer.length-2 ); + buffer.set( new Complex64( 6.0, 6.0 ), buffer.length-1 ); + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex64\', new Complex64Array( [ 1, 1, 2, 2, 3, 3, ..., 4, 4, 5, 5, 6, 6 ] ), [ 10000 ], [ 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toString()` method (large array; complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex128'; + buffer = new Complex128Array( 1e4 ); + shape = [ buffer.length ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + buffer.set( new Complex128( 1.0, 1.0 ), 0 ); + buffer.set( new Complex128( 2.0, 2.0 ), 1 ); + buffer.set( new Complex128( 3.0, 3.0 ), 2 ); + buffer.set( new Complex128( 4.0, 4.0 ), buffer.length-3 ); + buffer.set( new Complex128( 5.0, 5.0 ), buffer.length-2 ); + buffer.set( new Complex128( 6.0, 6.0 ), buffer.length-1 ); + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex128\', new Complex128Array( [ 1, 1, 2, 2, 3, 3, ..., 4, 4, 5, 5, 6, 6 ] ), [ 10000 ], [ 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toJSON()` method (row-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'float64', + 'data': [ 3.0, 4.0, 5.0, 6.0 ], + 'shape': [ 2, 2 ], + 'strides': [ 2, 1 ], + 'order': 'row-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toJSON()` method (column-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'generic', + 'data': [ 4.0, 3.0, 2.0, 1.0 ], + 'shape': [ 2, 2 ], + 'strides': [ 1, 2 ], + 'order': 'column-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toJSON()` method (complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'complex64', + 'data': [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ], + 'shape': [ 2, 2 ], + 'strides': [ 2, 1 ], + 'order': 'row-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a custom `toJSON()` method (0d)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'generic', + 'data': [ 3.0 ], + 'shape': [], + 'strides': [ 0 ], + 'order': 'row-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray has a protocol method for serializing meta data to a DataView', function test( t ) { + /* eslint-disable no-underscore-dangle */ + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, '__array_meta_dataview__' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, '__array_meta_dataview__' ), true, 'has property' ); + t.strictEqual( isFunction( arr.__array_meta_dataview__ ), true, 'has method' ); + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'throw' ], + 'nsubmodes': 1, + 'submodes': [ MODES[ 'throw' ] ] + }; + + arr.__meta_dataview__ = null; + actual = arr.__array_meta_dataview__(); + arr.__meta_dataview__ = null; + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(1*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*arr.BYTES_PER_ELEMENT, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*arr.BYTES_PER_ELEMENT, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*arr.BYTES_PER_ELEMENT, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*arr.BYTES_PER_ELEMENT, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*arr.BYTES_PER_ELEMENT, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*arr.BYTES_PER_ELEMENT, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } + t.end(); + + /* eslint-enable no-underscore-dangle */ +}); + +tape( 'an ndarray has a protocol method for serializing meta data to a DataView (no BigInt support)', function test( t ) { + /* eslint-disable no-underscore-dangle */ + var expected; + var strides; + var ndarray; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + ndarray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-bigint-support': hasSupport + }); + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, '__array_meta_dataview__' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, '__array_meta_dataview__' ), true, 'has property' ); + t.strictEqual( isFunction( arr.__array_meta_dataview__ ), true, 'has method' ); + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'throw' ], + 'nsubmodes': 1, + 'submodes': [ MODES[ 'throw' ] ] + }; + + arr.__meta_dataview__ = null; + actual = arr.__array_meta_dataview__(); + arr.__meta_dataview__ = null; + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(1*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*arr.BYTES_PER_ELEMENT, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*arr.BYTES_PER_ELEMENT, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*arr.BYTES_PER_ELEMENT, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*arr.BYTES_PER_ELEMENT, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*arr.BYTES_PER_ELEMENT, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*arr.BYTES_PER_ELEMENT, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } + t.end(); + + function hasSupport() { + return false; + } + + /* eslint-enable no-underscore-dangle */ +}); + +tape( 'an ndarray has a protocol method for serializing meta data to a DataView (cached)', function test( t ) { + /* eslint-disable no-underscore-dangle */ + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var dv1; + var dv2; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.__meta_dataview__ = null; + dv1 = arr.__array_meta_dataview__(); + dv2 = arr.__array_meta_dataview__(); + arr.__meta_dataview__ = null; + + t.strictEqual( dv1, dv2, 'returns cached meta data' ); + + t.end(); + + /* eslint-enable no-underscore-dangle */ +}); + +tape( 'an ndarray has a protocol method for serializing meta data to a DataView (cached)', function test( t ) { + /* eslint-disable no-underscore-dangle */ + var ndarray; + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var dv1; + var dv2; + + ndarray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-bigint-support': hasSupport + }); + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.__meta_dataview__ = null; + dv1 = arr.__array_meta_dataview__(); + dv2 = arr.__array_meta_dataview__(); + arr.__meta_dataview__ = null; + + t.strictEqual( dv1, dv2, 'returns cached meta data' ); + + t.end(); + + function hasSupport() { + return false; + } + + /* eslint-enable no-underscore-dangle */ +}); diff --git a/base/docs/types/index.d.ts b/base/docs/types/index.d.ts new file mode 100644 index 00000000..6d4053d9 --- /dev/null +++ b/base/docs/types/index.d.ts @@ -0,0 +1,1054 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +// TypeScript Version: 2.0 + +/* tslint:disable:max-line-length */ +/* tslint:disable:max-file-line-count */ + +import assert = require( '@stdlib/ndarray/base/assert' ); +import bind2vind = require( '@stdlib/ndarray/base/bind2vind' ); +import broadcastShapes = require( '@stdlib/ndarray/base/broadcast-shapes' ); +import buffer = require( '@stdlib/ndarray/base/buffer' ); +import bufferCtors = require( '@stdlib/ndarray/base/buffer-ctors' ); +import bufferDataType = require( '@stdlib/ndarray/base/buffer-dtype' ); +import bufferDataTypeEnum = require( '@stdlib/ndarray/base/buffer-dtype-enum' ); +import bytesPerElement = require( '@stdlib/ndarray/base/bytes-per-element' ); +import clampIndex = require( '@stdlib/ndarray/base/clamp-index' ); +import ndarray = require( '@stdlib/ndarray/base/ctor' ); +import dtypeChar = require( '@stdlib/ndarray/base/dtype-char' ); +import dtypes2signatures = require( '@stdlib/ndarray/base/dtypes2signatures' ); +import ind = require( '@stdlib/ndarray/base/ind' ); +import ind2sub = require( '@stdlib/ndarray/base/ind2sub' ); +import iterationOrder = require( '@stdlib/ndarray/base/iteration-order' ); +import maxViewBufferIndex = require( '@stdlib/ndarray/base/max-view-buffer-index' ); +import minViewBufferIndex = require( '@stdlib/ndarray/base/min-view-buffer-index' ); +import minmaxViewBufferIndex = require( '@stdlib/ndarray/base/minmax-view-buffer-index' ); +import nonsingletonDimensions = require( '@stdlib/ndarray/base/nonsingleton-dimensions' ); +import numel = require( '@stdlib/ndarray/base/numel' ); +import serializeMetaData = require( '@stdlib/ndarray/base/serialize-meta-data' ); +import shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +import singletonDimensions = require( '@stdlib/ndarray/base/singleton-dimensions' ); +import strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +import strides2order = require( '@stdlib/ndarray/base/strides2order' ); +import sub2ind = require( '@stdlib/ndarray/base/sub2ind' ); +import ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +import vind2bind = require( '@stdlib/ndarray/base/vind2bind' ); +import wrapIndex = require( '@stdlib/ndarray/base/wrap-index' ); + +/** +* Interface describing the `base` namespace. +*/ +interface Namespace { + /** + * Base ndarray assertion utilities. + */ + assert: typeof assert; + + /** + * Converts a linear index in an underlying data buffer to a linear index in an array view. + * + * @param shape - array shape + * @param strides - stride array + * @param offset - location of the first indexed value **based** on the stride array + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @param idx - linear index in an underlying data buffer + * @param mode - specifies how to handle a linear index which exceeds array dimensions + * @throws linear index must not exceed array dimensions + * @returns linear index in an array view + * + * @example + * var shape = [ 3, 3 ]; + * var strides = [ -3, 1 ]; + * var offset = 6; + * var order = 'row-major'; + * var mode = 'throw'; + * + * var ind = ns.bind2vind( shape, strides, offset, order, 7, mode ); + * // returns 1 + */ + bind2vind: typeof bind2vind; + + /** + * Broadcasts array shapes to a single shape. + * + * ## Notes + * + * - Two respective dimensions in two shape arrays are compatible if + * + * 1. the dimensions are equal. + * 2. one dimension is `1`. + * + * - The function returns `null` if provided incompatible shapes (i.e., shapes which cannot be broadcast one another). + * + * @param shapes - array shapes + * @returns broadcast shape + * + * @example + * var shapes = [ + * [ 8, 1, 6, 1 ], + * [ 7, 1, 5 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 8, 7, 6, 5 ] + * + * @example + * var shapes = [ + * [ 5, 4 ], + * [ 1 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 5, 4 ] + * + * @example + * var shapes = [ + * [ 5, 4 ], + * [ 4 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 5, 4 ] + * + * @example + * var shapes = [ + * [ 15, 3, 5 ], + * [ 15, 1, 5 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 15, 3, 5 ] + * + * @example + * var shapes = [ + * [ 15, 3, 5 ], + * [ 3, 5 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 15, 3, 5 ] + * + * @example + * var shapes = [ + * [ 15, 3, 5 ], + * [ 3, 1 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 15, 3, 5 ] + * + * @example + * var shapes = [ + * [ 8, 1, 1, 6, 1 ], + * [ 1, 7, 1, 5 ], + * [ 8, 4, 1, 6, 5 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 8, 4, 7, 6, 5 ] + * + * @example + * var shapes = [ + * [ 8, 1, 1, 6, 1 ], + * [ 0 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 8, 1, 1, 6, 0 ] + * + * @example + * var shapes = [ + * [ 8, 1, 1, 6, 1 ], + * [ 8, 0, 1, 6, 1 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 8, 0, 1, 6, 1 ] + * + * @example + * var shapes = [ + * [ 8, 8, 1, 6, 1 ], + * [ 8, 0, 1, 6, 1 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns null + * + * @example + * var shapes = [ + * [] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [] + * + * @example + * var shapes = [ + * [], + * [] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [] + * + * @example + * var shapes = []; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [] + * + * @example + * var shapes = [ + * [ 3, 2, 1 ], + * [] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 3, 2, 1 ] + * + * @example + * var shapes = [ + * [], + * [ 3, 2, 1 ] + * ]; + * + * var out = ns.broadcastShapes( shapes ); + * // returns [ 3, 2, 1 ] + */ + broadcastShapes: typeof broadcastShapes; + + /** + * Returns a zero-filled contiguous linear ndarray data buffer. + * + * @param dtype - data type + * @param size - buffer size + * @returns data buffer + * + * @example + * var buf = ns.buffer( 'float64', 3 ); + * // returns [ 0.0, 0.0, 0.0 ] + */ + buffer: typeof buffer; + + /** + * Returns an ndarray data buffer constructor. + * + * @param dtype - data type + * @returns data buffer constructor or null + * + * @example + * var ctor = ns.bufferCtors( 'float64' ); + * // returns + * + * @example + * var ctor = ns.bufferCtors( 'float' ); + * // returns null + */ + bufferCtors: typeof bufferCtors; + + /** + * Returns the data type of an ndarray data buffer. + * + * @param value - input value + * @returns data type + * + * @example + * var dt = ns.bufferDataType( [ 1, 2, 3 ] ); + * // returns 'generic' + * + * var dt = ns.bufferDataType( 'beep' ); + * // returns null + */ + bufferDataType: typeof bufferDataType; + + /** + * Returns the data type enumeration constant for a provided ndarray data buffer. + * + * @param arr - strided array + * @returns data type enumeration constant or null + * + * @example + * var Float64Array = require( `@stdlib/array/float64` ); + * + * var x = new Float64Array( 10 ); + * + * var c = ns.bufferDataTypeEnum( x ); + * // returns + */ + bufferDataTypeEnum: typeof bufferDataTypeEnum; + + /** + * Returns the number of bytes per element provided an underlying array data type. + * + * @param dtype - data type + * @returns number of bytes per element + * + * @example + * var nbytes = ns.bytesPerElement( 'float64' ); + * // returns 8 + * + * nbytes = ns.bytesPerElement( 'generic' ); + * // returns null + */ + bytesPerElement: typeof bytesPerElement; + + /** + * Restricts an index to the interval `[0,max]`. + * + * @param idx - index + * @param max - maximum index + * @returns index + * + * @example + * var idx = ns.clampIndex( -1, 10 ); + * // returns 0 + * + * idx = ns.clampIndex( 15, 10 ); + * // returns 10 + * + * idx = ns.clampIndex( 5, 10 ); + * // returns 5 + */ + clampIndex: typeof clampIndex; + + /** + * ndarray constructor. + * + * ## Notes + * + * - To create a zero-dimensional array, + * + * ```javascript + * var buffer = [ 1 ]; + * var shape = []; + * var strides = [ 0 ]; + * var offset = 0; + * + * var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + * ``` + * + * @param dtype - data type + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @returns ndarray instance + * + * @example + * var buffer = [ 1, 2, 3, 4, 5, 6 ]; + * var shape = [ 3, 2 ]; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = ns.ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + */ + ndarray: typeof ndarray; + + /** + * Returns the single letter character abbreviation for an underlying array data type. + * + * @param dtype - data type + * @returns single letter character abbreviation + * + * @example + * var ch = ns.dtypeChar( 'float64' ); + * // returns 'd' + * + * ch = ns.dtypeChar( 'generic' ); + * // returns 'o' + */ + dtypeChar: typeof dtypeChar; + + /** + * Transforms a list of array argument data types into a list of signatures. + * + * @param dtypes - list of array argument data types + * @param nin - number of input array arguments + * @param nout - number of output array arguments + * @throws first argument must be an array-like object containing strings + * @throws second argument must be a nonnegative integer + * @throws third argument must be a nonnegative integer + * @throws first argument must have at least one element + * @throws first argument must be compatible with second and third arguments + * @returns list of signatures + * + * @example + * var dtypes = [ + * 'float64', 'float64', + * 'float32', 'float32' + * ]; + * + * var sigs = ns.dtypes2signatures( dtypes, 1, 1 ); + * // returns [ '(float64) => (float64)', '(float32) => (float32)' ] + */ + dtypes2signatures: typeof dtypes2signatures; + + /** + * Returns an index given an index mode. + * + * @param idx - index + * @param max - maximum index + * @param mode - specifies how to handle an index outside the interval `[0,max]` + * @throws index out-of-bounds + * @returns index + * + * @example + * var idx = ns.ind( 2, 9, 'clamp' ); + * // returns 2 + * + * idx = ns.ind( 10, 9, 'clamp' ); + * // returns 9 + * + * idx = ns.ind( -1, 9, 'clamp' ); + * // returns 0 + * + * @example + * var idx = ns.ind( 2, 9, 'wrap' ); + * // returns 2 + * + * idx = ns.ind( 10, 9, 'wrap' ); + * // returns 0 + * + * idx = ns.ind( -1, 9, 'wrap' ); + * // returns 9 + * + * @example + * var idx = ns.ind( 2, 9, 'throw' ); + * // returns 2 + * + * idx = ns.ind( 10, 9, 'throw' ); + * // throws + * + * idx = ns.ind( -1, 9, 'throw' ); + * // throws + */ + ind: typeof ind; + + /** + * Converts a linear index to an array of subscripts. + * + * ## Notes + * + * - The function accepts the following "modes": + * + * - `throw`: throws an error when a linear index exceeds array dimensions. + * - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic. + * - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index. + * + * - When provided a stride array containing negative strides, if an `offset` is greater than `0`, the function interprets the linear index as an index into the underlying data buffer for the array, thus returning subscripts from the perspective of that buffer. If an `offset` is equal to `0`, the function treats the linear index as an index into an array view, thus returning subscripts from the perspective of that view. + * + * ```text + * Dims: 2x2 + * Buffer: [ 1, 2, 3, 4 ] + * + * View = [ a00, a01, + * a10, a11 ] + * + * Strides: 2,1 + * Offset: 0 + * + * View = [ 1, 2, + * 3, 4 ] + * + * Strides: 2,-1 + * Offset: 1 + * + * View = [ 2, 1, + * 4, 3 ] + * + * Strides: -2,1 + * Offset: 2 + * + * View = [ 3, 4, + * 1, 2 ] + * + * Strides: -2,-1 + * Offset: 3 + * + * View = [ 4, 3, + * 2, 1 ] + * ``` + * + * ```javascript + * var shape = [ 2, 2 ]; + * var order = 'row-major'; + * var strides = [ -2, 1 ]; + * var offset = 2; + * var mode = 'throw'; + * + * // From the perspective of a view... + * var s = ind2sub( shape, strides, 0, order, 0, mode ); + * // returns [ 0, 0 ] + * + * s = ind2sub( shape, strides, 0, order, 1, mode ); + * // returns [ 0, 1 ] + * + * s = ind2sub( shape, strides, 0, order, 2, mode ); + * // returns [ 1, 0 ] + * + * s = ind2sub( shape, strides, 0, order, 3, mode ); + * // returns [ 1, 1 ] + * + * // From the perspective of an underlying buffer... + * s = ind2sub( shape, strides, offset, order, 0, mode ); + * // returns [ 1, 0 ] + * + * s = ind2sub( shape, strides, offset, order, 1, mode ); + * // returns [ 1, 1 ] + * + * s = ind2sub( shape, strides, offset, order, 2, mode ); + * // returns [ 0, 0 ] + * + * s = ind2sub( shape, strides, offset, order, 3, mode ); + * // returns [ 0, 1 ] + * ``` + * + * In short, from the perspective of a view, view data is always ordered. + * + * + * @param shape - array shape + * @param strides - stride array + * @param offset - location of the first indexed value **based** on the stride array + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @param idx - linear index + * @param mode - specifies how to handle a linear index which exceeds array dimensions + * @throws linear index must not exceed array dimensions + * @returns subscripts + * + * @example + * var shape = [ 3, 3, 3 ]; + * var strides = [ 9, 6, 1 ]; + * var offset = 0; + * var order = 'row-major'; + * + * var s = ns.ind2sub( shape, strides, offset, order, 17, 'throw' ); + * // returns [ 1, 2, 2 ] + */ + ind2sub: typeof ind2sub; + + /** + * Returns array iteration order. + * + * ## Notes + * + * - Return value key: + * + * - `0`: unordered (i.e., strides of mixed sign; e.g., `[ 9, -3, 1 ]`) + * - `1`: ordered left-to-right (i.e., all nonnegative strides) + * - `-1`: ordered right-to-left (i.e., all negative strides) + * + * @param strides - stride array + * @returns iteration order + * + * @example + * var o = ns.iterationOrder( [ 2, 1 ] ); + * // returns 1 + * + * o = ns.iterationOrder( [ -2, 1 ] ); + * // returns 0 + * + * o = ns.iterationOrder( [ -2, -1 ] ); + * // returns -1 + */ + iterationOrder: typeof iterationOrder; + + /** + * Computes the maximum linear index in an underlying data buffer accessible to an array view. + * + * @param shape - array shape + * @param strides - stride array + * @param offset - index offset + * @returns linear index + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ 10, 1 ]; + * var offset = 0; + * + * var idx = ns.maxViewBufferIndex( shape, strides, offset ); + * // returns 99 + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ -10, -1 ]; + * var offset = 99; + * + * var idx = ns.maxViewBufferIndex( shape, strides, offset ); + * // returns 99 + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ 1, 10 ]; + * var offset = 0; + * + * var idx = ns.maxViewBufferIndex( shape, strides, offset ); + * // returns 99 + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ -1, -10 ]; + * var offset = 99; + * + * var idx = ns.maxViewBufferIndex( shape, strides, offset ); + * // returns 99 + */ + maxViewBufferIndex: typeof maxViewBufferIndex; + + /** + * Computes the minimum linear index in an underlying data buffer accessible to an array view. + * + * @param shape - array shape + * @param strides - stride array + * @param offset - index offset + * @returns linear index + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ 10, 1 ]; + * var offset = 10; + * + * var idx = ns.minViewBufferIndex( shape, strides, offset ); + * // returns 10 + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ -10, -1 ]; + * var offset = 109; + * + * var idx = ns.minViewBufferIndex( shape, strides, offset ); + * // returns 10 + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ 1, 10 ]; + * var offset = 10; + * + * var idx = ns.minViewBufferIndex( shape, strides, offset ); + * // returns 10 + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ -1, -10 ]; + * var offset = 109; + * + * var idx = ns.minViewBufferIndex( shape, strides, offset ); + * // returns 10 + */ + minViewBufferIndex: typeof minViewBufferIndex; + + /** + * Computes the minimum and maximum linear indices in an underlying data buffer which are accessible to an array view. + * + * @param shape - array shape + * @param strides - stride array + * @param offset - index offset + * @returns linear indices + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ 10, 1 ]; + * var offset = 10; + * + * var idx = ns.minmaxViewBufferIndex( shape, strides, offset ); + * // returns [ 10, 109 ] + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ -10, -1 ]; + * var offset = 99; + * + * var idx = ns.minmaxViewBufferIndex( shape, strides, offset ); + * // returns [ 0, 99 ] + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ 1, 10 ]; + * var offset = 10; + * + * var idx = ns.minmaxViewBufferIndex( shape, strides, offset ); + * // returns [ 10, 109 ] + * + * @example + * var shape = [ 10, 10 ]; + * var strides = [ -1, -10 ]; + * var offset = 99; + * + * var idx = ns.minmaxViewBufferIndex( shape, strides, offset ); + * // returns [ 0, 99 ] + */ + minmaxViewBufferIndex: typeof minmaxViewBufferIndex; + + /** + * Returns the number of non-singleton dimensions. + * + * ## Notes + * + * - A singleton dimension is a dimension whose size is equal to `1`. + * + * @param shape - array shape + * @returns number of non-singleton dimensions + * + * @example + * var n = ns.nonsingletonDimensions( [ 3, 3, 1, 2 ] ); + * // returns 3 + * + * @example + * var n = ns.nonsingletonDimensions( [ 1, 1 ] ); + * // returns 0 + */ + nonsingletonDimensions: typeof nonsingletonDimensions; + + /** + * Returns the number of elements in an array. + * + * @param shape - array shape + * @returns number of elements + * + * @example + * var n = ns.numel( [ 3, 3, 3 ] ); + * // returns 27 + */ + numel: typeof numel; + + /** + * Serializes ndarray meta data. + * + * ## Notes + * + * - Serialization is performed according to host byte order (endianness). + * + * - Meta data format: + * + * ```text + * | (1 byte) | (2 bytes) | (8 bytes) | (ndims*8 bytes) | (ndims*8 bytes) | (8 bytes) | (1 byte) | (1 byte) | (8 bytes) | (nsubmodes*1 bytes) | + * ``` + * + * which translates to the following `ArrayBuffer` layout: + * + * ```text + * ArrayBuffer[ + * [int8], + * [int16], + * [int64], + * [ndims*int64], + * [ndims*int64], + * [int64], + * [int8], + * [int8], + * [int64], + * [nsubmodes*int8] + * ] + * ``` + * + * where `strides` and `offset` are in units of bytes. + * + * - If the endianness is `1`, the byte order is little endian. If the endianness is `0`, the byte order is big endian. + * + * - Buffer length: + * + * ```text + * 1 + 2 + 8 + (ndims*8) + (ndims*8) + 8 + 1 + 1 + 8 + (nsubmodes*1) = 29 + (ndims*16) + nsubmodes + * ``` + * + * For example, consider a three-dimensional ndarray with one subscript index mode (submode): + * + * ```text + * 29 + (3*16) + 1 = 78 bytes + * ``` + * + * - Views: + * + * - endianness: `Int8Array( buf, 0, 1 )` + * - dtype: `Int16Array( buf, 1, 1 )` + * - ndims: `Int64Array( buf, 3, 1 )` + * - shape: `Int64Array( buf, 11, ndims )` + * - strides: `Int64Array( buf, 11+(ndims*8), ndims )` + * - offset: `Int64Array( buf, 11+(ndims*16), 1 )` + * - order: `Int8Array( buf, 19+(ndims*16), 1 )` + * - mode: `Int8Array( buf, 20+(ndims*16), 1 )` + * - nsubmodes: `Int64Array( buf, 21+(ndims*16), 1 )` + * - submodes: `Int8Array( buf, 29+(ndims*16), nsubmodes )` + * + * @param x - input ndarray + * @returns serialized meta data + * + * @example + * var array = require( `@stdlib/ndarray/array` ); + * + * var x = array( [ [ 1, 2 ], [ 3, 4 ] ] ); + * + * var dv = ns.serializeMetaData( x ); + * // returns + */ + serializeMetaData: typeof serializeMetaData; + + /** + * Generates a stride array from an array shape. + * + * @param shape - array shape + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @returns array strides + * + * @example + * var s = ns.shape2strides( [ 3, 2 ], 'row-major' ); + * // returns [ 2, 1 ] + * + * s = ns.shape2strides( [ 3, 2 ], 'column-major' ); + * // returns [ 1, 3 ] + */ + shape2strides: typeof shape2strides; + + /** + * Returns the number of singleton dimensions. + * + * ## Notes + * + * - A singleton dimension is a dimension whose size is equal to `1`. + * + * @param shape - array shape + * @returns number of singleton dimensions + * + * @example + * var n = ns.singletonDimensions( [ 3, 3, 1, 2 ] ); + * // returns 1 + * + * @example + * var n = ns.singletonDimensions( [ 2, 2 ] ); + * // returns 0 + */ + singletonDimensions: typeof singletonDimensions; + + /** + * Returns the index offset which specifies the location of the first indexed value in a multidimensional array based on a stride array. + * + * @param shape - array shape + * @param strides - stride array + * @returns offset + * + * @example + * var shape = [ 2, 3, 10 ]; + * var strides = [ 30, -10, 1 ]; + * + * var offset = ns.strides2offset( shape, strides ); + * // returns 20 + */ + strides2offset: typeof strides2offset; + + /** + * Determines the order of a multidimensional array based on a provided stride array. + * + * @param strides - stride array + * @returns order + * + * @example + * var order = ns.strides2order( [ 2, 1 ] ); + * // returns 1 + * + * @example + * var order = ns.strides2order( [ 1, 2 ] ); + * // returns 2 + * + * @example + * var order = ns.strides2order( [ 1, 1, 1 ] ); + * // returns 3 + * + * @example + * var order = ns.strides2order( [ 2, 3, 1 ] ); + * // returns 0 + */ + strides2order: typeof strides2order; + + /** + * Converts subscripts to a linear index. + * + * ## Notes + * + * - The function accepts the following "modes": + * + * - `throw`: throws an error when a subscript exceeds array dimensions. + * - `wrap`: wrap around subscripts exceeding array dimensions using modulo arithmetic. + * - `clamp`: set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension. + * + * - When provided fewer modes than dimensions, the function recycles modes using modulo arithmetic. + * + * - When provided a stride array containing negative strides, if an `offset` is greater than `0`, the function treats subscripts as mapping to a linear index in an underlying data buffer for the array, thus returning a linear index from the perspective of that buffer. If an `offset` is equal to `0`, the function treats subscripts as mapping to a linear index in an array view, thus returning a linear index from the perspective of that view. + * + * ```text + * Dims: 2x2 + * Buffer: [ 1, 2, 3, 4 ] + * + * View = [ a00, a01, + * a10, a11 ] + * + * Strides: 2,1 + * Offset: 0 + * + * View = [ 1, 2, + * 3, 4 ] + * + * Strides: 2,-1 + * Offset: 1 + * + * View = [ 2, 1, + * 4, 3 ] + * + * Strides: -2,1 + * Offset: 2 + * + * View = [ 3, 4, + * 1, 2 ] + * + * Strides: -2,-1 + * Offset: 3 + * + * View = [ 4, 3, + * 2, 1 ] + * ``` + * + * ```javascript + * var shape = [ 2, 2 ]; + * var strides = [ -2, 1 ]; + * var offset = 2; + * var mode = [ 'throw' ]; + * + * // From the perspective of a view... + * var idx = sub2ind( shape, strides, 0, 0, 0, mode ); + * // returns 0 + * + * idx = sub2ind( shape, strides, 0, 0, 1, mode ); + * // returns 1 + * + * idx = sub2ind( shape, strides, 0, 1, 0, mode ); + * // returns 2 + * + * idx = sub2ind( shape, strides, 0, 1, 1, mode ); + * // returns 3 + * + * // From the perspective of an underlying buffer... + * idx = sub2ind( shape, strides, offset, 0, 0, mode ); + * // returns 2 + * + * idx = sub2ind( shape, strides, offset, 0, 1, mode ); + * // returns 3 + * + * idx = sub2ind( shape, strides, offset, 1, 0, mode ); + * // returns 0 + * + * idx = sub2ind( shape, strides, offset, 1, 1, mode ); + * // returns 1 + * ``` + * + * In short, from the perspective of a view, view data is always ordered. + * + * + * @param shape - array shape + * @param strides - stride array + * @param offset - location of the first indexed value **based** on the stride array + * @param args - subscripts followed by a `mode` specifying how to handle subscripts which exceed array dimensions + * @param mode - specifies how to handle subscripts which exceed array dimensions + * @throws must provide subscripts which do not exceed array dimensions + * @returns linear index + * + * @example + * var shape = [ 3, 3, 3 ]; + * var strides = [ 9, 3, 1 ]; + * var offset = 0; + * var mode = [ 'throw' ] + * + * var idx = ns.sub2ind( shape, strides, offset, 1, 2, 2, mode ); + * // returns 17 + */ + sub2ind: typeof sub2ind; + + /** + * Converts an ndarray buffer to a generic array (which may include nested arrays). + * + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @returns array (which may include nested arrays) + * + * @example + * var buffer = [ 1, 2, 3, 4 ]; + * var shape = [ 2, 2 ]; + * var order = 'row-major'; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = ns.ndarray2array( buffer, shape, strides, offset, order ); + * // returns [ [ 1, 2 ], [ 3, 4 ] ] + */ + ndarray2array: typeof ndarray2array; + + /** + * Converts a linear index in an array view to a linear index in an underlying data buffer. + * + * @param shape - array shape + * @param strides - stride array + * @param offset - location of the first indexed value **based** on the stride array + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @param idx - linear index in an array view + * @param mode - specifies how to handle a linear index which exceeds array dimensions + * @throws linear index must not exceed array dimensions + * @returns linear index in an underlying data buffer + * + * @example + * var shape = [ 3, 3 ]; + * var strides = [ -3, 1 ]; + * var offset = 6; + * var order = 'row-major'; + * var mode = 'throw'; + * + * var ind = ns.vind2bind( shape, strides, offset, order, 1, mode ); + * // returns 7 + */ + vind2bind: typeof vind2bind; + + /** + * Wraps an index on the interval `[0,max]`. + * + * @param idx - index + * @param max - maximum index + * @returns index + * + * @example + * var idx = ns.wrapIndex( -1, 10 ); + * // returns 10 + * + * idx = ns.wrapIndex( 13, 10 ); + * // returns 2 + * + * idx = ns.wrapIndex( 6, 10 ); + * // returns 6 + */ + wrapIndex: typeof wrapIndex; +} + +/** +* Base ndarray. +*/ +declare var ns: Namespace; + + +// EXPORTS // + +export = ns; diff --git a/base/docs/types/test.ts b/base/docs/types/test.ts new file mode 100644 index 00000000..43ef6ea9 --- /dev/null +++ b/base/docs/types/test.ts @@ -0,0 +1,29 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* tslint:disable:no-unused-expression */ + +import base = require( './index' ); + + +// TESTS // + +// The exported value is the expected interface... +{ + base; // $ExpectType Namespace +} diff --git a/base/dtype-char/benchmark/benchmark.js b/base/dtype-char/benchmark/benchmark.js new file mode 100644 index 00000000..9f501b4c --- /dev/null +++ b/base/dtype-char/benchmark/benchmark.js @@ -0,0 +1,65 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pkg = require( './../package.json' ).name; +var dtypeChar = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var dtypes; + var dtype; + var out; + var i; + + dtypes = [ + 'float64', + 'float32', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'binary', + 'generic', + 'foobar' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + dtype = dtypes[ i%dtypes.length ]; + out = dtypeChar( dtype ); + if ( typeof out !== 'string' && out !== null ) { + b.fail( 'should return a string or null' ); + } + } + b.toc(); + if ( typeof out !== 'string' && out !== null ) { + b.fail( 'should return a string or null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/dtype-char/benchmark/c/Makefile b/base/dtype-char/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/dtype-char/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/dtype-char/benchmark/c/benchmark.c b/base/dtype-char/benchmark/c/benchmark.c new file mode 100644 index 00000000..c3df8135 --- /dev/null +++ b/base/dtype-char/benchmark/c/benchmark.c @@ -0,0 +1,149 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `dtype_char`. +*/ +#include "stdlib/ndarray/base/dtype_char.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "dtype-char" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + uint8_t ch; + double t; + int i; + + int dtypes[ 8 ] = { + STDLIB_NDARRAY_INT8, + STDLIB_NDARRAY_UINT8, + STDLIB_NDARRAY_INT16, + STDLIB_NDARRAY_UINT16, + STDLIB_NDARRAY_INT32, + STDLIB_NDARRAY_UINT32, + STDLIB_NDARRAY_FLOAT32, + STDLIB_NDARRAY_FLOAT64 + }; + enum STDLIB_NDARRAY_DTYPE dtype; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + dtype = dtypes[ (int)(i%8) ]; + ch = stdlib_ndarray_dtype_char( dtype ); + if ( ch > 254 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ch > 254 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/dtype-char/examples/index.js b/base/dtype-char/examples/index.js new file mode 100644 index 00000000..f2d05303 --- /dev/null +++ b/base/dtype-char/examples/index.js @@ -0,0 +1,45 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypeChar = require( './../lib' ); + +var dtypes; +var ch; +var i; + +dtypes = [ + 'float64', + 'float32', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'binary', + 'generic', + 'foobar' +]; + +for ( i = 0; i < dtypes.length; i++ ) { + ch = dtypeChar( dtypes[ i ] ); + console.log( '%s => %s', dtypes[ i ], ch ); +} diff --git a/base/dtype-char/test/test.js b/base/dtype-char/test/test.js new file mode 100644 index 00000000..e118806d --- /dev/null +++ b/base/dtype-char/test/test.js @@ -0,0 +1,87 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypeChar = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dtypeChar, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the single letter character abbreviation for an underlying array data type', function test( t ) { + var expected; + var values; + var ch; + var i; + + values = [ + 'float64', + 'float32', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'int64', + 'uint64', + 'binary', + 'generic', + 'complex64', + 'complex128' + ]; + + expected = [ + 'd', + 'f', + 's', + 'b', + 'a', + 'k', + 't', + 'i', + 'u', + 'l', + 'v', + 'r', + 'o', + 'c', + 'z' + ]; + for ( i = 0; i < values.length; i++ ) { + ch = dtypeChar( values[ i ] ); + t.strictEqual( ch, expected[ i ], 'returns '+expected[i]+' when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns `null` if provided an unknown/unsupported data type', function test( t ) { + var ch = dtypeChar( 'foobar' ); + t.strictEqual( ch, null, 'returns expected value' ); + t.end(); +}); diff --git a/base/dtypes2signatures/benchmark/benchmark.js b/base/dtypes2signatures/benchmark/benchmark.js new file mode 100644 index 00000000..28a5f4a4 --- /dev/null +++ b/base/dtypes2signatures/benchmark/benchmark.js @@ -0,0 +1,56 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var pkg = require( './../package.json' ).name; +var dtypes2signatures = require( './../lib' ); + + +// FIXTURES // + +var types = require( './fixtures/types.json' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var len; + var out; + var i; + + len = types.length / 2; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = dtypes2signatures( types, 1, 1 ); + if ( out.length !== len ) { + b.fail( 'should return an array of length ' + len ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/dtypes2signatures/benchmark/fixtures/types.json b/base/dtypes2signatures/benchmark/fixtures/types.json new file mode 100644 index 00000000..88f22ffd --- /dev/null +++ b/base/dtypes2signatures/benchmark/fixtures/types.json @@ -0,0 +1,65 @@ +[ + "float64", "float64", + "float64", "generic", + + "float32", "float32", + "float32", "float64", + "float32", "generic", + + "generic", "generic", + + "int32", "int32", + "int32", "uint32", + "int32", "float64", + "int32", "generic", + + "int16", "int16", + "int16", "int32", + "int16", "uint16", + "int16", "uint32", + "int16", "float32", + "int16", "float64", + "int16", "generic", + + "int8", "int8", + "int8", "int16", + "int8", "int32", + "int8", "uint8", + "int8", "uint8c", + "int8", "uint16", + "int8", "uint32", + "int8", "float32", + "int8", "float64", + "int8", "generic", + + "uint32", "uint32", + "uint32", "float64", + "uint32", "generic", + + "uint16", "int32", + "uint16", "uint16", + "uint16", "uint32", + "uint16", "float32", + "uint16", "float64", + "uint16", "generic", + + "uint8", "int16", + "uint8", "int32", + "uint8", "uint8", + "uint8", "uint8c", + "uint8", "uint16", + "uint8", "uint32", + "uint8", "float32", + "uint8", "float64", + "uint8", "generic", + + "uint8c", "int16", + "uint8c", "int32", + "uint8c", "uint8", + "uint8c", "uint8c", + "uint8c", "uint16", + "uint8c", "uint32", + "uint8c", "float32", + "uint8c", "float64", + "uint8c", "generic" +] diff --git a/base/dtypes2signatures/examples/index.js b/base/dtypes2signatures/examples/index.js new file mode 100644 index 00000000..5277eab0 --- /dev/null +++ b/base/dtypes2signatures/examples/index.js @@ -0,0 +1,92 @@ +/** +* @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. +*/ + +/* eslint-disable array-element-newline */ + +'use strict'; + +var dtypes2signatures = require( './../lib' ); + +var dtypes = [ + 'float64', 'float64', + 'float64', 'generic', + + 'float32', 'float32', + 'float32', 'float64', + 'float32', 'generic', + + 'generic', 'generic', + + 'int32', 'int32', + 'int32', 'uint32', + 'int32', 'float64', + 'int32', 'generic', + + 'int16', 'int16', + 'int16', 'int32', + 'int16', 'uint16', + 'int16', 'uint32', + 'int16', 'float32', + 'int16', 'float64', + 'int16', 'generic', + + 'int8', 'int8', + 'int8', 'int16', + 'int8', 'int32', + 'int8', 'uint8', + 'int8', 'uint8c', + 'int8', 'uint16', + 'int8', 'uint32', + 'int8', 'float32', + 'int8', 'float64', + 'int8', 'generic', + + 'uint32', 'uint32', + 'uint32', 'float64', + 'uint32', 'generic', + + 'uint16', 'int32', + 'uint16', 'uint16', + 'uint16', 'uint32', + 'uint16', 'float32', + 'uint16', 'float64', + 'uint16', 'generic', + + 'uint8', 'int16', + 'uint8', 'int32', + 'uint8', 'uint8', + 'uint8', 'uint8c', + 'uint8', 'uint16', + 'uint8', 'uint32', + 'uint8', 'float32', + 'uint8', 'float64', + 'uint8', 'generic', + + 'uint8c', 'int16', + 'uint8c', 'int32', + 'uint8c', 'uint8', + 'uint8c', 'uint8c', + 'uint8c', 'uint16', + 'uint8c', 'uint32', + 'uint8c', 'float32', + 'uint8c', 'float64', + 'uint8c', 'generic' +]; + +var sigs = dtypes2signatures( dtypes, 1, 1 ); +console.log( sigs ); diff --git a/base/dtypes2signatures/test/fixtures/types.json b/base/dtypes2signatures/test/fixtures/types.json new file mode 100644 index 00000000..88f22ffd --- /dev/null +++ b/base/dtypes2signatures/test/fixtures/types.json @@ -0,0 +1,65 @@ +[ + "float64", "float64", + "float64", "generic", + + "float32", "float32", + "float32", "float64", + "float32", "generic", + + "generic", "generic", + + "int32", "int32", + "int32", "uint32", + "int32", "float64", + "int32", "generic", + + "int16", "int16", + "int16", "int32", + "int16", "uint16", + "int16", "uint32", + "int16", "float32", + "int16", "float64", + "int16", "generic", + + "int8", "int8", + "int8", "int16", + "int8", "int32", + "int8", "uint8", + "int8", "uint8c", + "int8", "uint16", + "int8", "uint32", + "int8", "float32", + "int8", "float64", + "int8", "generic", + + "uint32", "uint32", + "uint32", "float64", + "uint32", "generic", + + "uint16", "int32", + "uint16", "uint16", + "uint16", "uint32", + "uint16", "float32", + "uint16", "float64", + "uint16", "generic", + + "uint8", "int16", + "uint8", "int32", + "uint8", "uint8", + "uint8", "uint8c", + "uint8", "uint16", + "uint8", "uint32", + "uint8", "float32", + "uint8", "float64", + "uint8", "generic", + + "uint8c", "int16", + "uint8c", "int32", + "uint8c", "uint8", + "uint8c", "uint8c", + "uint8c", "uint16", + "uint8c", "uint32", + "uint8c", "float32", + "uint8c", "float64", + "uint8c", "generic" +] diff --git a/base/dtypes2signatures/test/test.js b/base/dtypes2signatures/test/test.js new file mode 100644 index 00000000..a4d614cb --- /dev/null +++ b/base/dtypes2signatures/test/test.js @@ -0,0 +1,457 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes2signatures = require( './../lib' ); + + +// FIXTURES // + +var dtypes = require( './fixtures/types.json' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dtypes2signatures, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided a first argument which is an array-like object containing strings', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [ 'float64', 2 ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + dtypes2signatures( value, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided a second argument which is a nonnegative integer', function test( t ) { + var values; + var i; + + values = [ + '5', + -5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + dtypes2signatures( [ 'float64', 'float64' ], value, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided a third argument which is a nonnegative integer', function test( t ) { + var values; + var i; + + values = [ + '5', + -5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + dtypes2signatures( [ 'float64', 'float64' ], 1, value ); + }; + } +}); + +tape( 'the function throws an error if not provided a first argument which is compatible with the second and third arguments', function test( t ) { + var values; + var i; + + values = [ + [], + [ 'float64' ], + [ 'float64', 'float64' ], + [ 'float64', 'float64', 'float64', 'float64' ], + [ 'float64', 'float64', 'float64', 'float64', 'float64' ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), RangeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + dtypes2signatures( value, 2, 1 ); + }; + } +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (1 in, 1 out)', function test( t ) { + var expected; + var actual; + + expected = [ + '(float64) => (float64)', + '(float64) => (generic)', + + '(float32) => (float32)', + '(float32) => (float64)', + '(float32) => (generic)', + + '(generic) => (generic)', + + '(int32) => (int32)', + '(int32) => (uint32)', + '(int32) => (float64)', + '(int32) => (generic)', + + '(int16) => (int16)', + '(int16) => (int32)', + '(int16) => (uint16)', + '(int16) => (uint32)', + '(int16) => (float32)', + '(int16) => (float64)', + '(int16) => (generic)', + + '(int8) => (int8)', + '(int8) => (int16)', + '(int8) => (int32)', + '(int8) => (uint8)', + '(int8) => (uint8c)', + '(int8) => (uint16)', + '(int8) => (uint32)', + '(int8) => (float32)', + '(int8) => (float64)', + '(int8) => (generic)', + + '(uint32) => (uint32)', + '(uint32) => (float64)', + '(uint32) => (generic)', + + '(uint16) => (int32)', + '(uint16) => (uint16)', + '(uint16) => (uint32)', + '(uint16) => (float32)', + '(uint16) => (float64)', + '(uint16) => (generic)', + + '(uint8) => (int16)', + '(uint8) => (int32)', + '(uint8) => (uint8)', + '(uint8) => (uint8c)', + '(uint8) => (uint16)', + '(uint8) => (uint32)', + '(uint8) => (float32)', + '(uint8) => (float64)', + '(uint8) => (generic)', + + '(uint8c) => (int16)', + '(uint8c) => (int32)', + '(uint8c) => (uint8)', + '(uint8c) => (uint8c)', + '(uint8c) => (uint16)', + '(uint8c) => (uint32)', + '(uint8c) => (float32)', + '(uint8c) => (float64)', + '(uint8c) => (generic)' + ]; + actual = dtypes2signatures( dtypes, 1, 1 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (2 in, 0 out)', function test( t ) { + var expected; + var actual; + + expected = [ + '(float64, float64) => ()', + '(float64, generic) => ()', + + '(float32, float32) => ()', + '(float32, float64) => ()', + '(float32, generic) => ()', + + '(generic, generic) => ()', + + '(int32, int32) => ()', + '(int32, uint32) => ()', + '(int32, float64) => ()', + '(int32, generic) => ()', + + '(int16, int16) => ()', + '(int16, int32) => ()', + '(int16, uint16) => ()', + '(int16, uint32) => ()', + '(int16, float32) => ()', + '(int16, float64) => ()', + '(int16, generic) => ()', + + '(int8, int8) => ()', + '(int8, int16) => ()', + '(int8, int32) => ()', + '(int8, uint8) => ()', + '(int8, uint8c) => ()', + '(int8, uint16) => ()', + '(int8, uint32) => ()', + '(int8, float32) => ()', + '(int8, float64) => ()', + '(int8, generic) => ()', + + '(uint32, uint32) => ()', + '(uint32, float64) => ()', + '(uint32, generic) => ()', + + '(uint16, int32) => ()', + '(uint16, uint16) => ()', + '(uint16, uint32) => ()', + '(uint16, float32) => ()', + '(uint16, float64) => ()', + '(uint16, generic) => ()', + + '(uint8, int16) => ()', + '(uint8, int32) => ()', + '(uint8, uint8) => ()', + '(uint8, uint8c) => ()', + '(uint8, uint16) => ()', + '(uint8, uint32) => ()', + '(uint8, float32) => ()', + '(uint8, float64) => ()', + '(uint8, generic) => ()', + + '(uint8c, int16) => ()', + '(uint8c, int32) => ()', + '(uint8c, uint8) => ()', + '(uint8c, uint8c) => ()', + '(uint8c, uint16) => ()', + '(uint8c, uint32) => ()', + '(uint8c, float32) => ()', + '(uint8c, float64) => ()', + '(uint8c, generic) => ()' + ]; + actual = dtypes2signatures( dtypes, 2, 0 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (0 in, 2 out)', function test( t ) { + var expected; + var actual; + + expected = [ + '() => (float64, float64)', + '() => (float64, generic)', + + '() => (float32, float32)', + '() => (float32, float64)', + '() => (float32, generic)', + + '() => (generic, generic)', + + '() => (int32, int32)', + '() => (int32, uint32)', + '() => (int32, float64)', + '() => (int32, generic)', + + '() => (int16, int16)', + '() => (int16, int32)', + '() => (int16, uint16)', + '() => (int16, uint32)', + '() => (int16, float32)', + '() => (int16, float64)', + '() => (int16, generic)', + + '() => (int8, int8)', + '() => (int8, int16)', + '() => (int8, int32)', + '() => (int8, uint8)', + '() => (int8, uint8c)', + '() => (int8, uint16)', + '() => (int8, uint32)', + '() => (int8, float32)', + '() => (int8, float64)', + '() => (int8, generic)', + + '() => (uint32, uint32)', + '() => (uint32, float64)', + '() => (uint32, generic)', + + '() => (uint16, int32)', + '() => (uint16, uint16)', + '() => (uint16, uint32)', + '() => (uint16, float32)', + '() => (uint16, float64)', + '() => (uint16, generic)', + + '() => (uint8, int16)', + '() => (uint8, int32)', + '() => (uint8, uint8)', + '() => (uint8, uint8c)', + '() => (uint8, uint16)', + '() => (uint8, uint32)', + '() => (uint8, float32)', + '() => (uint8, float64)', + '() => (uint8, generic)', + + '() => (uint8c, int16)', + '() => (uint8c, int32)', + '() => (uint8c, uint8)', + '() => (uint8c, uint8c)', + '() => (uint8c, uint16)', + '() => (uint8c, uint32)', + '() => (uint8c, float32)', + '() => (uint8c, float64)', + '() => (uint8c, generic)' + ]; + actual = dtypes2signatures( dtypes, 0, 2 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (2 in, 1 out)', function test( t ) { + var expected; + var actual; + var dtypes; + + dtypes = [ 'float64', 'float64', 'generic' ]; + expected = [ '(float64, float64) => (generic)' ]; + + actual = dtypes2signatures( dtypes, 2, 1 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (3 in, 0 out)', function test( t ) { + var expected; + var actual; + var dtypes; + + dtypes = [ 'float64', 'float64', 'generic' ]; + expected = [ '(float64, float64, generic) => ()' ]; + + actual = dtypes2signatures( dtypes, 3, 0 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (1 in, 2 out)', function test( t ) { + var expected; + var actual; + var dtypes; + + dtypes = [ 'float64', 'float64', 'generic' ]; + expected = [ '(float64) => (float64, generic)' ]; + + actual = dtypes2signatures( dtypes, 1, 2 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (0 in, 3 out)', function test( t ) { + var expected; + var actual; + var dtypes; + + dtypes = [ 'float64', 'float64', 'generic' ]; + expected = [ '() => (float64, float64, generic)' ]; + + actual = dtypes2signatures( dtypes, 0, 3 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (1 in, 0 out)', function test( t ) { + var expected; + var actual; + var dtypes; + + dtypes = [ 'float64' ]; + expected = [ '(float64) => ()' ]; + + actual = dtypes2signatures( dtypes, 1, 0 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function transforms a list of array argument data types into a list of signatures (0 in, 1 out)', function test( t ) { + var expected; + var actual; + var dtypes; + + dtypes = [ 'float64' ]; + expected = [ '() => (float64)' ]; + + actual = dtypes2signatures( dtypes, 0, 1 ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); diff --git a/base/examples/index.js b/base/examples/index.js new file mode 100644 index 00000000..c7e940d8 --- /dev/null +++ b/base/examples/index.js @@ -0,0 +1,24 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var objectKeys = require( '@stdlib/utils/keys' ); +var ns = require( './../lib' ); + +console.log( objectKeys( ns ) ); diff --git a/base/function-object/examples/c/Makefile b/base/function-object/examples/c/Makefile new file mode 100644 index 00000000..70c91f4e --- /dev/null +++ b/base/function-object/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/function-object/examples/c/example.c b/base/function-object/examples/c/example.c new file mode 100644 index 00000000..a5aaa53c --- /dev/null +++ b/base/function-object/examples/c/example.c @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/function_object.h" +#include "stdlib/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include +#include +#include + +// Define the function(s) we want to apply to ndarrays: +static uint8_t scale( const uint8_t x ) { + return x * 10; +} + +int main() { + // Manually create an ndarray function object... + struct ndarrayFunctionObject *obj = malloc( sizeof( struct ndarrayFunctionObject ) ); + if ( obj == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( 1 ); + } + + // As the function to be applied is a unary function, define a unary ndarray interface: + const char name[] = "unary_ndarray_function"; + obj->name = name; + + obj->nin = 1; + obj->nout = 1; + obj->narrays = 2; // (obj->nin) + (obj->nout) + + // Define a list of ndarray functions (in this case, as the function to be applied accepts unsigned 8-bit integers, we only use ndarray functions which handle unsigned 8-bit integers as function arguments and, for the purposes of this example, we assume that the output ndarray is always an unsigned 8-bit integer array): + obj->nfunctions = 1; + + ndarrayFcn functions[] = { + stdlib_ndarray_b_b + }; + obj->functions = functions; + + // Define the **ndarray** argument types for each ndarray function: + int32_t types[] = { + STDLIB_NDARRAY_UINT8, STDLIB_NDARRAY_UINT8 + }; + obj->types = types; + + // Define a list of ndarray function "data" (in this case, callbacks): + void *data[] = { + (void *)scale + }; + obj->data = data; + + printf( "name = %s\n", obj->name ); + printf( "nin = %u\n", obj->nin ); + printf( "nout = %u\n", obj->nout ); + printf( "narrays = %u\n", obj->narrays ); + printf( "nfunctions = %u\n", obj->nfunctions ); + + // Free allocated memory: + stdlib_ndarray_function_free( obj ); + + // Use the function interface to create an ndarray function object... + struct ndarrayFunctionObject *obj2 = stdlib_ndarray_function_allocate( "unary_ndarray_function_2", 1, 1, functions, 1, types, data ); + if ( obj == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( 1 ); + } + + printf( "name = %s\n", obj2->name ); + printf( "nin = %u\n", obj2->nin ); + printf( "nout = %u\n", obj2->nout ); + printf( "narrays = %u\n", obj2->narrays ); + printf( "nfunctions = %u\n", obj2->nfunctions ); + + // Free allocated memory: + stdlib_ndarray_function_free( obj ); +} diff --git a/base/function-object/examples/index.js b/base/function-object/examples/index.js new file mode 100644 index 00000000..53706b4c --- /dev/null +++ b/base/function-object/examples/index.js @@ -0,0 +1,23 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var headerDir = require( './../lib' ); + +console.log( headerDir ); diff --git a/base/function-object/test/test.browser.js b/base/function-object/test/test.browser.js new file mode 100644 index 00000000..794230a5 --- /dev/null +++ b/base/function-object/test/test.browser.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var headerDir = require( './../lib/browser.js' ); + + +// TESTS // + +tape( 'main export is a null', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( headerDir, null, 'main export is null' ); + t.end(); +}); diff --git a/base/function-object/test/test.js b/base/function-object/test/test.js new file mode 100644 index 00000000..863a4dea --- /dev/null +++ b/base/function-object/test/test.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var tape = require( 'tape' ); +var IS_BROWSER = require( '@stdlib/assert/is-browser' ); +var headerDir = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': IS_BROWSER +}; + + +// TESTS // + +tape( 'main export is a string', opts, function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof headerDir, 'string', 'main export is a string' ); + t.end(); +}); + +tape( 'the exported value corresponds to the package directory containing header files', opts, function test( t ) { + var dir = resolve( __dirname, '..', 'include' ); + t.strictEqual( headerDir, dir, 'exports expected value' ); + t.end(); +}); diff --git a/base/ind/benchmark/benchmark.js b/base/ind/benchmark/benchmark.js new file mode 100644 index 00000000..123e8ea9 --- /dev/null +++ b/base/ind/benchmark/benchmark.js @@ -0,0 +1,94 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var ind = require( './../lib' ); + + +// MAIN // + +bench( pkg+':mode=clamp', function benchmark( b ) { + var out; + var idx; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*100.0 ) - 50.0; + out = ind( idx, 10, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap', function benchmark( b ) { + var out; + var idx; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*100.0 ) - 50.0; + out = ind( idx, 10, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw', function benchmark( b ) { + var out; + var idx; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*11.0 ); + out = ind( idx, 10, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/ind/benchmark/c/Makefile b/base/ind/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/ind/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/ind/benchmark/c/benchmark.c b/base/ind/benchmark/c/benchmark.c new file mode 100644 index 00000000..2bfa7896 --- /dev/null +++ b/base/ind/benchmark/c/benchmark.c @@ -0,0 +1,209 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `ind`. +*/ +#include "stdlib/ndarray/base/ind.h" +#include "stdlib/ndarray/index_modes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "ind" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + int64_t idx; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*100.0) - 50.0 ); + idx = stdlib_ndarray_ind( idx, 10, STDLIB_NDARRAY_INDEX_ERROR ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + int64_t idx; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*100.0) - 50.0 ); + idx = stdlib_ndarray_ind( idx, 10, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( idx < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < 0 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark3() { + double elapsed; + int64_t idx; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*100.0) - 50.0 ); + idx = stdlib_ndarray_ind( idx, 10, STDLIB_NDARRAY_INDEX_WRAP ); + if ( idx < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < 0 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap\n", NAME ); + elapsed = benchmark3(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/ind/examples/index.js b/base/ind/examples/index.js new file mode 100644 index 00000000..98efe110 --- /dev/null +++ b/base/ind/examples/index.js @@ -0,0 +1,37 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var ind = require( './../lib' ); + +var modes; +var mode; +var idx; +var out; +var i; + +modes = [ 'clamp', 'wrap' ]; + +for ( i = 0; i < 100; i++ ) { + idx = discreteUniform( -20, 20 ); + mode = modes[ discreteUniform( 0, modes.length-1 ) ]; + out = ind( idx, 9, mode ); + console.log( '%d => %s(%d,%d) => %d', idx, mode, 0, 9, out ); +} diff --git a/base/ind/test/test.js b/base/ind/test/test.js new file mode 100644 index 00000000..a9467093 --- /dev/null +++ b/base/ind/test/test.js @@ -0,0 +1,98 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var ind = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ind, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'when the `mode` is equal to "clamp", the function clamps an index to the interval [0,max]', function test( t ) { + t.strictEqual( ind( 2, 10, 'clamp' ), 2, 'returns expected value' ); + t.strictEqual( ind( -5, 10, 'clamp' ), 0, 'returns expected value' ); + t.strictEqual( ind( 15, 10, 'clamp' ), 10, 'returns expected value' ); + t.end(); +}); + +tape( 'when the `mode` is equal to "wrap", the function wraps an index on the interval [0,max]', function test( t ) { + var expected; + var values; + var i; + + values = [ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; // eslint-disable-line max-len + expected = [ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 ]; // eslint-disable-line max-len + + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( ind( values[ i ], 9, 'wrap' ), expected[ i ], 'returns expected value. idx: '+values[ i ]+'. expected: '+expected[ i ]+'.' ); + } + t.end(); +}); + +tape( 'when the `mode` is equal to "wrap", the function wraps an index on the interval [0,max]', function test( t ) { + t.strictEqual( ind( 2, 10, 'wrap' ), 2, 'returns expected value' ); + t.strictEqual( ind( 12, 10, 'wrap' ), 1, 'returns expected value' ); + t.strictEqual( ind( -2, 10, 'wrap' ), 9, 'returns expected value' ); + t.strictEqual( ind( 21, 10, 'wrap' ), 10, 'returns expected value' ); + t.strictEqual( ind( 22, 10, 'wrap' ), 0, 'returns expected value' ); + t.strictEqual( ind( 26, 10, 'wrap' ), 4, 'returns expected value' ); + t.strictEqual( ind( -21, 10, 'wrap' ), 1, 'returns expected value' ); + t.strictEqual( ind( -22, 10, 'wrap' ), 0, 'returns expected value' ); + t.strictEqual( ind( -26, 10, 'wrap' ), 7, 'returns expected value' ); + t.end(); +}); + +tape( 'when the `mode` is equal to `throw`, the function returns the index when on the interval [0,max]', function test( t ) { + var max; + var i; + + max = 10; + for ( i = 0; i < max+1; i++ ) { + t.strictEqual( ind( i, max, 'throw' ), i, 'returns expected value' ); + } + t.end(); +}); + +tape( 'when the `mode` is equal to `throw`, the function throws an error when a provided index is outside the interval [0,max]', function test( t ) { + var max; + var i; + + max = 10; + for ( i = -100; i < 0; i++ ) { + t.throws( badValue( i ), RangeError, 'throws an range error when provided '+i ); + } + for ( i = max+1; i < 100; i++ ) { + t.throws( badValue( i ), RangeError, 'throws an range error when provided '+i ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind( value, max, 'throw' ); + }; + } +}); diff --git a/base/ind2sub/README.md b/base/ind2sub/README.md index 9e2a33a0..ce67e7d6 100644 --- a/base/ind2sub/README.md +++ b/base/ind2sub/README.md @@ -301,13 +301,16 @@ for ( i = 0; i < 20; i++ ) { #include "stdlib/ndarray/base/ind2sub.h" ``` -#### stdlib_ndarray_ind2sub( ndims, \*shape, strides, offset, order, idx, mode, \*out ) + + +#### stdlib_ndarray_ind2sub( ndims, \*shape, \*strides, offset, order, idx, mode, \*out ) Computes the minimum and maximum linear indices in an underlying data buffer accessible to an array view. ```c #include "stdlib/ndarray/index_modes.h" #include "stdlib/ndarray/orders.h" +#include int64_t ndims = 2; int64_t shape[] = { 3, 3 }; @@ -359,6 +362,7 @@ int8_t stdlib_ndarray_ind2sub( int64_t ndims, int64_t *shape, int64_t *strides, #include "stdlib/ndarray/base/ind2sub.h" #include "stdlib/ndarray/index_modes.h" #include "stdlib/ndarray/orders.h" +#include #include int main() { diff --git a/base/ind2sub/benchmark/benchmark.js b/base/ind2sub/benchmark/benchmark.js new file mode 100644 index 00000000..72fbe8b9 --- /dev/null +++ b/base/ind2sub/benchmark/benchmark.js @@ -0,0 +1,716 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isNonNegativeIntegerArray = require( '@stdlib/assert/is-nonnegative-integer-array' ).primitives; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var pkg = require( './../package.json' ).name; +var ind2sub = require( './../lib' ); + + +// MAIN // + +bench( pkg+':mode=throw,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, strides, offset, order, idx, 'throw' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, strides, offset, order, idx, 'throw' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::memory_reuse:assign:mode=throw,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var s; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + out = [ 0, 0, 0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + s = ind2sub.assign( shape, strides, offset, order, idx, 'throw', out ); + if ( s !== out ) { + b.fail( 'should return output array' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( s ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::memory_reuse:assign:mode=throw,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var s; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + out = [ 0, 0, 0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + s = ind2sub.assign( shape, strides, offset, order, idx, 'throw', out ); + if ( out !== s ) { + b.fail( 'should return output array' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( s ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:offset=0,mode=throw,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, strides, offset, order, idx, 'throw' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:offset=0,mode=throw,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, strides, offset, order, idx, 'throw' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:mode=throw,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, strides, offset, order, idx, 'throw' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:mode=throw,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, strides, offset, order, idx, 'throw' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len*10) ) - (len*5); + out = ind2sub( shape, strides, offset, order, idx, 'wrap' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len*10) ) - (len*5); + out = ind2sub( shape, strides, offset, order, idx, 'wrap' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:offset=0,mode=wrap,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len*10) ) - (len*5); + out = ind2sub( shape, strides, offset, order, idx, 'wrap' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:offset=0,mode=wrap,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len*10) ) - (len*5); + out = ind2sub( shape, strides, offset, order, idx, 'wrap' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:mode=wrap,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len*10) ) - (len*5); + out = ind2sub( shape, strides, offset, order, idx, 'wrap' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:mode=wrap,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len*10) ) - (len*5); + out = ind2sub( shape, strides, offset, order, idx, 'wrap' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len+20) ) - 10.0; + out = ind2sub( shape, strides, offset, order, idx, 'clamp' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len+20) ) - 10.0; + out = ind2sub( shape, strides, offset, order, idx, 'clamp' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:offset=0,mode=clamp,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len+20) ) - 10; + out = ind2sub( shape, strides, offset, order, idx, 'clamp' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:offset=0,mode=clamp,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len+20) ) - 10; + out = ind2sub( shape, strides, offset, order, idx, 'clamp' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:mode=clamp,order=row-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len+20) ) - 10.0; + out = ind2sub( shape, strides, offset, order, idx, 'clamp' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::negative_strides:mode=clamp,order=column-major', function benchmark( b ) { + var strides; + var offset; + var order; + var shape; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = strides2offset( shape, strides ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*(len+20) ) - 10.0; + out = ind2sub( shape, strides, offset, order, idx, 'clamp' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/ind2sub/benchmark/c/Makefile b/base/ind2sub/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/ind2sub/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/ind2sub/benchmark/c/benchmark.c b/base/ind2sub/benchmark/c/benchmark.c new file mode 100644 index 00000000..70cec934 --- /dev/null +++ b/base/ind2sub/benchmark/c/benchmark.c @@ -0,0 +1,624 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `ind2sub`. +*/ +#include "stdlib/ndarray/base/ind2sub.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include +#include +#include +#include +#include +#include + +#define NAME "ind2sub" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark3() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark4() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark5() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark6() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark7() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark8() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark9() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark10() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark11() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark12() { + double elapsed; + int64_t idx; + int64_t flg; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + flg = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP, out ); + if ( flg < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( flg < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=row-major\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=column-major\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=row-major,offset=0\n", NAME ); + elapsed = benchmark3(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=column-major,offset=0\n", NAME ); + elapsed = benchmark4(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=row-major\n", NAME ); + elapsed = benchmark5(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=column-major\n", NAME ); + elapsed = benchmark6(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=row-major,offset=0\n", NAME ); + elapsed = benchmark7(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=column-major,offset=0\n", NAME ); + elapsed = benchmark8(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=row-major\n", NAME ); + elapsed = benchmark9(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=column-major\n", NAME ); + elapsed = benchmark10(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=row-major,offset=0\n", NAME ); + elapsed = benchmark11(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=column-major,offset=0\n", NAME ); + elapsed = benchmark12(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/ind2sub/benchmark/julia/REQUIRE b/base/ind2sub/benchmark/julia/REQUIRE new file mode 100644 index 00000000..98645e19 --- /dev/null +++ b/base/ind2sub/benchmark/julia/REQUIRE @@ -0,0 +1,2 @@ +julia 1.5 +BenchmarkTools 0.5.0 diff --git a/base/ind2sub/benchmark/julia/benchmark.jl b/base/ind2sub/benchmark/julia/benchmark.jl new file mode 100644 index 00000000..f9805fc9 --- /dev/null +++ b/base/ind2sub/benchmark/julia/benchmark.jl @@ -0,0 +1,144 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +import BenchmarkTools +using Printf + +# Benchmark variables: +name = "ind2sub"; +repeats = 3; + +""" + print_version() + +Prints the TAP version. + +# Examples + +``` julia +julia> print_version() +``` +""" +function print_version() + @printf( "TAP version 13\n" ); +end + +""" + print_summary( total, passing ) + +Print the benchmark summary. + +# Arguments + +* `total`: total number of tests +* `passing`: number of passing tests + +# Examples + +``` julia +julia> print_summary( 3, 3 ) +``` +""" +function print_summary( total, passing ) + @printf( "#\n" ); + @printf( "1..%d\n", total ); # TAP plan + @printf( "# total %d\n", total ); + @printf( "# pass %d\n", passing ); + @printf( "#\n" ); + @printf( "# ok\n" ); +end + +""" + print_results( iterations, elapsed ) + +Print benchmark results. + +# Arguments + +* `iterations`: number of iterations +* `elapsed`: elapsed time (in seconds) + +# Examples + +``` julia +julia> print_results( 1000000, 0.131009101868 ) +``` +""" +function print_results( iterations, elapsed ) + rate = iterations / elapsed + + @printf( " ---\n" ); + @printf( " iterations: %d\n", iterations ); + @printf( " elapsed: %0.9f\n", elapsed ); + @printf( " rate: %0.9f\n", rate ); + @printf( " ...\n" ); +end + +""" + benchmark() + +Run a benchmark. + +# Notes + +* Benchmark results are returned as a two-element array: [ iterations, elapsed ]. +* The number of iterations is not the true number of iterations. Instead, an 'iteration' is defined as a 'sample', which is a computed estimate for a single evaluation. +* The elapsed time is in seconds. + +# Examples + +``` julia +julia> out = benchmark(); +``` +""" +function benchmark() + t = BenchmarkTools.@benchmark Base._ind2sub( (10,10,10), Int32( floor( rand()*1000.0 ) ) ) samples=1e6 + + # Compute the total "elapsed" time and convert from nanoseconds to seconds: + s = sum( t.times ) / 1.0e9; + + # Determine the number of "iterations": + iter = length( t.times ); + + # Return the results: + [ iter, s ]; +end + +""" + main() + +Run benchmarks. + +# Examples + +``` julia +julia> main(); +``` +""" +function main() + print_version(); + for i in 1:repeats + @printf( "# julia::%s\n", name ); + results = benchmark(); + print_results( results[ 1 ], results[ 2 ] ); + @printf( "ok %d benchmark finished\n", i ); + end + print_summary( repeats, repeats ); +end + +main(); diff --git a/base/ind2sub/benchmark/python/numpy/benchmark.py b/base/ind2sub/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..8dbf8198 --- /dev/null +++ b/base/ind2sub/benchmark/python/numpy/benchmark.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.unravel_index.""" + +from __future__ import print_function +import timeit + +NAME = "ind2sub" +REPEATS = 3 +ITERATIONS = 1000000 + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(elapsed): + """Print benchmark results. + + # Arguments + + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(0.131009101868) + ``` + """ + rate = ITERATIONS / elapsed + + print(" ---") + print(" iterations: " + str(ITERATIONS)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(): + """Run the benchmark and print benchmark results.""" + setup = "import numpy as np; from random import random;" + stmt = "y = np.unravel_index(int(random()*1000.0), (10,10,10))" + + t = timeit.Timer(stmt, setup=setup) + + print_version() + + for i in range(REPEATS): + print("# python::numpy::" + NAME) + elapsed = t.timeit(number=ITERATIONS) + print_results(elapsed) + print("ok " + str(i+1) + " benchmark finished") + + print_summary(REPEATS, REPEATS) + + +def main(): + """Run the benchmark.""" + benchmark() + + +if __name__ == "__main__": + main() diff --git a/base/ind2sub/docs/types/index.d.ts b/base/ind2sub/docs/types/index.d.ts index 0992a776..e659213c 100644 --- a/base/ind2sub/docs/types/index.d.ts +++ b/base/ind2sub/docs/types/index.d.ts @@ -19,7 +19,6 @@ // TypeScript Version: 2.0 /// -/// import { ArrayLike } from '@stdlib/types/array'; import { Mode, Order } from '@stdlib/types/ndarray'; diff --git a/base/ind2sub/examples/c/Makefile b/base/ind2sub/examples/c/Makefile new file mode 100644 index 00000000..ff5293d3 --- /dev/null +++ b/base/ind2sub/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/ind2sub/examples/c/example.c b/base/ind2sub/examples/c/example.c new file mode 100644 index 00000000..767878ca --- /dev/null +++ b/base/ind2sub/examples/c/example.c @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/ind2sub.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include +#include + +int main() { + int64_t ndims = 2; + int64_t shape[] = { 3, 3 }; + int64_t strides[] = { -3, 1 }; + int64_t offset = 6; + + int64_t out[ 2 ]; + + stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, 7, STDLIB_NDARRAY_INDEX_ERROR, out ); + + int i; + printf( "subscripts = { " ); + for ( i = 0; i < ndims; i++ ) { + printf( "%lli", out[ i ] ); + if ( i < ndims-1 ) { + printf( ", " ); + } + } + printf( " }\n" ); +} diff --git a/base/ind2sub/examples/index.js b/base/ind2sub/examples/index.js new file mode 100644 index 00000000..a4d3ff81 --- /dev/null +++ b/base/ind2sub/examples/index.js @@ -0,0 +1,93 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var randu = require( '@stdlib/random/base/randu' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var ind2sub = require( './../lib' ); + +// Specify array characteristics: +var shape = [ 3, 3, 3 ]; +var order = 'row-major'; + +// Compute array meta data: +var ndims = shape.length; +var strides = shape2strides( shape, order ); +var len = numel( shape ); + +// Determine stride indices to be used for formatting how views are displayed... +var s0; +var s1; +if ( order === 'column-major' ) { + s0 = ndims - 1; + s1 = s0 - 1; +} else { // row-major + s0 = 0; + s1 = s0 + 1; +} + +// Initialize a linear array... +var arr = []; +var i; +for ( i = 0; i < len; i++ ) { + arr.push( 0 ); +} + +// Generate random views and display the mapping of elements in the linear array to view subscripts... +var offset; +var row; +var j; +var s; +for ( i = 0; i < 20; i++ ) { + // Randomly flip the sign of one of the strides... + j = discreteUniform( 0, ndims-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + offset = strides2offset( shape, strides ); + + // Print view meta data... + console.log( '' ); + console.log( 'Dimensions: %s.', shape.join( 'x' ) ); + console.log( 'Strides: %s.', strides.join( ',' ) ); + console.log( 'View (subscripts):' ); + + // Print the mapping of elements in the linear array to view subscripts... + row = ' '; + for ( j = 0; j < len; j++ ) { + s = ind2sub( shape, strides, offset, order, j, 'throw' ); + row += '(' + s.join( ',' ) + ')'; + if ( ndims === 1 && j === len-1 ) { + console.log( row ); + } else if ( ndims === 2 && (j+1)%abs( strides[ s0 ] ) === 0 ) { + console.log( row ); + row = ' '; + } else if ( ndims > 2 && (j+1)%abs( strides[ s1 ] ) === 0 ) { + console.log( row ); + if ( (j+1)%abs( strides[ s0 ] ) === 0 ) { + console.log( '' ); + } + row = ' '; + } else { + row += ', '; + } + } +} diff --git a/base/ind2sub/src/main.c b/base/ind2sub/src/main.c index df693688..ec5c0f3a 100644 --- a/base/ind2sub/src/main.c +++ b/base/ind2sub/src/main.c @@ -45,6 +45,7 @@ * #include "stdlib/ndarray/base/ind2sub.h" * #include "stdlib/ndarray/index_modes.h" * #include "stdlib/ndarray/orders.h" +* #include * * int64_t ndims = 2; * int64_t shape[] = { 3, 3 }; diff --git a/base/ind2sub/test/test.js b/base/ind2sub/test/test.js new file mode 100644 index 00000000..bb738691 --- /dev/null +++ b/base/ind2sub/test/test.js @@ -0,0 +1,929 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var ind2sub = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ind2sub, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 4, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 5, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 6, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 7, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2, 4 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 4, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 5, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 6, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 7, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=row-major; negative strides)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 4, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 5, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 6, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 7, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; offset=0; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; offset=0; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; offset=0; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; offset=0; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; offset=0; order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (negative strides; offset=0; order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'attached to the main function is a method which supports providing an output object', function test( t ) { + var strides; + var actual; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = [ 0, 0 ]; + actual = ind2sub.assign( shape, strides, offset, order, 0, 'throw', out ); + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual, out, 'returns output array' ); + t.deepEqual( actual, [ 0, 0 ], 'returns expected value' ); + + out = [ 0, 0 ]; + actual = ind2sub.assign( shape, strides, offset, order, 1, 'throw', out ); + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual, out, 'returns output array' ); + t.deepEqual( actual, [ 0, 1 ], 'returns expected value' ); + + out = [ 0, 0 ]; + actual = ind2sub.assign( shape, strides, offset, order, 2, 'throw', out ); + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual, out, 'returns output array' ); + t.deepEqual( actual, [ 1, 0 ], 'returns expected value' ); + + out = [ 0, 0 ]; + actual = ind2sub.assign( shape, strides, offset, order, 3, 'throw', out ); + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual, out, 'returns output array' ); + t.deepEqual( actual, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'attached to the main function is a method which supports providing an output object (typed array)', function test( t ) { + var strides; + var actual; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = new Uint8Array( shape.length ); + actual = ind2sub.assign( shape, strides, offset, order, 0, 'throw', out ); + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual[ 0 ], 0, 'returns expected value' ); + t.deepEqual( actual[ 1 ], 0, 'returns expected value' ); + + out = new Uint8Array( shape.length ); + actual = ind2sub.assign( shape, strides, offset, order, 1, 'throw', out ); + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual[ 0 ], 0, 'returns expected value' ); + t.deepEqual( actual[ 1 ], 1, 'returns expected value' ); + + out = new Uint8Array( shape.length ); + actual = ind2sub.assign( shape, strides, offset, order, 2, 'throw', out ); + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual[ 0 ], 1, 'returns expected value' ); + t.deepEqual( actual[ 1 ], 0, 'returns expected value' ); + + out = new Uint8Array( shape.length ); + actual = ind2sub.assign( shape, strides, offset, order, 3, 'throw', out ); + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual[ 0 ], 1, 'returns expected value' ); + t.deepEqual( actual[ 1 ], 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions', function test( t ) { + var offset; + var shape; + + shape = [ 2, 2 ]; + offset = 0; + + t.throws( foo, RangeError, 'throws a range error' ); + t.throws( bar, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + var strides = [ 2, 1 ]; + ind2sub( shape, strides, offset, 'row-major', 999999, 'throw' ); + } + + function bar() { + var strides = [ 1, 2 ]; + ind2sub( shape, strides, offset, 'column-major', 999999, 'throw' ); + } +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'wrap' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'wrap' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -8, 'wrap' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -10, 'wrap' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 5, 'wrap' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 8, 'wrap' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'wrap' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'wrap' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'wrap' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -8, 'wrap' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -10, 'wrap' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 5, 'wrap' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 8, 'wrap' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'wrap' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (offset=0; order=row-major)', function test( t ) { + var strides; + var offset; + var shape; + var order; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'wrap' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'wrap' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'wrap' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (offset=0; order=column-major)', function test( t ) { + var strides; + var offset; + var shape; + var order; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'wrap' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'wrap' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'wrap' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'clamp' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'clamp' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'clamp' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'clamp' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'clamp' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'clamp' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (offset=0; order=row-major)', function test( t ) { + var strides; + var offset; + var shape; + var order; + var out; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'clamp' ); + t.deepEqual( out, [ 1, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'clamp' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'clamp' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (offset=0; order=column-major)', function test( t ) { + var strides; + var offset; + var shape; + var order; + var out; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 0; + + out = ind2sub( shape, strides, offset, order, 2, 'clamp' ); + t.deepEqual( out, [ 0, 1 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, -1, 'clamp' ); + t.deepEqual( out, [ 0, 0 ], 'returns expected value' ); + + out = ind2sub( shape, strides, offset, order, 10, 'clamp' ); + t.deepEqual( out, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); diff --git a/base/iteration-order/benchmark/benchmark.js b/base/iteration-order/benchmark/benchmark.js new file mode 100644 index 00000000..ac54a2dd --- /dev/null +++ b/base/iteration-order/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var iterationOrder = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = iterationOrder( strides ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/iteration-order/benchmark/c/Makefile b/base/iteration-order/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/iteration-order/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/iteration-order/benchmark/c/benchmark.c b/base/iteration-order/benchmark/c/benchmark.c new file mode 100644 index 00000000..95a6a0a2 --- /dev/null +++ b/base/iteration-order/benchmark/c/benchmark.c @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `iteration_order`. +*/ +#include "stdlib/ndarray/base/iteration_order.h" +#include +#include +#include +#include +#include +#include + +#define NAME "iteration-order" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t o; + double t; + int i; + + int64_t strides[] = { 3, 2, 1 }; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 0 ] = (int64_t)( (rand_double()*10.0) - 5.0 ); + o = stdlib_ndarray_iteration_order( ndims, strides ); + if ( o > 1 || o < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( o > 1 || o < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/iteration-order/examples/index.js b/base/iteration-order/examples/index.js new file mode 100644 index 00000000..68b57555 --- /dev/null +++ b/base/iteration-order/examples/index.js @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var randu = require( '@stdlib/random/base/randu' ); +var iterationOrder = require( './../lib' ); + +var strides; +var shape; +var out; +var i; +var j; + +shape = [ 0, 0, 0 ]; +shape[ 0 ] = discreteUniform( 1, 10 ); +shape[ 1 ] = discreteUniform( 1, 10 ); +shape[ 2 ] = discreteUniform( 1, 10 ); + +strides = shape2strides( shape, 'row-major' ); + +for ( i = 0; i < 100; i++ ) { + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + out = iterationOrder( strides ); + console.log( 'strides: %s => %d', strides.join( ',' ), out ); +} diff --git a/base/iteration-order/test/test.js b/base/iteration-order/test/test.js new file mode 100644 index 00000000..3b0e4687 --- /dev/null +++ b/base/iteration-order/test/test.js @@ -0,0 +1,80 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var iterationOrder = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof iterationOrder, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function determines array iteration order based on a stride array', function test( t ) { + var strides; + var o; + + strides = [ 2, 1 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ -2, 1 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + strides = [ 2, -1 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + strides = [ -2, -1 ]; + o = iterationOrder( strides ); + t.strictEqual( o, -1, 'returns expected value' ); + + strides = [ 1, 3 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ -1, 3 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + strides = [ 1, -3 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + strides = [ -1, -3 ]; + o = iterationOrder( strides ); + t.strictEqual( o, -1, 'returns expected value' ); + + strides = [ 30, 10, 1 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ 30, -10, 1 ]; + o = iterationOrder( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + t.end(); +}); diff --git a/base/lib/index.js b/base/lib/index.js index a03d3f95..ef8ebf6d 100644 --- a/base/lib/index.js +++ b/base/lib/index.js @@ -54,6 +54,15 @@ setReadOnly( ns, 'assert', require( '@stdlib/ndarray/base/assert' ) ); */ setReadOnly( ns, 'bind2vind', require( '@stdlib/ndarray/base/bind2vind' ) ); +/** +* @name broadcastShapes +* @memberof ns +* @readonly +* @type {Function} +* @see {@link module:@stdlib/ndarray/base/broadcast-shapes} +*/ +setReadOnly( ns, 'broadcastShapes', require( '@stdlib/ndarray/base/broadcast-shapes' ) ); + /** * @name buffer * @memberof ns diff --git a/base/max-view-buffer-index/benchmark/benchmark.js b/base/max-view-buffer-index/benchmark/benchmark.js new file mode 100644 index 00000000..dd04629d --- /dev/null +++ b/base/max-view-buffer-index/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var maxViewBufferIndex = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = maxViewBufferIndex( shape, strides, 1000 ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/max-view-buffer-index/benchmark/c/Makefile b/base/max-view-buffer-index/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/max-view-buffer-index/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/max-view-buffer-index/benchmark/c/benchmark.c b/base/max-view-buffer-index/benchmark/c/benchmark.c new file mode 100644 index 00000000..e6faa0ed --- /dev/null +++ b/base/max-view-buffer-index/benchmark/c/benchmark.c @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `max_view_buffer_index`. +*/ +#include +#include +#include +#include +#include +#include +#include "stdlib/ndarray/base/max_view_buffer_index.h" + +#define NAME "max-view-buffer-index" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t n; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 1000; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 0 ] *= ( rand_double() < 0.5 ) ? 1 : -1; + n = stdlib_ndarray_max_view_buffer_index( ndims, shape, strides, offset ); + if ( n > 1e10 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( n > 1e10 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/max-view-buffer-index/examples/index.js b/base/max-view-buffer-index/examples/index.js new file mode 100644 index 00000000..b82596d4 --- /dev/null +++ b/base/max-view-buffer-index/examples/index.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var maxViewBufferIndex = require( './../lib' ); + +var strides; +var offset; +var shape; +var idx; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + // Compute the index offset: + offset = strides2offset( shape, strides ); + + // Compute the maximum linear index: + idx = maxViewBufferIndex( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Max idx: %d.', shape.join( 'x' ), strides.join( ',' ), offset, idx ); +} diff --git a/base/max-view-buffer-index/test/test.js b/base/max-view-buffer-index/test/test.js new file mode 100644 index 00000000..d1a9d2bb --- /dev/null +++ b/base/max-view-buffer-index/test/test.js @@ -0,0 +1,128 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var maxViewBufferIndex = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof maxViewBufferIndex, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function computes the maximum linear index in an underlying array buffer which is accessible to an array view', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 0; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 4; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 1; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 5; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ 1, 3 ]; + offset = 0; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ -1, 3 ]; + offset = 2; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ 1, -3 ]; + offset = 3; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + strides = [ -1, -3 ]; + offset = 5; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 5, 'returns expected value' ); + + // 3d array... + shape = [ 2, 3, 10 ]; + + strides = [ 30, 10, 1 ]; + offset = 0; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 59, 'returns expected value' ); + + strides = [ 30, -10, 1 ]; + offset = 20; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 59, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function computes the maximum linear index in an underlying array buffer which is accessible to an array view (buffer offset)', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 10; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 15, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 14; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 15, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 11; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 15, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 15; + idx = maxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 15, 'returns expected value' ); + + t.end(); +}); diff --git a/base/min-view-buffer-index/benchmark/benchmark.js b/base/min-view-buffer-index/benchmark/benchmark.js new file mode 100644 index 00000000..9c511449 --- /dev/null +++ b/base/min-view-buffer-index/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var minViewBufferIndex = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = minViewBufferIndex( shape, strides, 1000 ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/min-view-buffer-index/benchmark/c/Makefile b/base/min-view-buffer-index/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/min-view-buffer-index/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/min-view-buffer-index/benchmark/c/benchmark.c b/base/min-view-buffer-index/benchmark/c/benchmark.c new file mode 100644 index 00000000..41dda8b1 --- /dev/null +++ b/base/min-view-buffer-index/benchmark/c/benchmark.c @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `min_view_buffer_index`. +*/ +#include +#include +#include +#include +#include +#include +#include "stdlib/ndarray/base/min_view_buffer_index.h" + +#define NAME "min-view-buffer-index" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t n; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 1000; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 0 ] *= ( rand_double() < 0.5 ) ? 1 : -1; + n = stdlib_ndarray_min_view_buffer_index( ndims, shape, strides, offset ); + if ( n > 1e10 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( n > 1e10 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/min-view-buffer-index/examples/index.js b/base/min-view-buffer-index/examples/index.js new file mode 100644 index 00000000..7c05dd94 --- /dev/null +++ b/base/min-view-buffer-index/examples/index.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var minViewBufferIndex = require( './../lib' ); + +var strides; +var offset; +var shape; +var idx; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + // Compute the index offset: + offset = strides2offset( shape, strides ) + 25; // include view offset + + // Compute the minimum linear index: + idx = minViewBufferIndex( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Min idx: %d.', shape.join( 'x' ), strides.join( ',' ), offset, idx ); +} diff --git a/base/min-view-buffer-index/test/test.js b/base/min-view-buffer-index/test/test.js new file mode 100644 index 00000000..f59b8968 --- /dev/null +++ b/base/min-view-buffer-index/test/test.js @@ -0,0 +1,128 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var minViewBufferIndex = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof minViewBufferIndex, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function computes the minimum linear index in an underlying array buffer which is accessible to an array view', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 0; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 4; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 1; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 5; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ 1, 3 ]; + offset = 0; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ -1, 3 ]; + offset = 2; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ 1, -3 ]; + offset = 3; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ -1, -3 ]; + offset = 5; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + // 3d array... + shape = [ 2, 3, 10 ]; + + strides = [ 30, 10, 1 ]; + offset = 0; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + strides = [ 30, -10, 1 ]; + offset = 20; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function computes the minimum linear index in an underlying array buffer which is accessible to an array view (buffer offset)', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 10; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 10, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 14; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 10, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 11; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 10, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 15; + idx = minViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx, 10, 'returns expected value' ); + + t.end(); +}); diff --git a/base/minmax-view-buffer-index/benchmark/benchmark.js b/base/minmax-view-buffer-index/benchmark/benchmark.js new file mode 100644 index 00000000..f4231bce --- /dev/null +++ b/base/minmax-view-buffer-index/benchmark/benchmark.js @@ -0,0 +1,158 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isNonNegativeIntegerArray = require( '@stdlib/assert/is-nonnegative-integer-array' ).primitives; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var minViewBufferIndex = require( '@stdlib/ndarray/base/min-view-buffer-index' ); +var maxViewBufferIndex = require( '@stdlib/ndarray/base/max-view-buffer-index' ); +var pkg = require( './../package.json' ).name; +var minmaxViewBufferIndex = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = minmaxViewBufferIndex( shape, strides, 1000 ); + if ( out.length !== 2 ) { + b.fail( 'should return an array having two elements' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::memory_reuse:assign', function benchmark( b ) { + var strides; + var shape; + var out; + var mm; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + out = [ 0, 0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + mm = minmaxViewBufferIndex( shape, strides, 1000, out ); + if ( mm.length !== 2 ) { + b.fail( 'should return an array having two elements' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( mm ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::separately', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = [ 0, 0 ]; + out[ 0 ] = minViewBufferIndex( shape, strides, 1000 ); + out[ 1 ] = maxViewBufferIndex( shape, strides, 1000 ); + if ( out.length !== 2 ) { + b.fail( 'should return an array having two elements' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::separately,memory_reuse', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + out = [ 0, 0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 2 ] *= ( randu() < 0.5 ) ? -1 : 1; + out[ 0 ] = minViewBufferIndex( shape, strides, 1000 ); + out[ 1 ] = maxViewBufferIndex( shape, strides, 1000 ); + if ( out.length !== 2 ) { + b.fail( 'should return an array having two elements' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/minmax-view-buffer-index/benchmark/c/Makefile b/base/minmax-view-buffer-index/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/minmax-view-buffer-index/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/minmax-view-buffer-index/benchmark/c/benchmark.c b/base/minmax-view-buffer-index/benchmark/c/benchmark.c new file mode 100644 index 00000000..753a2ffb --- /dev/null +++ b/base/minmax-view-buffer-index/benchmark/c/benchmark.c @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `minmax_view_buffer_index`. +*/ +#include "stdlib/ndarray/base/minmax_view_buffer_index.h" +#include +#include +#include +#include +#include +#include + +#define NAME "minmax-view-buffer-index" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + double t; + int i; + + int64_t out[ 2 ]; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 1000; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 0 ] *= ( rand_double() < 0.5 ) ? 1 : -1; + stdlib_ndarray_minmax_view_buffer_index( ndims, shape, strides, offset, out ); + if ( out[ 0 ] > 1e10 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( out[ 0 ] > 1e10 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/minmax-view-buffer-index/examples/c/Makefile b/base/minmax-view-buffer-index/examples/c/Makefile new file mode 100644 index 00000000..ff5293d3 --- /dev/null +++ b/base/minmax-view-buffer-index/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/minmax-view-buffer-index/examples/c/example.c b/base/minmax-view-buffer-index/examples/c/example.c new file mode 100644 index 00000000..37fc37ea --- /dev/null +++ b/base/minmax-view-buffer-index/examples/c/example.c @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/minmax_view_buffer_index.h" +#include + +int main() { + int64_t ndims = 2; + int64_t shape[] = { 10, 10 }; + int64_t strides[] = { 10, 1 }; + int64_t offset = 0; + int64_t out[ 2 ]; + + stdlib_ndarray_minmax_view_buffer_index( ndims, shape, strides, offset, out ); + + printf( "min: %lli\n", out[ 0 ] ); + printf( "max: %lli\n", out[ 1 ] ); +} diff --git a/base/minmax-view-buffer-index/examples/index.js b/base/minmax-view-buffer-index/examples/index.js new file mode 100644 index 00000000..259785f4 --- /dev/null +++ b/base/minmax-view-buffer-index/examples/index.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var randu = require( '@stdlib/random/base/randu' ); +var minmaxViewBufferIndex = require( './../lib' ); + +var strides; +var offset; +var shape; +var idx; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 100; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Generate strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + // Compute the index offset: + offset = strides2offset( shape, strides ) + 25; // include a view offset + + // Compute the minimum and maximum linear indices: + idx = minmaxViewBufferIndex( shape, strides, offset ); + console.log( 'Shape: %s. Strides: %s. Offset: %d. Min idx: %d. Max idx: %d.', shape.join( 'x' ), strides.join( ',' ), offset, idx[ 0 ], idx[ 1 ] ); +} diff --git a/base/minmax-view-buffer-index/test/test.js b/base/minmax-view-buffer-index/test/test.js new file mode 100644 index 00000000..982d34d0 --- /dev/null +++ b/base/minmax-view-buffer-index/test/test.js @@ -0,0 +1,267 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var minmaxViewBufferIndex = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof minmaxViewBufferIndex, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function computes the minimum and maximum linear indices in an underlying array buffer which are accessible to an array view', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 0; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 4; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 1; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 5; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ 1, 3 ]; + offset = 0; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ -1, 3 ]; + offset = 2; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ 1, -3 ]; + offset = 3; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + strides = [ -1, -3 ]; + offset = 5; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + // 3d array... + shape = [ 2, 3, 10 ]; + + strides = [ 30, 10, 1 ]; + offset = 0; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 59, 'returns expected value' ); + + strides = [ 30, -10, 1 ]; + offset = 20; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 59, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function computes the minimum and maximum linear indices in an underlying array buffer which are accessible to an array view (buffer offset)', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 3, 2 ]; + + strides = [ 2, 1 ]; + offset = 10; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx[ 0 ], 10, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 15, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 14; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx[ 0 ], 10, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 15, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 11; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx[ 0 ], 10, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 15, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 15; + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( idx[ 0 ], 10, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 15, 'returns expected value' ); + + t.end(); +}); + +tape( 'attached to the main function is a method which supports providing an output object', function test( t ) { + var strides; + var offset; + var shape; + var idx; + var out; + + shape = [ 3, 2 ]; + + out = [ 0, 0 ]; + strides = [ 2, 1 ]; + offset = 0; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ -2, 1 ]; + offset = 4; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ 2, -1 ]; + offset = 1; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ -2, -1 ]; + offset = 5; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ 1, 3 ]; + offset = 0; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ -1, 3 ]; + offset = 2; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ 1, -3 ]; + offset = 3; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ -1, -3 ]; + offset = 5; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 5, 'returns expected value' ); + + // 3d array... + shape = [ 2, 3, 10 ]; + + out = [ 0, 0 ]; + strides = [ 30, 10, 1 ]; + offset = 0; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 59, 'returns expected value' ); + + out = [ 0, 0 ]; + strides = [ 30, -10, 1 ]; + offset = 20; + idx = minmaxViewBufferIndex.assign( shape, strides, offset, out ); + t.strictEqual( idx, out, 'returns expected value' ); + t.strictEqual( idx[ 0 ], 0, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 59, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function computes the minimum and maximum linear indices in an underlying array buffer which are accessible to an array view (shape[k]=1)', function test( t ) { + var strides; + var offset; + var shape; + var idx; + + shape = [ 1, 1 ]; + + strides = [ 0, 0 ]; + offset = 10; + + idx = minmaxViewBufferIndex( shape, strides, offset ); + t.strictEqual( isArray( idx ), true, 'returns an array' ); + t.strictEqual( idx[ 0 ], 10, 'returns expected value' ); + t.strictEqual( idx[ 1 ], 10, 'returns expected value' ); + + t.end(); +}); diff --git a/base/napi/addon-arguments/benchmark/benchmark.native.js b/base/napi/addon-arguments/benchmark/benchmark.native.js new file mode 100644 index 00000000..2c2f9085 --- /dev/null +++ b/base/napi/addon-arguments/benchmark/benchmark.native.js @@ -0,0 +1,72 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var bench = require( '@stdlib/bench' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var tryRequire = require( '@stdlib/utils/try-require' ); +var pkg = require( './../package.json' ).name; + + +// VARIABLES // + +var addon = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( addon instanceof Error ) +}; + + +// MAIN // + +bench( pkg, opts, function benchmark( b ) { + var xbuf; + var ybuf; + var len; + var x; + var y; + var z; + var i; + + len = 10; + + xbuf = new Float64Array( len ); + ybuf = new Float64Array( len ); + + x = ndarray( 'float64', xbuf, [ len ], [ 1 ], 0, 'row-major' ); + y = ndarray( 'float64', ybuf, [ len ], [ 1 ], 0, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = addon( x, y ); + if ( isnan( z.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( z.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/napi/addon-arguments/examples/index.js b/base/napi/addon-arguments/examples/index.js new file mode 100644 index 00000000..c24bbfd9 --- /dev/null +++ b/base/napi/addon-arguments/examples/index.js @@ -0,0 +1,24 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var headerDir = require( './../lib' ); + +console.log( headerDir ); +// => diff --git a/base/napi/addon-arguments/include.gypi b/base/napi/addon-arguments/include.gypi index a1941d2a..5c60648e 100644 --- a/base/napi/addon-arguments/include.gypi +++ b/base/napi/addon-arguments/include.gypi @@ -28,7 +28,7 @@ # Include directories: 'include_dirs': [ - ' diff --git a/base/napi/test/test.browser.js b/base/napi/test/test.browser.js new file mode 100644 index 00000000..794230a5 --- /dev/null +++ b/base/napi/test/test.browser.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var headerDir = require( './../lib/browser.js' ); + + +// TESTS // + +tape( 'main export is a null', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( headerDir, null, 'main export is null' ); + t.end(); +}); diff --git a/base/napi/test/test.js b/base/napi/test/test.js new file mode 100644 index 00000000..863a4dea --- /dev/null +++ b/base/napi/test/test.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var tape = require( 'tape' ); +var IS_BROWSER = require( '@stdlib/assert/is-browser' ); +var headerDir = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': IS_BROWSER +}; + + +// TESTS // + +tape( 'main export is a string', opts, function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof headerDir, 'string', 'main export is a string' ); + t.end(); +}); + +tape( 'the exported value corresponds to the package directory containing header files', opts, function test( t ) { + var dir = resolve( __dirname, '..', 'include' ); + t.strictEqual( headerDir, dir, 'exports expected value' ); + t.end(); +}); diff --git a/base/napi/typedarray-type-to-dtype/test/test.browser.js b/base/napi/typedarray-type-to-dtype/test/test.browser.js new file mode 100644 index 00000000..56e8e392 --- /dev/null +++ b/base/napi/typedarray-type-to-dtype/test/test.browser.js @@ -0,0 +1,33 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var headerDir = require( './../lib/browser.js' ); + + +// TESTS // + +tape( 'main export is a null', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( headerDir, null, 'main export is null' ); + t.end(); +}); diff --git a/base/napi/typedarray-type-to-dtype/test/test.js b/base/napi/typedarray-type-to-dtype/test/test.js new file mode 100644 index 00000000..b61649d5 --- /dev/null +++ b/base/napi/typedarray-type-to-dtype/test/test.js @@ -0,0 +1,48 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var tape = require( 'tape' ); +var IS_BROWSER = require( '@stdlib/assert/is-browser' ); +var headerDir = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': IS_BROWSER +}; + + +// TESTS // + +tape( 'main export is a string', opts, function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof headerDir, 'string', 'main export is a string' ); + t.end(); +}); + +tape( 'the exported value corresponds to the package directory containing header files', opts, function test( t ) { + var dir = resolve( __dirname, '..', 'include' ); + t.strictEqual( headerDir, dir, 'exports expected value' ); + t.end(); +}); diff --git a/base/napi/unary/benchmark/benchmark.native.js b/base/napi/unary/benchmark/benchmark.native.js new file mode 100644 index 00000000..349bcd4e --- /dev/null +++ b/base/napi/unary/benchmark/benchmark.native.js @@ -0,0 +1,71 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var bench = require( '@stdlib/bench' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/base/ctor' ); +var tryRequire = require( '@stdlib/utils/try-require' ); +var pkg = require( './../package.json' ).name; + + +// VARIABLES // + +var addon = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( addon instanceof Error ) +}; + + +// MAIN // + +bench( pkg, opts, function benchmark( b ) { + var xbuf; + var ybuf; + var len; + var x; + var y; + var z; + var i; + + len = 10; + xbuf = new Float64Array( len ); + ybuf = new Float64Array( len ); + + x = new ndarray( 'float64', xbuf, [ len ], [ 1 ], 0, 'row-major' ); + y = new ndarray( x.dtype, ybuf, x.shape, x.strides, x.offset, x.order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = addon( x, y ); + if ( isnan( z.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( z.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/napi/unary/examples/index.js b/base/napi/unary/examples/index.js new file mode 100644 index 00000000..c24bbfd9 --- /dev/null +++ b/base/napi/unary/examples/index.js @@ -0,0 +1,24 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var headerDir = require( './../lib' ); + +console.log( headerDir ); +// => diff --git a/base/napi/unary/include.gypi b/base/napi/unary/include.gypi index a1941d2a..5c60648e 100644 --- a/base/napi/unary/include.gypi +++ b/base/napi/unary/include.gypi @@ -28,7 +28,7 @@ # Include directories: 'include_dirs': [ - ' +#include +#include +#include +#include +#include + +#define NAME "nonsingleton-dimensions" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t n; + double t; + int i; + + int64_t shape[] = { 5, 2, 1 }; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + shape[ 0 ] = (int64_t)( rand_double()*5.0 ); + n = stdlib_ndarray_nonsingleton_dimensions( ndims, shape ); + if ( n > ndims ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( n > ndims ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/nonsingleton-dimensions/examples/c/Makefile b/base/nonsingleton-dimensions/examples/c/Makefile new file mode 100644 index 00000000..ff5293d3 --- /dev/null +++ b/base/nonsingleton-dimensions/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/nonsingleton-dimensions/examples/c/example.c b/base/nonsingleton-dimensions/examples/c/example.c new file mode 100644 index 00000000..aa058eda --- /dev/null +++ b/base/nonsingleton-dimensions/examples/c/example.c @@ -0,0 +1,27 @@ +/** +* @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/ndarray/base/nonsingleton_dimensions.h" +#include + +int main() { + int64_t shape[] = { 10, 3, 1, 1, 5 }; + + int64_t n = stdlib_ndarray_nonsingleton_dimensions( 5, shape ); + printf( "shape: %llux%llux%llux%llux%llu. non-singleton dimensions: %llu\n", shape[ 0 ], shape[ 1 ], shape[ 2 ], shape[ 3 ], shape[ 4 ], n ); +} diff --git a/base/nonsingleton-dimensions/examples/index.js b/base/nonsingleton-dimensions/examples/index.js new file mode 100644 index 00000000..520627c1 --- /dev/null +++ b/base/nonsingleton-dimensions/examples/index.js @@ -0,0 +1,35 @@ +/** +* @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. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var nonsingletonDimensions = require( './../lib' ); + +var shape; +var n; +var i; + +shape = [ 0, 0, 0 ]; +for ( i = 0; i < 100; i++ ) { + shape[ 0 ] = discreteUniform( 1, 5 ); + shape[ 1 ] = discreteUniform( 1, 5 ); + shape[ 2 ] = discreteUniform( 1, 5 ); + n = nonsingletonDimensions( shape ); + console.log( 'shape: %s. non-singleton dimensions: %d.', shape.join( 'x' ), n ); +} diff --git a/base/nonsingleton-dimensions/test/test.js b/base/nonsingleton-dimensions/test/test.js new file mode 100644 index 00000000..88ebe627 --- /dev/null +++ b/base/nonsingleton-dimensions/test/test.js @@ -0,0 +1,62 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var nonsingletonDimensions = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof nonsingletonDimensions, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the number of non-singleton dimensions', function test( t ) { + var expected; + var values; + var n; + var i; + + values = [ + [ 3, 3, 3 ], + [ 1, 1 ], + [ 3, 3, 0, 3 ], + [ 1, 2, 3, 4 ], + [ 5 ] + ]; + + expected = [ + 3, + 0, + 4, + 3, + 1 + ]; + + for ( i = 0; i < values.length; i++ ) { + n = nonsingletonDimensions( values[ i ] ); + t.strictEqual( n, expected[ i ], 'returns expected value for shape '+values[ i ].join( 'x' ) ); + } + t.end(); +}); diff --git a/base/numel/benchmark/benchmark.js b/base/numel/benchmark/benchmark.js new file mode 100644 index 00000000..23a2c6d2 --- /dev/null +++ b/base/numel/benchmark/benchmark.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var pkg = require( './../package.json' ).name; +var numel = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var shape; + var n; + var i; + + shape = [ 0, 0, 0 ]; + for ( i = 0; i < shape.length; i++ ) { + shape[ i ] = floor( randu()*10.0 ) + 10.0; + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 0 ] = floor( randu()*10.0 ) + 10.0; + n = numel( shape ); + if ( n !== n ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( n !== n ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/numel/benchmark/c/Makefile b/base/numel/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/numel/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/numel/benchmark/c/benchmark.c b/base/numel/benchmark/c/benchmark.c new file mode 100644 index 00000000..0836c0ac --- /dev/null +++ b/base/numel/benchmark/c/benchmark.c @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `numel`. +*/ +#include +#include +#include +#include +#include +#include +#include "stdlib/ndarray/base/numel.h" + +#define NAME "numel" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t n; + double t; + int i; + + int64_t shape[] = { 20, 19, 18 }; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + shape[ 0 ] = (int64_t)( (100%(i+1)) + 10 ); + n = stdlib_ndarray_numel( ndims, shape ); + if ( n < 10 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( n < 10 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/numel/examples/index.js b/base/numel/examples/index.js new file mode 100644 index 00000000..3f5b1efc --- /dev/null +++ b/base/numel/examples/index.js @@ -0,0 +1,37 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var numel = require( './../lib' ); + +var shape; +var n; +var i; + +shape = [ 0, 0, 0 ]; +for ( i = 0; i < 100; i++ ) { + // Generate random NxMxL dimensions: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 2, 7 ); + shape[ 2 ] = discreteUniform( 1, 12 ); + + n = numel( shape ); + console.log( '%s => %d elements', shape.join( 'x' ), n ); +} diff --git a/base/numel/test/test.js b/base/numel/test/test.js new file mode 100644 index 00000000..f4ba0410 --- /dev/null +++ b/base/numel/test/test.js @@ -0,0 +1,67 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var numel = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof numel, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if provided an empty array, the function returns 0', function test( t ) { + t.strictEqual( numel( [] ), 0, 'returns 0' ); + t.end(); +}); + +tape( 'the function returns the number of elements in an array', function test( t ) { + var expected; + var values; + var n; + var i; + + values = [ + [ 3, 3, 3 ], + [ 1, 1 ], + [ 3, 3, 0, 3 ], + [ 1, 2, 3, 4 ], + [ 5 ] + ]; + + expected = [ + 27, + 1, + 0, + 24, + 5 + ]; + + for ( i = 0; i < values.length; i++ ) { + n = numel( values[ i ] ); + t.strictEqual( n, expected[ i ], 'returns expected value for shape '+values[ i ].join( 'x' ) ); + } + t.end(); +}); diff --git a/base/package.json b/base/package.json index 89c03d50..0dbe4fca 100644 --- a/base/package.json +++ b/base/package.json @@ -19,6 +19,7 @@ "lib": "./lib", "test": "./test" }, + "types": "./docs/types", "scripts": {}, "homepage": "https://github.com/stdlib-js/stdlib", "repository": { diff --git a/base/serialize-meta-data/benchmark/benchmark.js b/base/serialize-meta-data/benchmark/benchmark.js new file mode 100644 index 00000000..bd58d412 --- /dev/null +++ b/base/serialize-meta-data/benchmark/benchmark.js @@ -0,0 +1,161 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarrayBase = require( '@stdlib/ndarray/base/ctor' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var isDataView = require( '@stdlib/assert/is-dataview' ); +var pkg = require( './../package.json' ).name; +var serialize = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::base_ndarray,2d', function benchmark( b ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var shape; + var order; + var out; + var i; + + dtype = 'float64'; + buffer = new Float64Array( 4 ); + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + values = [ + ndarrayBase( dtype, buffer, shape, strides, offset, order ), + ndarrayBase( dtype, buffer, shape, strides, offset, order ), + ndarrayBase( dtype, buffer, shape, strides, offset, order ), + ndarrayBase( dtype, buffer, shape, strides, offset, order ), + ndarrayBase( dtype, buffer, shape, strides, offset, order ) + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = serialize( values[ i%values.length ] ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isDataView( out ) ) { + b.fail( 'should return a DataView' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::ndarray,2d', function benchmark( b ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var shape; + var order; + var out; + var i; + + dtype = 'float64'; + buffer = new Float64Array( 4 ); + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + values = [ + ndarray( dtype, buffer, shape, strides, offset, order ), + ndarray( dtype, buffer, shape, strides, offset, order ), + ndarray( dtype, buffer, shape, strides, offset, order ), + ndarray( dtype, buffer, shape, strides, offset, order ), + ndarray( dtype, buffer, shape, strides, offset, order ) + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = serialize( values[ i%values.length ] ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isDataView( out ) ) { + b.fail( 'should return a DataView' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::ndarray_like,2d', function benchmark( b ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var shape; + var order; + var out; + var obj; + var i; + + dtype = 'float64'; + buffer = new Float64Array( 4 ); + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + values = []; + for ( i = 0; i < 5; i++ ) { + obj = { + 'dtype': dtype, + 'data': buffer, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': order + }; + values.push( obj ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = serialize( values[ i%values.length ] ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isDataView( out ) ) { + b.fail( 'should return a DataView' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/serialize-meta-data/examples/index.js b/base/serialize-meta-data/examples/index.js new file mode 100644 index 00000000..59fbfabd --- /dev/null +++ b/base/serialize-meta-data/examples/index.js @@ -0,0 +1,74 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var IS_LITTLE_ENDIAN = require( '@stdlib/assert/is-little-endian' ); +var array = require( '@stdlib/ndarray/array' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var fromInt64Bytes = require( '@stdlib/number/float64/base/from-int64-bytes' ); +var serialize = require( './../lib' ); + +// Create an ndarray: +var x = array( [ [ 1, 2 ], [ 3, 4 ] ] ); + +// Print various properties: +console.log( 'dtype: %s', x.dtype ); +console.log( 'ndims: %d', x.ndims ); +console.log( 'shape: [ %s ]', x.shape.join( ', ' ) ); +console.log( 'strides: [ %s ]', x.strides.join( ', ' ) ); +console.log( 'offset: %d', x.offset ); +console.log( 'order: %s', x.order ); + +// Serialize ndarray meta data to a DataView: +var dv = serialize( x ); +// returns + +// Create a Uint8Array view: +var bytes = new Uint8Array( dv.buffer ); + +// Extract the data type (enum): +var dtype = dv.getInt16( 1, IS_LITTLE_ENDIAN ); +console.log( 'dtype (enum): %d', dtype ); + +// Extract the number of dimensions: +var ndims = fromInt64Bytes( bytes, 1, 3 ); +console.log( 'ndims: %d', x.ndims ); + +// Extract the shape: +var shape = []; +var i; +for ( i = 0; i < ndims; i++ ) { + shape.push( fromInt64Bytes( bytes, 1, 11+(i*8) ) ); +} +console.log( 'shape: [ %s ]', shape.join( ', ' ) ); + +// Extract the strides (in units of bytes): +var strides = []; +for ( i = 0; i < ndims; i++ ) { + strides.push( fromInt64Bytes( bytes, 1, 11+(ndims*8)+(i*8) ) ); +} +console.log( 'strides (bytes): [ %s ]', strides.join( ', ' ) ); + +// Extract the index offset (in bytes): +var offset = fromInt64Bytes( bytes, 1, 11+(ndims*16) ); +console.log( 'offset (bytes): %d', offset ); + +// Extract the order (enum): +var order = dv.getInt8( 19+(ndims*16) ); +console.log( 'order (enum): %d', order ); diff --git a/base/serialize-meta-data/test/test.js b/base/serialize-meta-data/test/test.js new file mode 100644 index 00000000..8576eeb2 --- /dev/null +++ b/base/serialize-meta-data/test/test.js @@ -0,0 +1,62 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var proxyquire = require( 'proxyquire' ); +var main = require( './../lib/main.js' ); +var polyfill = require( './../lib/polyfill.js' ); +var serialize = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof serialize, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if an environment support BigInts, the function includes BigInt operations', function test( t ) { + var serialize = proxyquire( './../lib', { + '@stdlib/assert/has-bigint-support': hasSupport + }); + + t.strictEqual( serialize, main, 'is expected value' ); + t.end(); + + function hasSupport() { + return true; + } +}); + +tape( 'if an environment does not support BigInts, the function is a polyfill', function test( t ) { + var serialize = proxyquire( './../lib', { + '@stdlib/assert/has-bigint-support': hasSupport + }); + + t.strictEqual( serialize, polyfill, 'is expected value' ); + t.end(); + + function hasSupport() { + return false; + } +}); diff --git a/base/serialize-meta-data/test/test.main.js b/base/serialize-meta-data/test/test.main.js new file mode 100644 index 00000000..348b035c --- /dev/null +++ b/base/serialize-meta-data/test/test.main.js @@ -0,0 +1,282 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var IS_LITTLE_ENDIAN = require( '@stdlib/assert/is-little-endian' ); +var isDataView = require( '@stdlib/assert/is-dataview' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var ndarray = require( '@stdlib/ndarray/base/ctor' ); +var bytesPerElement = require( '@stdlib/ndarray/base/bytes-per-element' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ).enum; +var modes = require( '@stdlib/ndarray/index-modes' ).enum; +var orders = require( '@stdlib/ndarray/orders' ).enum; +var serialize = require( './../lib/main.js' ); + + +// VARIABLES // + +var DTYPES = dtypes(); +var MODES = modes(); +var ORDERS = orders(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof serialize, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function serializes ndarray meta data to a DataView (ndarray)', function test( t ) { + var expected; + var strides; + var nbytes; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'throw' ], + 'nsubmodes': 1, + 'submodes': [ MODES[ 'throw' ] ] + }; + + actual = serialize( arr ); + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(1*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + nbytes = bytesPerElement( dtype ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } + t.end(); +}); + +tape( 'the function serializes ndarray meta data to a DataView (ndarray-like object)', function test( t ) { + var expected; + var strides; + var nbytes; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = { + 'dtype': dtype, + 'data': buffer, + 'shape': shape, + 'strides': strides, + 'order': order, + 'offset': offset + }; + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'throw' ], + 'nsubmodes': 1, + 'submodes': [ MODES[ 'throw' ] ] + }; + + actual = serialize( arr ); + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(1*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + nbytes = bytesPerElement( dtype ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } + t.end(); +}); + +tape( 'the function serializes ndarray meta data to a DataView (ndarray-like object; modes)', function test( t ) { + var expected; + var strides; + var nbytes; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = { + 'dtype': dtype, + 'data': buffer, + 'shape': shape, + 'strides': strides, + 'order': order, + 'offset': offset, + 'mode': 'wrap', + 'submode': [ 'clamp', 'wrap', 'throw' ] + }; + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'wrap' ], + 'nsubmodes': 3, + 'submodes': [ MODES[ 'clamp' ], MODES[ 'wrap' ], MODES[ 'throw' ] ] + }; + + actual = serialize( arr ); + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(3*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + nbytes = bytesPerElement( dtype ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + t.strictEqual( bytes[ 62 ], expected.submodes[ 1 ], 'returns expected submode' ); + t.strictEqual( bytes[ 63 ], expected.submodes[ 2 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + t.strictEqual( bytes[ 62 ], expected.submodes[ 1 ], 'returns expected submode' ); + t.strictEqual( bytes[ 63 ], expected.submodes[ 2 ], 'returns expected submode' ); + } + t.end(); +}); diff --git a/base/serialize-meta-data/test/test.polyfill.js b/base/serialize-meta-data/test/test.polyfill.js new file mode 100644 index 00000000..5b669d19 --- /dev/null +++ b/base/serialize-meta-data/test/test.polyfill.js @@ -0,0 +1,282 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var IS_LITTLE_ENDIAN = require( '@stdlib/assert/is-little-endian' ); +var isDataView = require( '@stdlib/assert/is-dataview' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var ndarray = require( '@stdlib/ndarray/base/ctor' ); +var bytesPerElement = require( '@stdlib/ndarray/base/bytes-per-element' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ).enum; +var modes = require( '@stdlib/ndarray/index-modes' ).enum; +var orders = require( '@stdlib/ndarray/orders' ).enum; +var serialize = require( './../lib/polyfill.js' ); + + +// VARIABLES // + +var DTYPES = dtypes(); +var MODES = modes(); +var ORDERS = orders(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof serialize, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function serializes ndarray meta data to a DataView (ndarray)', function test( t ) { + var expected; + var strides; + var nbytes; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'throw' ], + 'nsubmodes': 1, + 'submodes': [ MODES[ 'throw' ] ] + }; + + actual = serialize( arr ); + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(1*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + nbytes = bytesPerElement( dtype ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } + t.end(); +}); + +tape( 'the function serializes ndarray meta data to a DataView (ndarray-like object)', function test( t ) { + var expected; + var strides; + var nbytes; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = { + 'dtype': dtype, + 'data': buffer, + 'shape': shape, + 'strides': strides, + 'order': order, + 'offset': offset + }; + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'throw' ], + 'nsubmodes': 1, + 'submodes': [ MODES[ 'throw' ] ] + }; + + actual = serialize( arr ); + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(1*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + nbytes = bytesPerElement( dtype ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + } + t.end(); +}); + +tape( 'the function serializes ndarray meta data to a DataView (ndarray-like object; modes)', function test( t ) { + var expected; + var strides; + var nbytes; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var bytes; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = { + 'dtype': dtype, + 'data': buffer, + 'shape': shape, + 'strides': strides, + 'order': order, + 'offset': offset, + 'mode': 'wrap', + 'submode': [ 'clamp', 'wrap', 'throw' ] + }; + + expected = { + 'dtype': DTYPES[ 'float64' ], + 'ndims': shape.length, + 'shape': shape, + 'strides': strides, + 'offset': offset, + 'order': ORDERS[ 'row-major' ], + 'mode': MODES[ 'wrap' ], + 'nsubmodes': 3, + 'submodes': [ MODES[ 'clamp' ], MODES[ 'wrap' ], MODES[ 'throw' ] ] + }; + + actual = serialize( arr ); + + t.strictEqual( isDataView( actual ), true, 'returns a DataView' ); + t.strictEqual( actual.byteLength, 1+2+8+(2*8)+(2*8)+8+1+1+8+(3*1), 'returns expected byte length' ); + + bytes = new Uint8Array( actual.buffer ); + nbytes = bytesPerElement( dtype ); + if ( IS_LITTLE_ENDIAN ) { + t.strictEqual( bytes[ 0 ], 1, 'returns expected endianness' ); + t.strictEqual( bytes[ 1 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 3 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 11 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 19 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 27 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 35 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 43 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 53 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + t.strictEqual( bytes[ 62 ], expected.submodes[ 1 ], 'returns expected submode' ); + t.strictEqual( bytes[ 63 ], expected.submodes[ 2 ], 'returns expected submode' ); + } else { + t.strictEqual( bytes[ 0 ], 0, 'returns expected endianness' ); + t.strictEqual( bytes[ 2 ], expected.dtype, 'returns expected dtype' ); + t.strictEqual( bytes[ 10 ], expected.ndims, 'returns expected ndims' ); + t.strictEqual( bytes[ 18 ], expected.shape[ 0 ], 'returns expected first dimension' ); + t.strictEqual( bytes[ 26 ], expected.shape[ 1 ], 'returns expected second dimension' ); + t.strictEqual( bytes[ 34 ], expected.strides[ 0 ]*nbytes, 'returns expected first stride' ); + t.strictEqual( bytes[ 42 ], expected.strides[ 1 ]*nbytes, 'returns expected second stride' ); + t.strictEqual( bytes[ 50 ], expected.offset*nbytes, 'returns expected offset' ); + t.strictEqual( bytes[ 51 ], expected.order, 'returns expected order' ); + t.strictEqual( bytes[ 52 ], expected.mode, 'returns expected index mode' ); + t.strictEqual( bytes[ 60 ], expected.nsubmodes, 'returns expected number of subscript modes' ); + t.strictEqual( bytes[ 61 ], expected.submodes[ 0 ], 'returns expected submode' ); + t.strictEqual( bytes[ 62 ], expected.submodes[ 1 ], 'returns expected submode' ); + t.strictEqual( bytes[ 63 ], expected.submodes[ 2 ], 'returns expected submode' ); + } + t.end(); +}); diff --git a/base/shape2strides/benchmark/benchmark.js b/base/shape2strides/benchmark/benchmark.js new file mode 100644 index 00000000..dc11ed68 --- /dev/null +++ b/base/shape2strides/benchmark/benchmark.js @@ -0,0 +1,140 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isArray = require( '@stdlib/assert/is-array' ); +var pkg = require( './../package.json' ).name; +var shape2strides = require( './../lib' ); + + +// MAIN // + +bench( pkg+':order=row-major', function benchmark( b ) { + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 0 ] = floor( randu()*10 ); + out = shape2strides( shape, 'row-major' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':order=column-major', function benchmark( b ) { + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = floor( randu()*10 ); + shape[ 1 ] = floor( randu()*10 ); + shape[ 2 ] = floor( randu()*10 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 0 ] = floor( randu()*10 ); + out = shape2strides( shape, 'column-major' ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':assign:order=row-major', function benchmark( b ) { + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = floor( randu()*10 ); + shape[ 1 ] = floor( randu()*10 ); + shape[ 2 ] = floor( randu()*10 ); + + out = new Array( shape.length ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 0 ] = floor( randu()*10 ); + out = shape2strides.assign( shape, 'row-major', out ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':assign:order=column-major', function benchmark( b ) { + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = floor( randu()*10 ); + shape[ 1 ] = floor( randu()*10 ); + shape[ 2 ] = floor( randu()*10 ); + + out = new Array( shape.length ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 0 ] = floor( randu()*10 ); + out = shape2strides.assign( shape, 'column-major', out ); + if ( out.length !== shape.length ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( !isArray( out ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/shape2strides/benchmark/c/Makefile b/base/shape2strides/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/shape2strides/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/shape2strides/benchmark/c/benchmark.c b/base/shape2strides/benchmark/c/benchmark.c new file mode 100644 index 00000000..cf4568c6 --- /dev/null +++ b/base/shape2strides/benchmark/c/benchmark.c @@ -0,0 +1,181 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `shape2strides`. +*/ +#include "stdlib/ndarray/base/shape2strides.h" +#include "stdlib/ndarray/orders.h" +#include +#include +#include +#include +#include +#include + +#define NAME "shape2strides" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t ndims = 3; + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + shape[ 0 ] = (int64_t)( rand_double()*11.0 ); + stdlib_ndarray_shape2strides( ndims, shape, STDLIB_NDARRAY_ROW_MAJOR, out ); + if ( out[ 0 ] < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( out[ 0 ] < 0 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + uint64_t ndims = 3; + int64_t out[ 3 ]; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + shape[ 0 ] = (int64_t)( rand_double()*11.0 ); + stdlib_ndarray_shape2strides( ndims, shape, STDLIB_NDARRAY_COLUMN_MAJOR, out ); + if ( out[ 0 ] < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( out[ 0 ] < 0 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:order=row-major\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:order=column-major\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/shape2strides/examples/c/Makefile b/base/shape2strides/examples/c/Makefile new file mode 100644 index 00000000..ff5293d3 --- /dev/null +++ b/base/shape2strides/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/shape2strides/examples/c/example.c b/base/shape2strides/examples/c/example.c new file mode 100644 index 00000000..c0bb254c --- /dev/null +++ b/base/shape2strides/examples/c/example.c @@ -0,0 +1,39 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/shape2strides.h" +#include "stdlib/ndarray/orders.h" +#include + +int main() { + int64_t shape[] = { 2, 3, 10 }; + int64_t ndims = 3; + int64_t out[ 3 ]; + + stdlib_ndarray_shape2strides( ndims, shape, STDLIB_NDARRAY_ROW_MAJOR, out ); + + int i; + printf( "strides = { " ); + for ( i = 0; i < ndims; i++ ) { + printf( "%lli", out[ i ] ); + if ( i < ndims-1 ) { + printf( ", " ); + } + } + printf( " }\n" ); +} diff --git a/base/shape2strides/examples/index.js b/base/shape2strides/examples/index.js new file mode 100644 index 00000000..4df6fc8c --- /dev/null +++ b/base/shape2strides/examples/index.js @@ -0,0 +1,35 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( './../lib' ); + +var strides; +var shape; +var i; + +shape = [ 0, 0, 0 ]; +for ( i = 0; i < 100; i++ ) { + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + strides = shape2strides( shape, 'row-major' ); + console.log( 'shape: %s. strides: %s.', shape.join( 'x' ), strides.join( ', ' ) ); +} diff --git a/base/shape2strides/test/test.js b/base/shape2strides/test/test.js new file mode 100644 index 00000000..be27cc58 --- /dev/null +++ b/base/shape2strides/test/test.js @@ -0,0 +1,140 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var shape2strides = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof shape2strides, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function generates a stride array from an array shape (row-major)', function test( t ) { + var expected; + var actual; + var shape; + + shape = [ 3, 2 ]; + expected = [ 2, 1 ]; + actual = shape2strides( shape, 'row-major' ); + + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + shape = [ 2, 1, 10 ]; + expected = [ 10, 10, 1 ]; + actual = shape2strides( shape, 'row-major' ); + + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function generates a stride array from an array shape (column-major)', function test( t ) { + var expected; + var actual; + var shape; + + shape = [ 3, 2 ]; + expected = [ 1, 3 ]; + actual = shape2strides( shape, 'column-major' ); + + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + shape = [ 2, 1, 10 ]; + expected = [ 1, 2, 2 ]; + actual = shape2strides( shape, 'column-major' ); + + t.strictEqual( isArray( actual ), true, 'returns an array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'attached to the main function is a method which supports generating a stride array from an array shape in-place (row-major)', function test( t ) { + var expected; + var actual; + var shape; + var out; + + shape = [ 3, 2 ]; + expected = [ 2, 1 ]; + + out = new Array( shape.length ); + actual = shape2strides.assign( shape, 'row-major', out ); + + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + shape = [ 2, 1, 10 ]; + expected = [ 10, 10, 1 ]; + + out = new Array( shape.length ); + actual = shape2strides.assign( shape, 'row-major', out ); + + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'attached to the main function is a method which supports generating a stride array from an array shape in-place (column-major)', function test( t ) { + var expected; + var actual; + var shape; + var out; + + shape = [ 3, 2 ]; + expected = [ 1, 3 ]; + + out = new Array( shape.length ); + actual = shape2strides.assign( shape, 'column-major', out ); + + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + shape = [ 2, 1, 10 ]; + expected = [ 1, 2, 2 ]; + + out = new Array( shape.length ); + actual = shape2strides.assign( shape, 'column-major', out ); + + t.strictEqual( actual, out, 'returns output array' ); + t.strictEqual( actual.length, shape.length, 'returns expected length' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); diff --git a/base/singleton-dimensions/benchmark/benchmark.js b/base/singleton-dimensions/benchmark/benchmark.js new file mode 100644 index 00000000..b9c6c746 --- /dev/null +++ b/base/singleton-dimensions/benchmark/benchmark.js @@ -0,0 +1,57 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var pkg = require( './../package.json' ).name; +var singletonDimensions = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var shape; + var n; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 1, 5 ); + shape[ 1 ] = discreteUniform( 1, 5 ); + shape[ 2 ] = discreteUniform( 1, 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + shape[ 0 ] = floor( randu()*5.0 ); + n = singletonDimensions( shape ); + if ( n < 0 ) { + b.fail( 'should be nonnegative' ); + } + } + b.toc(); + if ( n < 0 ) { + b.fail( 'should be nonnegative' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/singleton-dimensions/benchmark/c/Makefile b/base/singleton-dimensions/benchmark/c/Makefile new file mode 100644 index 00000000..e8a077e0 --- /dev/null +++ b/base/singleton-dimensions/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/singleton-dimensions/benchmark/c/benchmark.c b/base/singleton-dimensions/benchmark/c/benchmark.c new file mode 100644 index 00000000..3ee95c6e --- /dev/null +++ b/base/singleton-dimensions/benchmark/c/benchmark.c @@ -0,0 +1,143 @@ +/** +* @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. +*/ + +/** +* Benchmark `singleton-dimensions`. +*/ +#include "stdlib/ndarray/base/singleton_dimensions.h" +#include +#include +#include +#include +#include +#include + +#define NAME "singleton-dimensions" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t n; + double t; + int i; + + int64_t shape[] = { 5, 2, 1 }; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + shape[ 0 ] = (int64_t)( rand_double()*5.0 ); + n = stdlib_ndarray_singleton_dimensions( ndims, shape ); + if ( n > ndims ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( n > ndims ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/singleton-dimensions/examples/c/Makefile b/base/singleton-dimensions/examples/c/Makefile new file mode 100644 index 00000000..ff5293d3 --- /dev/null +++ b/base/singleton-dimensions/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/singleton-dimensions/examples/c/example.c b/base/singleton-dimensions/examples/c/example.c new file mode 100644 index 00000000..d3ebf2dd --- /dev/null +++ b/base/singleton-dimensions/examples/c/example.c @@ -0,0 +1,27 @@ +/** +* @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/ndarray/base/singleton_dimensions.h" +#include + +int main() { + int64_t shape[] = { 10, 3, 1, 1, 5 }; + + int64_t n = stdlib_ndarray_singleton_dimensions( 5, shape ); + printf( "shape: %llux%llux%llux%llux%llu. singleton dimensions: %llu\n", shape[ 0 ], shape[ 1 ], shape[ 2 ], shape[ 3 ], shape[ 4 ], n ); +} diff --git a/base/singleton-dimensions/examples/index.js b/base/singleton-dimensions/examples/index.js new file mode 100644 index 00000000..d053365c --- /dev/null +++ b/base/singleton-dimensions/examples/index.js @@ -0,0 +1,35 @@ +/** +* @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. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var singletonDimensions = require( './../lib' ); + +var shape; +var n; +var i; + +shape = [ 0, 0, 0 ]; +for ( i = 0; i < 100; i++ ) { + shape[ 0 ] = discreteUniform( 1, 5 ); + shape[ 1 ] = discreteUniform( 1, 5 ); + shape[ 2 ] = discreteUniform( 1, 5 ); + n = singletonDimensions( shape ); + console.log( 'shape: %s. singleton dimensions: %d.', shape.join( 'x' ), n ); +} diff --git a/base/singleton-dimensions/test/test.js b/base/singleton-dimensions/test/test.js new file mode 100644 index 00000000..f92f69fc --- /dev/null +++ b/base/singleton-dimensions/test/test.js @@ -0,0 +1,62 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var singletonDimensions = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof singletonDimensions, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the number of singleton dimensions', function test( t ) { + var expected; + var values; + var n; + var i; + + values = [ + [ 3, 3, 3 ], + [ 1, 1 ], + [ 3, 3, 0, 3 ], + [ 1, 2, 3, 4 ], + [ 5 ] + ]; + + expected = [ + 0, + 2, + 0, + 1, + 0 + ]; + + for ( i = 0; i < values.length; i++ ) { + n = singletonDimensions( values[ i ] ); + t.strictEqual( n, expected[ i ], 'returns expected value for shape '+values[ i ].join( 'x' ) ); + } + t.end(); +}); diff --git a/base/strides2offset/benchmark/benchmark.js b/base/strides2offset/benchmark/benchmark.js new file mode 100644 index 00000000..ccb16280 --- /dev/null +++ b/base/strides2offset/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var strides2offset = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 0, 0, 0 ]; + shape[ 0 ] = discreteUniform( 0, 10 ); + shape[ 1 ] = discreteUniform( 0, 10 ); + shape[ 2 ] = discreteUniform( 0, 10 ); + + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 1 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = strides2offset( shape, strides ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/strides2offset/benchmark/c/Makefile b/base/strides2offset/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/strides2offset/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/strides2offset/benchmark/c/benchmark.c b/base/strides2offset/benchmark/c/benchmark.c new file mode 100644 index 00000000..0f1e845e --- /dev/null +++ b/base/strides2offset/benchmark/c/benchmark.c @@ -0,0 +1,140 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `strides2offset`. +*/ +#include +#include +#include +#include +#include +#include +#include "stdlib/ndarray/base/strides2offset.h" + +#define NAME "strides2offset" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t o; + double t; + int i; + + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 0 ] *= ( rand_double() < 0.5 ) ? -1 : 1; + o = stdlib_ndarray_strides2offset( ndims, shape, strides ); + if ( o > 1e10 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( o > 1e10 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/strides2offset/examples/index.js b/base/strides2offset/examples/index.js new file mode 100644 index 00000000..e1499c10 --- /dev/null +++ b/base/strides2offset/examples/index.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var randu = require( '@stdlib/random/base/randu' ); +var strides2offset = require( './../lib' ); + +var strides; +var offset; +var shape; +var len; +var arr; +var i; +var j; + +shape = [ 0, 0, 0 ]; +shape[ 0 ] = discreteUniform( 1, 10 ); +shape[ 1 ] = discreteUniform( 1, 10 ); +shape[ 2 ] = discreteUniform( 1, 10 ); + +strides = shape2strides( shape, 'row-major' ); +len = numel( shape ); + +arr = []; +for ( i = 0; i < len; i++ ) { + arr.push( i ); +} +for ( i = 0; i < 100; i++ ) { + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + offset = strides2offset( shape, strides ); + console.log( 'arr[0][0][0] = %d', arr[ offset ] ); +} diff --git a/base/strides2offset/test/test.js b/base/strides2offset/test/test.js new file mode 100644 index 00000000..9a05eba8 --- /dev/null +++ b/base/strides2offset/test/test.js @@ -0,0 +1,104 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var strides2offset = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof strides2offset, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function determines an index offset based on a stride array', function test( t ) { + var strides; + var shape; + var o; + + // 2-d, row major... + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 4, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 2, -1 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 5, 'returns expected value' ); + + // 2-d, column major... + shape = [ 3, 2 ]; + strides = [ 1, 3 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -1, 3 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ 1, -3 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 3, 'returns expected value' ); + + shape = [ 3, 2 ]; + strides = [ -1, -3 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 5, 'returns expected value' ); + + // 3-d, row major... + shape = [ 2, 3, 10 ]; + strides = [ 30, 10, 1 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + shape = [ 2, 3, 10 ]; + strides = [ 30, -10, 1 ]; + + o = strides2offset( shape, strides ); + t.strictEqual( o, 20, 'returns expected value' ); + + t.end(); +}); diff --git a/base/strides2order/benchmark/benchmark.js b/base/strides2order/benchmark/benchmark.js new file mode 100644 index 00000000..2354480a --- /dev/null +++ b/base/strides2order/benchmark/benchmark.js @@ -0,0 +1,106 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var strides2order = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::row-major', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 1 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = strides2order( strides ); + if ( typeof out !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::column-major', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'column-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 1 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = strides2order( strides ); + if ( typeof out !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::both', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 10 ]; + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 0 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = strides2order( strides ); + if ( typeof out !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/strides2order/benchmark/c/Makefile b/base/strides2order/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/strides2order/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/strides2order/benchmark/c/benchmark.c b/base/strides2order/benchmark/c/benchmark.c new file mode 100644 index 00000000..65554844 --- /dev/null +++ b/base/strides2order/benchmark/c/benchmark.c @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `strides2order`. +*/ +#include "stdlib/ndarray/base/strides2order.h" +#include +#include +#include +#include +#include +#include + +#define NAME "strides2order" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int8_t o; + double t; + int i; + + int64_t strides[] = { 3, 2, 1 }; + int64_t ndims = 3; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + strides[ 0 ] = (int64_t)( (rand_double()*10.0) - 5.0 ); + o = stdlib_ndarray_strides2order( ndims, strides ); + if ( o > 3 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( o > 3 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/strides2order/examples/index.js b/base/strides2order/examples/index.js new file mode 100644 index 00000000..06b666d1 --- /dev/null +++ b/base/strides2order/examples/index.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var randu = require( '@stdlib/random/base/randu' ); +var strides2order = require( './../lib' ); + +var strides; +var order; +var shape; +var i; +var j; + +shape = [ 0, 0, 0 ]; + +for ( i = 0; i < 20; i++ ) { + // Generate a random array shape: + shape[ 0 ] = discreteUniform( 1, 10 ); + shape[ 1 ] = discreteUniform( 1, 10 ); + shape[ 2 ] = discreteUniform( 1, 10 ); + + // Compute the strides: + if ( randu() < 0.5 ) { + strides = shape2strides( shape, 'row-major' ); + } else { + strides = shape2strides( shape, 'column-major' ); + } + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + + // Determine the order: + order = strides2order( strides ); + console.log( 'Strides: %s. Order: %s.', strides.join( ',' ), order ); +} diff --git a/base/strides2order/test/test.js b/base/strides2order/test/test.js new file mode 100644 index 00000000..6ab80dd9 --- /dev/null +++ b/base/strides2order/test/test.js @@ -0,0 +1,124 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var strides2order = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof strides2order, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function determines the array order based on a provided stride array', function test( t ) { + var strides; + var o; + + // 1-d, both row-major and column-major + strides = [ 1 ]; + o = strides2order( strides ); + t.strictEqual( o, 3, 'returns expected value' ); + + strides = [ 10 ]; + o = strides2order( strides ); + t.strictEqual( o, 3, 'returns expected value' ); + + strides = [ -1 ]; + o = strides2order( strides ); + t.strictEqual( o, 3, 'returns expected value' ); + + strides = [ -10 ]; + o = strides2order( strides ); + t.strictEqual( o, 3, 'returns expected value' ); + + // 2-d, row-major... + strides = [ 2, 1 ]; + o = strides2order( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ -2, 1 ]; + o = strides2order( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ 2, -1 ]; + o = strides2order( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ -2, -1 ]; + o = strides2order( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + // 2-d, column-major... + strides = [ 1, 3 ]; + o = strides2order( strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + strides = [ -1, 3 ]; + o = strides2order( strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + strides = [ 1, -3 ]; + o = strides2order( strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + strides = [ -1, -3 ]; + o = strides2order( strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + // 3-d, row-major... + strides = [ 30, 10, 1 ]; + o = strides2order( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + strides = [ 30, -10, 1 ]; + o = strides2order( strides ); + t.strictEqual( o, 1, 'returns expected value' ); + + // 3-d, column-major... + strides = [ 1, 10, 30 ]; + o = strides2order( strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + strides = [ 1, -10, 30 ]; + o = strides2order( strides ); + t.strictEqual( o, 2, 'returns expected value' ); + + // 3-d, neither row-major nor column-major... + strides = [ 30, 1, 10 ]; + o = strides2order( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + strides = [ 2, 3, 1 ]; + o = strides2order( strides ); + t.strictEqual( o, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided an empty stride array, the function returns `0` (none)', function test( t ) { + var o = strides2order( [] ); + t.strictEqual( o, 0, 'returns expected value' ); + t.end(); +}); diff --git a/base/sub2ind/benchmark/benchmark.js b/base/sub2ind/benchmark/benchmark.js new file mode 100644 index 00000000..f8d2c17c --- /dev/null +++ b/base/sub2ind/benchmark/benchmark.js @@ -0,0 +1,403 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var pkg = require( './../package.json' ).name; +var sub2ind = require( './../lib' ); + + +// MAIN // + +bench( pkg+':mode=[throw]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'throw' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[throw],offset=0', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + mode = [ 'throw' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'wrap' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*100.0 ) - 50.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap],offset=0', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + mode = [ 'wrap' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*100.0 ) - 50.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[clamp]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'clamp' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[clamp],offset=0', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + for ( i = 0; i < shape.length; i++ ) { + strides[ i ] *= -1; + } + offset = 0; + mode = [ 'clamp' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap,clamp]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'wrap', 'clamp' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap,clamp,clamp]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'wrap', 'clamp', 'clamp' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[clamp,wrap]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'clamp', 'wrap' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[clamp,wrap,wrap]', function benchmark( b ) { + var strides; + var offset; + var shape; + var mode; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + offset = strides2offset( shape, strides ); + mode = [ 'clamp', 'wrap', 'wrap' ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, strides, offset, s0, s1, s2, mode ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/sub2ind/benchmark/c/Makefile b/base/sub2ind/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/sub2ind/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/sub2ind/benchmark/c/benchmark.c b/base/sub2ind/benchmark/c/benchmark.c new file mode 100644 index 00000000..5e2e5de7 --- /dev/null +++ b/base/sub2ind/benchmark/c/benchmark.c @@ -0,0 +1,573 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `sub2ind`. +*/ +#include "stdlib/ndarray/base/sub2ind.h" +#include "stdlib/ndarray/index_modes.h" +#include +#include +#include +#include +#include +#include + +#define NAME "sub2ind" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_ERROR + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( rand_double()*10.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { -100, -10, -1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_ERROR + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( rand_double()*10.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark3() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_WRAP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0)-5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark4() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { -100, -10, -1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_WRAP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0) - 5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark5() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_CLAMP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0)-5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark6() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { -100, -10, -1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_CLAMP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0) - 5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark7() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_WRAP, + STDLIB_NDARRAY_INDEX_CLAMP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0)-5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark8() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_WRAP, + STDLIB_NDARRAY_INDEX_CLAMP, + STDLIB_NDARRAY_INDEX_CLAMP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0)-5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark9() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_CLAMP, + STDLIB_NDARRAY_INDEX_WRAP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0)-5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark10() { + double elapsed; + int64_t idx; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + + int64_t sub[] = { 5, 5, 5 }; + + int64_t nmodes = 1; + int8_t modes[] = { + STDLIB_NDARRAY_INDEX_CLAMP, + STDLIB_NDARRAY_INDEX_WRAP, + STDLIB_NDARRAY_INDEX_WRAP + }; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*20.0)-5.0 ); + idx = stdlib_ndarray_sub2ind( ndims, shape, strides, offset, sub, nmodes, modes ); + if ( idx < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[error]\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[error],offset=0\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[wrap]\n", NAME ); + elapsed = benchmark3(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[wrap],offset=0\n", NAME ); + elapsed = benchmark4(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[clamp]\n", NAME ); + elapsed = benchmark5(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[clamp],offset=0\n", NAME ); + elapsed = benchmark6(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[wrap,clamp]\n", NAME ); + elapsed = benchmark7(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[wrap,clamp,clamp]\n", NAME ); + elapsed = benchmark8(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[clamp,wrap]\n", NAME ); + elapsed = benchmark9(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=[clamp,wrap,wrap]\n", NAME ); + elapsed = benchmark10(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/sub2ind/benchmark/julia/REQUIRE b/base/sub2ind/benchmark/julia/REQUIRE new file mode 100644 index 00000000..98645e19 --- /dev/null +++ b/base/sub2ind/benchmark/julia/REQUIRE @@ -0,0 +1,2 @@ +julia 1.5 +BenchmarkTools 0.5.0 diff --git a/base/sub2ind/benchmark/julia/benchmark.jl b/base/sub2ind/benchmark/julia/benchmark.jl new file mode 100644 index 00000000..a385ef11 --- /dev/null +++ b/base/sub2ind/benchmark/julia/benchmark.jl @@ -0,0 +1,144 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +import BenchmarkTools +using Printf + +# Benchmark variables: +name = "sub2ind"; +repeats = 3; + +""" + print_version() + +Prints the TAP version. + +# Examples + +``` julia +julia> print_version() +``` +""" +function print_version() + @printf( "TAP version 13\n" ); +end + +""" + print_summary( total, passing ) + +Print the benchmark summary. + +# Arguments + +* `total`: total number of tests +* `passing`: number of passing tests + +# Examples + +``` julia +julia> print_summary( 3, 3 ) +``` +""" +function print_summary( total, passing ) + @printf( "#\n" ); + @printf( "1..%d\n", total ); # TAP plan + @printf( "# total %d\n", total ); + @printf( "# pass %d\n", passing ); + @printf( "#\n" ); + @printf( "# ok\n" ); +end + +""" + print_results( iterations, elapsed ) + +Print benchmark results. + +# Arguments + +* `iterations`: number of iterations +* `elapsed`: elapsed time (in seconds) + +# Examples + +``` julia +julia> print_results( 1000000, 0.131009101868 ) +``` +""" +function print_results( iterations, elapsed ) + rate = iterations / elapsed + + @printf( " ---\n" ); + @printf( " iterations: %d\n", iterations ); + @printf( " elapsed: %0.9f\n", elapsed ); + @printf( " rate: %0.9f\n", rate ); + @printf( " ...\n" ); +end + +""" + benchmark() + +Run a benchmark. + +# Notes + +* Benchmark results are returned as a two-element array: [ iterations, elapsed ]. +* The number of iterations is not the true number of iterations. Instead, an 'iteration' is defined as a 'sample', which is a computed estimate for a single evaluation. +* The elapsed time is in seconds. + +# Examples + +``` julia +julia> out = benchmark(); +``` +""" +function benchmark() + t = BenchmarkTools.@benchmark Base._sub2ind( (10,10,10), 9, 8, Int32( floor( rand()*10.0 ) ) ) samples=1e6 + + # Compute the total "elapsed" time and convert from nanoseconds to seconds: + s = sum( t.times ) / 1.0e9; + + # Determine the number of "iterations": + iter = length( t.times ); + + # Return the results: + [ iter, s ]; +end + +""" + main() + +Run benchmarks. + +# Examples + +``` julia +julia> main(); +``` +""" +function main() + print_version(); + for i in 1:repeats + @printf( "# julia::%s\n", name ); + results = benchmark(); + print_results( results[ 1 ], results[ 2 ] ); + @printf( "ok %d benchmark finished\n", i ); + end + print_summary( repeats, repeats ); +end + +main(); diff --git a/base/sub2ind/benchmark/python/numpy/benchmark.py b/base/sub2ind/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..f08b8fae --- /dev/null +++ b/base/sub2ind/benchmark/python/numpy/benchmark.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.ravel_multi_index.""" + +from __future__ import print_function +import timeit + +NAME = "sub2ind" +REPEATS = 3 +ITERATIONS = 1000000 + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(elapsed): + """Print benchmark results. + + # Arguments + + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(0.131009101868) + ``` + """ + rate = ITERATIONS / elapsed + + print(" ---") + print(" iterations: " + str(ITERATIONS)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(): + """Run the benchmark and print benchmark results.""" + setup = "import numpy as np; from random import random;" + stmt = "y = np.ravel_multi_index((9, 8, int(random()*10.0)), (10, 10, 10))" + + t = timeit.Timer(stmt, setup=setup) + + print_version() + + for i in range(REPEATS): + print("# python::numpy::" + NAME) + elapsed = t.timeit(number=ITERATIONS) + print_results(elapsed) + print("ok " + str(i+1) + " benchmark finished") + + print_summary(REPEATS, REPEATS) + + +def main(): + """Run the benchmark.""" + benchmark() + + +if __name__ == "__main__": + main() diff --git a/base/sub2ind/examples/index.js b/base/sub2ind/examples/index.js new file mode 100644 index 00000000..5c658eff --- /dev/null +++ b/base/sub2ind/examples/index.js @@ -0,0 +1,65 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var randu = require( '@stdlib/random/base/randu' ); +var sub2ind = require( './../lib' ); + +var shape = [ 3, 3 ]; +var strides = shape2strides( shape, 'row-major' ); +var mode = 'throw'; +var len = numel( shape ); + +var arr = []; +var i; +for ( i = 0; i < len; i++ ) { + arr.push( i ); +} + +var offset; +var idx; +var row; +var j; +var n; +var m; +for ( i = 0; i < 20; i++ ) { + j = discreteUniform( 0, shape.length-1 ); + strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1; + offset = strides2offset( shape, strides ); + + console.log( '' ); + console.log( 'Dimensions: %s.', shape.join( 'x' ) ); + console.log( 'Strides: %s.', strides.join( ',' ) ); + console.log( 'View:' ); + for ( n = 0; n < shape[ 0 ]; n++ ) { + row = ' '; + for ( m = 0; m < shape[ 1 ]; m++ ) { + idx = sub2ind( shape, strides, offset, n, m, mode ); + row += arr[ idx ]; + if ( m < shape[ 1 ]-1 ) { + row += ', '; + } + } + console.log( row ); + } +} diff --git a/base/sub2ind/test/test.js b/base/sub2ind/test/test.js new file mode 100644 index 00000000..8ed71e80 --- /dev/null +++ b/base/sub2ind/test/test.js @@ -0,0 +1,403 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var sub2ind = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof sub2ind, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (simple)', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 2; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (offset=0)', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 0; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ 2, -1 ]; + offset = 1; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (offset=0)', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ 2, -1 ]; + offset = 0; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ -2, -1 ]; + offset = 3; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (offset=0)', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ -2, -1 ]; + offset = 0; + mode = [ 'throw' ]; + + idx = sub2ind( shape, strides, offset, 0, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 1, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 1, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if a dimension index `mode` is `throw`, the function throws if provided a subscript which exceeds array dimensions', function test( t ) { + var strides; + var offset; + var shape; + var mode; + + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + mode = [ 'throw' ]; + + t.throws( foo, RangeError, 'throws a range error' ); + t.throws( bar, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + sub2ind( shape, strides, offset, 999999, 1, mode ); + } + + function bar() { + sub2ind( shape, strides, offset, 1, 999999, mode ); + } +}); + +tape( 'if a dimension index `mode` is `wrap`, the function wraps a subscript which exceeds array dimensions', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + mode = [ 'wrap' ]; + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 2, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 3, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, -1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, -3, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 5, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 4, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, -4, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if a dimension index `mode` is `wrap`, the function wraps a subscript which exceeds array dimensions (offset=0)', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 0; + mode = [ 'wrap' ]; + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 2, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 3, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, -1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, -3, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 5, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 4, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, -4, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if a dimension index `mode` is `clamp`, the function clamps a subscript which exceeds array dimensions', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + mode = [ 'clamp' ]; + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 2, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 3, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, -3, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 5, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if a dimension index `mode` is `clamp`, the function clamps a subscript which exceeds array dimensions (offset=0)', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2 ]; + strides = [ -2, 1 ]; + offset = 0; + mode = [ 'clamp' ]; + + idx = sub2ind( shape, strides, offset, 1, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 2, 0, mode ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 0, 3, mode ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, -3, 0, mode ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, strides, offset, 1, 5, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function supports providing mixed modes', function test( t ) { + var strides; + var offset; + var shape; + var mode; + var idx; + + shape = [ 2, 2, 2 ]; + strides = [ 4, 2, 1 ]; + offset = 0; + mode = [ 'wrap', 'clamp' ]; + + idx = sub2ind( shape, strides, offset, -2, 10, -1, mode ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); diff --git a/base/test/test.js b/base/test/test.js new file mode 100644 index 00000000..14dda1f7 --- /dev/null +++ b/base/test/test.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var objectKeys = require( '@stdlib/utils/keys' ); +var ns = require( './../lib' ); + + +// TESTS // + +tape( 'main export is an object', function test( t ) { + t.ok( true, __filename ); + t.equal( typeof ns, 'object', 'main export is an object' ); + t.end(); +}); + +tape( 'the exported object contains key-value pairs', function test( t ) { + var keys = objectKeys( ns ); + t.equal( keys.length > 0, true, 'has keys' ); + t.end(); +}); diff --git a/base/to-array/benchmark/benchmark.js b/base/to-array/benchmark/benchmark.js new file mode 100644 index 00000000..b7f00049 --- /dev/null +++ b/base/to-array/benchmark/benchmark.js @@ -0,0 +1,113 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isArrayArray = require( '@stdlib/assert/is-array-array' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var pkg = require( './../package.json' ).name; +var ndarray2array = require( './../lib' ); + + +// MAIN // + +bench( pkg+':order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var order; + var shape; + var len; + var out; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + + buffer = []; + for ( i = 0; i < len; i++ ) { + buffer.push( i ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 1 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = ndarray2array( buffer, shape, strides, offset, order ); + if ( out.length !== shape[ 0 ] ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( + !isArrayArray( out ) || + !isArrayArray( out[ 0 ] ) + ) { + b.fail( 'should return an array of arrays' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var order; + var shape; + var len; + var out; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + len = numel( shape ); + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + + buffer = []; + for ( i = 0; i < len; i++ ) { + buffer.push( i ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ 1 ] *= ( randu() < 0.5 ) ? -1 : 1; + out = ndarray2array( buffer, shape, strides, offset, order ); + if ( out.length !== shape[ 0 ] ) { + b.fail( 'should have expected length' ); + } + } + b.toc(); + if ( + !isArrayArray( out ) || + !isArrayArray( out[ 0 ] ) + ) { + b.fail( 'should return an array of arrays' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/to-array/benchmark/numpy/benchmark.py b/base/to-array/benchmark/numpy/benchmark.py new file mode 100644 index 00000000..ffcf8883 --- /dev/null +++ b/base/to-array/benchmark/numpy/benchmark.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.ndarray.tolist.""" + +from __future__ import print_function +import timeit + +NAME = "to-array" +REPEATS = 3 +ITERATIONS = 10000 +COUNT = [0] # use a list to allow modification within nested scopes + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(iterations, elapsed): + """Print benchmark results. + + # Arguments + + * `iterations`: number of iterations + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(100000, 0.131009101868) + ``` + """ + rate = iterations / elapsed + + print(" ---") + print(" iterations: " + str(iterations)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(name, setup, stmt, iterations): + """Run the benchmark and print benchmark results. + + # Arguments + + * `name`: benchmark name (suffix) + * `setup`: benchmark setup + * `stmt`: statement to benchmark + * `iterations`: number of iterations + + # Examples + + ``` python + python> benchmark("::random", "from random import random;", "y = random()", 1000000) + ``` + """ + t = timeit.Timer(stmt, setup=setup) + + print_version() + + i = 0 + while i < REPEATS: + print("# python::numpy::" + NAME + name) + COUNT[0] += 1 + elapsed = t.timeit(number=iterations) + print_results(iterations, elapsed) + print("ok " + str(COUNT[0]) + " benchmark finished") + i += 1 + + +def main(): + """Run the benchmarks.""" + name = "" + setup = "import numpy as np; from random import random; x = np.zeros((10,10,10))" + stmt = "y = x.tolist()" + benchmark(name, setup, stmt, ITERATIONS) + + print_summary(COUNT[0], COUNT[0]) + + +if __name__ == "__main__": + main() diff --git a/base/to-array/examples/index.js b/base/to-array/examples/index.js new file mode 100644 index 00000000..879864a5 --- /dev/null +++ b/base/to-array/examples/index.js @@ -0,0 +1,60 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var dicreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var ndarray2array = require( './../lib' ); + +// Create a data buffer: +var buffer = []; +var i; +for ( i = 0; i < 27; i++ ) { + buffer.push( i ); +} + +// Specify array meta data: +var shape = [ 3, 3, 3 ]; +var order = 'column-major'; +var ndims = shape.length; + +// Compute array meta data: +var strides = shape2strides( shape, order ); +var offset = strides2offset( shape, strides ); + +// Print array information: +console.log( '' ); +console.log( 'Dims: %s', shape.join( 'x' ) ); + +// Random flip strides and convert an ndarray to a nested array... +var arr; +var j; +for ( i = 0; i < 20; i++ ) { + j = dicreteUniform( 0, ndims-1 ); + strides[ j ] *= -1; + offset = strides2offset( shape, strides ); + + console.log( '' ); + console.log( 'Strides: %s', strides.join( ',' ) ); + console.log( 'Offset: %d', offset ); + + arr = ndarray2array( buffer, shape, strides, offset, order ); + console.log( JSON.stringify( arr ) ); +} diff --git a/base/to-array/test/test.js b/base/to-array/test/test.js new file mode 100644 index 00000000..79ae0854 --- /dev/null +++ b/base/to-array/test/test.js @@ -0,0 +1,300 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var ndarray2array = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray2array, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an empty array if provided an empty buffer/shape', function test( t ) { + var out = ndarray2array( [], [], [], 0, 'row-major' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.strictEqual( out.length, 0, 'returns an empty array' ); + t.end(); +}); + +tape( 'the function returns an empty array if provided a dimension which has zero elements', function test( t ) { + var out = ndarray2array( [ 1, 2, 3, 4 ], [ 2, 0 ], [ 0, 0 ], 0, 'row-major' ); + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.strictEqual( out.length, 0, 'returns an empty array' ); + t.end(); +}); + +tape( 'the function converts an ndarray buffer to a generic array (1d; order=row-major)', function test( t ) { + var expected; + var strides; + var offset; + var buffer; + var order; + var shape; + var out; + + buffer = [ 1, 2, 3, 4, 5, 6 ]; + + shape = [ 6 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ 1, 2, 3, 4, 5, 6 ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts an ndarray buffer to a generic array (1d; order=column-major)', function test( t ) { + var expected; + var strides; + var offset; + var buffer; + var order; + var shape; + var out; + + buffer = [ 1, 2, 3, 4, 5, 6 ]; + + shape = [ 6 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 5; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ 6, 5, 4, 3, 2, 1 ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts an ndarray buffer to a generic array (2d; order=row-major)', function test( t ) { + var expected; + var strides; + var offset; + var buffer; + var order; + var shape; + var out; + + buffer = [ 1, 2, 3, 4, 5, 6 ]; + + shape = [ 3, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 1, 2 ], + [ 3, 4 ], + [ 5, 6 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ -2, 1 ]; + offset = 4; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 5, 6 ], + [ 3, 4 ], + [ 1, 2 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ 2, -1 ]; + offset = 1; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 2, 1 ], + [ 4, 3 ], + [ 6, 5 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ -2, -1 ]; + offset = 5; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 6, 5 ], + [ 4, 3 ], + [ 2, 1 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts an ndarray buffer to a generic array (2d; order=column-major)', function test( t ) { + var expected; + var strides; + var offset; + var buffer; + var order; + var shape; + var out; + + buffer = [ 1, 2, 3, 4, 5, 6 ]; + + shape = [ 3, 2 ]; + order = 'column-major'; + strides = [ 1, 3 ]; + offset = 0; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 1, 4 ], + [ 2, 5 ], + [ 3, 6 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ -1, 3 ]; + offset = 2; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 3, 6 ], + [ 2, 5 ], + [ 1, 4 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ 1, -3 ]; + offset = 3; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 4, 1 ], + [ 5, 2 ], + [ 6, 3 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ -1, -3 ]; + offset = 5; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ 6, 3 ], + [ 5, 2 ], + [ 4, 1 ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts an ndarray buffer to a generic array (3d; order=row-major)', function test( t ) { + var expected; + var strides; + var offset; + var buffer; + var order; + var shape; + var out; + + buffer = [ 1, 2, 3, 4, 5, 6, 7, 8 ]; + + shape = [ 2, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ [ 1, 2 ], [ 3, 4 ] ], + [ [ 5, 6 ], [ 7, 8 ] ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ -4, -2, -1 ]; + offset = 7; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ [ 8, 7 ], [ 6, 5 ] ], + [ [ 4, 3 ], [ 2, 1 ] ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts an ndarray buffer to a generic array (3d; order=column-major)', function test( t ) { + var expected; + var strides; + var offset; + var buffer; + var order; + var shape; + var out; + + buffer = [ 1, 2, 3, 4, 5, 6, 7, 8 ]; + + shape = [ 2, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2, 4 ]; + offset = 0; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ [ 1, 5 ], [ 3, 7 ] ], + [ [ 2, 6 ], [ 4, 8 ] ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + strides = [ -1, -2, -4 ]; + offset = 7; + + out = ndarray2array( buffer, shape, strides, offset, order ); + expected = [ + [ [ 8, 4 ], [ 6, 2 ] ], + [ [ 7, 3 ], [ 5, 1 ] ] + ]; + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.deepEqual( out, expected, 'returns expected value' ); + + t.end(); +}); diff --git a/base/unary/benchmark/benchmark.10d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.10d_blocked_columnmajor.js new file mode 100644 index 00000000..b3ac9f50 --- /dev/null +++ b/base/unary/benchmark/benchmark.10d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/10d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/10.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 9 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.10d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.10d_blocked_rowmajor.js new file mode 100644 index 00000000..a65ea59b --- /dev/null +++ b/base/unary/benchmark/benchmark.10d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/10d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/10.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 9 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.10d_columnmajor.js b/base/unary/benchmark/benchmark.10d_columnmajor.js new file mode 100644 index 00000000..16a519b4 --- /dev/null +++ b/base/unary/benchmark/benchmark.10d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/10d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/10.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 9 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.10d_rowmajor.js b/base/unary/benchmark/benchmark.10d_rowmajor.js new file mode 100644 index 00000000..7a591389 --- /dev/null +++ b/base/unary/benchmark/benchmark.10d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/10d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/10.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 9 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.11d_columnmajor.js b/base/unary/benchmark/benchmark.11d_columnmajor.js new file mode 100644 index 00000000..961067d0 --- /dev/null +++ b/base/unary/benchmark/benchmark.11d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/nd.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/11.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 10 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.11d_rowmajor.js b/base/unary/benchmark/benchmark.11d_rowmajor.js new file mode 100644 index 00000000..d56288c6 --- /dev/null +++ b/base/unary/benchmark/benchmark.11d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/nd.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/11.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 10 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.1d_columnmajor.js b/base/unary/benchmark/benchmark.1d_columnmajor.js new file mode 100644 index 00000000..b59fd90e --- /dev/null +++ b/base/unary/benchmark/benchmark.1d_columnmajor.js @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( [ x, y ], identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.1d_rowmajor.js b/base/unary/benchmark/benchmark.1d_rowmajor.js new file mode 100644 index 00000000..6d09d8dd --- /dev/null +++ b/base/unary/benchmark/benchmark.1d_rowmajor.js @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( [ x, y ], identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.2d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.2d_blocked_columnmajor.js new file mode 100644 index 00000000..68e7218b --- /dev/null +++ b/base/unary/benchmark/benchmark.2d_blocked_columnmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/2d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( sqrt( len ) ); + sh = [ len, len ]; + len *= len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.2d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.2d_blocked_rowmajor.js new file mode 100644 index 00000000..134fd531 --- /dev/null +++ b/base/unary/benchmark/benchmark.2d_blocked_rowmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/2d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( sqrt( len ) ); + sh = [ len, len ]; + len *= len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.2d_columnmajor.js b/base/unary/benchmark/benchmark.2d_columnmajor.js new file mode 100644 index 00000000..40152a27 --- /dev/null +++ b/base/unary/benchmark/benchmark.2d_columnmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/2d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( sqrt( len ) ); + sh = [ len, len ]; + len *= len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.2d_rowmajor.js b/base/unary/benchmark/benchmark.2d_rowmajor.js new file mode 100644 index 00000000..d4043f81 --- /dev/null +++ b/base/unary/benchmark/benchmark.2d_rowmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/2d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( sqrt( len ) ); + sh = [ len, len ]; + len *= len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.2d_rowmajor_accessors.js b/base/unary/benchmark/benchmark.2d_rowmajor_accessors.js new file mode 100644 index 00000000..1ba36fe3 --- /dev/null +++ b/base/unary/benchmark/benchmark.2d_rowmajor_accessors.js @@ -0,0 +1,183 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/2d_accessors.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Returns an array data buffer element. +* +* @private +* @param {Collection} buf - data buffer +* @param {NonNegativeInteger} idx - element index +* @returns {*} element +*/ +function get( buf, idx ) { + return buf[ idx ]; +} + +/** +* Sets an array data buffer element. +* +* @private +* @param {Collection} buf - data buffer +* @param {NonNegativeInteger} idx - element index +* @param {*} value - value to set +*/ +function set( buf, idx, value ) { + buf[ idx ] = value; +} + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order, + 'accessors': true, + 'getter': get, + 'setter': set + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order, + 'accessors': true, + 'getter': get, + 'setter': set + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::accessors:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::accessors:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( sqrt( len ) ); + sh = [ len, len ]; + len *= len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::accessors:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.2d_rowmajor_accessors_complex.js b/base/unary/benchmark/benchmark.2d_rowmajor_accessors_complex.js new file mode 100644 index 00000000..cfe45cd4 --- /dev/null +++ b/base/unary/benchmark/benchmark.2d_rowmajor_accessors_complex.js @@ -0,0 +1,190 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var ctors = require( '@stdlib/array/typed-complex-ctors' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/2d_accessors.js' ); + + +// VARIABLES // + +var types = [ 'complex64' ]; +var order = 'row-major'; +var abtype = { + 'complex64': 'float32', + 'complex128': 'float64' +}; + + +// FUNCTIONS // + +/** +* Returns an array data buffer element. +* +* @private +* @param {Collection} buf - data buffer +* @param {NonNegativeInteger} idx - element index +* @returns {*} element +*/ +function get( buf, idx ) { + return buf.get( idx ); +} + +/** +* Sets an array data buffer element. +* +* @private +* @param {Collection} buf - data buffer +* @param {NonNegativeInteger} idx - element index +* @param {*} value - value to set +*/ +function set( buf, idx, value ) { + buf.set( value, idx ); +} + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var xbuf; + var ybuf; + var x; + var y; + var i; + + xbuf = filledarray( 0.0, len*2, abtype[ xtype ] ); + ybuf = filledarray( 0.0, len*2, abtype[ ytype ] ); + for ( i = 0; i < len*2; i++ ) { + xbuf[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': new ( ctors( xtype ) )( xbuf.buffer ), + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order, + 'accessors': true, + 'getter': get, + 'setter': set + }; + y = { + 'dtype': ytype, + 'data': new ( ctors( ytype ) )( ybuf.buffer ), + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order, + 'accessors': true, + 'getter': get, + 'setter': set + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( ybuf[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( ybuf[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 5; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::accessors:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::accessors:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( sqrt( len ) ); + sh = [ len, len ]; + len *= len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::accessors:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.3d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.3d_blocked_columnmajor.js new file mode 100644 index 00000000..37a82c86 --- /dev/null +++ b/base/unary/benchmark/benchmark.3d_blocked_columnmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var cbrt = require( '@stdlib/math/base/special/cbrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/3d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( cbrt( len ) ); + sh = [ len, len, len ]; + len *= len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.3d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.3d_blocked_rowmajor.js new file mode 100644 index 00000000..778cc824 --- /dev/null +++ b/base/unary/benchmark/benchmark.3d_blocked_rowmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var cbrt = require( '@stdlib/math/base/special/cbrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/3d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( cbrt( len ) ); + sh = [ len, len, len ]; + len *= len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.3d_columnmajor.js b/base/unary/benchmark/benchmark.3d_columnmajor.js new file mode 100644 index 00000000..86102df6 --- /dev/null +++ b/base/unary/benchmark/benchmark.3d_columnmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var cbrt = require( '@stdlib/math/base/special/cbrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/3d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( cbrt( len ) ); + sh = [ len, len, len ]; + len *= len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.3d_rowmajor.js b/base/unary/benchmark/benchmark.3d_rowmajor.js new file mode 100644 index 00000000..585f49a4 --- /dev/null +++ b/base/unary/benchmark/benchmark.3d_rowmajor.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var cbrt = require( '@stdlib/math/base/special/cbrt' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/3d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( cbrt( len ) ); + sh = [ len, len, len ]; + len *= len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.4d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.4d_blocked_columnmajor.js new file mode 100644 index 00000000..6f00ee15 --- /dev/null +++ b/base/unary/benchmark/benchmark.4d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/4d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/4.0 ) ); + sh = [ len, len, len, len ]; + len *= len * len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.4d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.4d_blocked_rowmajor.js new file mode 100644 index 00000000..8c88678b --- /dev/null +++ b/base/unary/benchmark/benchmark.4d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/4d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/4.0 ) ); + sh = [ len, len, len, len ]; + len *= len * len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.4d_columnmajor.js b/base/unary/benchmark/benchmark.4d_columnmajor.js new file mode 100644 index 00000000..4102f4a5 --- /dev/null +++ b/base/unary/benchmark/benchmark.4d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/4d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/4.0 ) ); + sh = [ len, len, len, len ]; + len *= len * len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.4d_rowmajor.js b/base/unary/benchmark/benchmark.4d_rowmajor.js new file mode 100644 index 00000000..43a5a7fc --- /dev/null +++ b/base/unary/benchmark/benchmark.4d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/4d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/4.0 ) ); + sh = [ len, len, len, len ]; + len *= len * len * len; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.5d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.5d_blocked_columnmajor.js new file mode 100644 index 00000000..c9d3e058 --- /dev/null +++ b/base/unary/benchmark/benchmark.5d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/5d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/5.0 ) ); + sh = [ len, len, len, len, len ]; + len *= pow( len, 4 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.5d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.5d_blocked_rowmajor.js new file mode 100644 index 00000000..23d94577 --- /dev/null +++ b/base/unary/benchmark/benchmark.5d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/5d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/5.0 ) ); + sh = [ len, len, len, len, len ]; + len *= pow( len, 4 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.5d_columnmajor.js b/base/unary/benchmark/benchmark.5d_columnmajor.js new file mode 100644 index 00000000..d4060221 --- /dev/null +++ b/base/unary/benchmark/benchmark.5d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/5d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/5.0 ) ); + sh = [ len, len, len, len, len ]; + len *= pow( len, 4 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.5d_rowmajor.js b/base/unary/benchmark/benchmark.5d_rowmajor.js new file mode 100644 index 00000000..849a86f3 --- /dev/null +++ b/base/unary/benchmark/benchmark.5d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/5d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/5.0 ) ); + sh = [ len, len, len, len, len ]; + len *= pow( len, 4 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.6d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.6d_blocked_columnmajor.js new file mode 100644 index 00000000..e9df7170 --- /dev/null +++ b/base/unary/benchmark/benchmark.6d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/6d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/6.0 ) ); + sh = [ len, len, len, len, len, len ]; + len *= pow( len, 5 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.6d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.6d_blocked_rowmajor.js new file mode 100644 index 00000000..bf8c2f87 --- /dev/null +++ b/base/unary/benchmark/benchmark.6d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/6d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/6.0 ) ); + sh = [ len, len, len, len, len, len ]; + len *= pow( len, 5 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.6d_columnmajor.js b/base/unary/benchmark/benchmark.6d_columnmajor.js new file mode 100644 index 00000000..ea6d29ab --- /dev/null +++ b/base/unary/benchmark/benchmark.6d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/6d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/6.0 ) ); + sh = [ len, len, len, len, len, len ]; + len *= pow( len, 5 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.6d_rowmajor.js b/base/unary/benchmark/benchmark.6d_rowmajor.js new file mode 100644 index 00000000..e2af3d2b --- /dev/null +++ b/base/unary/benchmark/benchmark.6d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/6d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/6.0 ) ); + sh = [ len, len, len, len, len, len ]; + len *= pow( len, 5 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.7d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.7d_blocked_columnmajor.js new file mode 100644 index 00000000..76d64bb9 --- /dev/null +++ b/base/unary/benchmark/benchmark.7d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/7d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/7.0 ) ); + sh = [ len, len, len, len, len, len, len ]; + len *= pow( len, 6 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.7d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.7d_blocked_rowmajor.js new file mode 100644 index 00000000..a84304d1 --- /dev/null +++ b/base/unary/benchmark/benchmark.7d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/7d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/7.0 ) ); + sh = [ len, len, len, len, len, len, len ]; + len *= pow( len, 6 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.7d_columnmajor.js b/base/unary/benchmark/benchmark.7d_columnmajor.js new file mode 100644 index 00000000..66f2d1a0 --- /dev/null +++ b/base/unary/benchmark/benchmark.7d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/7d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/7.0 ) ); + sh = [ len, len, len, len, len, len, len ]; + len *= pow( len, 6 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.7d_rowmajor.js b/base/unary/benchmark/benchmark.7d_rowmajor.js new file mode 100644 index 00000000..de129d25 --- /dev/null +++ b/base/unary/benchmark/benchmark.7d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/7d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/7.0 ) ); + sh = [ len, len, len, len, len, len, len ]; + len *= pow( len, 6 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.8d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.8d_blocked_columnmajor.js new file mode 100644 index 00000000..4ed808f1 --- /dev/null +++ b/base/unary/benchmark/benchmark.8d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/8d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/8.0 ) ); + sh = [ len, len, len, len, len, len, len, len ]; + len *= pow( len, 7 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.8d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.8d_blocked_rowmajor.js new file mode 100644 index 00000000..4ed808f1 --- /dev/null +++ b/base/unary/benchmark/benchmark.8d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/8d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/8.0 ) ); + sh = [ len, len, len, len, len, len, len, len ]; + len *= pow( len, 7 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.8d_columnmajor.js b/base/unary/benchmark/benchmark.8d_columnmajor.js new file mode 100644 index 00000000..76f7fd03 --- /dev/null +++ b/base/unary/benchmark/benchmark.8d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/8d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/8.0 ) ); + sh = [ len, len, len, len, len, len, len, len ]; + len *= pow( len, 7 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.8d_rowmajor.js b/base/unary/benchmark/benchmark.8d_rowmajor.js new file mode 100644 index 00000000..98c84248 --- /dev/null +++ b/base/unary/benchmark/benchmark.8d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/8d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/8.0 ) ); + sh = [ len, len, len, len, len, len, len, len ]; + len *= pow( len, 7 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.9d_blocked_columnmajor.js b/base/unary/benchmark/benchmark.9d_blocked_columnmajor.js new file mode 100644 index 00000000..9d78efb9 --- /dev/null +++ b/base/unary/benchmark/benchmark.9d_blocked_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/9d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/9.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 8 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.9d_blocked_rowmajor.js b/base/unary/benchmark/benchmark.9d_blocked_rowmajor.js new file mode 100644 index 00000000..33fef1ee --- /dev/null +++ b/base/unary/benchmark/benchmark.9d_blocked_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/9d_blocked.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/9.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 8 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+'::blocked:ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.9d_columnmajor.js b/base/unary/benchmark/benchmark.9d_columnmajor.js new file mode 100644 index 00000000..468fe367 --- /dev/null +++ b/base/unary/benchmark/benchmark.9d_columnmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/9d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'column-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/9.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 8 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/benchmark/benchmark.9d_rowmajor.js b/base/unary/benchmark/benchmark.9d_rowmajor.js new file mode 100644 index 00000000..6da5e950 --- /dev/null +++ b/base/unary/benchmark/benchmark.9d_rowmajor.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var round = require( '@stdlib/math/base/special/round' ); +var identity = require( '@stdlib/math/base/special/identity' ); +var filledarray = require( '@stdlib/array/filled' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var unary = require( './../lib/9d.js' ); + + +// VARIABLES // + +var types = [ 'float64' ]; +var order = 'row-major'; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - ndarray length +* @param {NonNegativeIntegerArray} shape - ndarray shape +* @param {string} xtype - input ndarray data type +* @param {string} ytype - output ndarray data type +* @returns {Function} benchmark function +*/ +function createBenchmark( len, shape, xtype, ytype ) { + var x; + var y; + var i; + + x = filledarray( 0.0, len, xtype ); + y = filledarray( 0.0, len, ytype ); + for ( i = 0; i < len; i++ ) { + x[ i ] = round( ( randu()*200.0 ) - 100.0 ); + } + x = { + 'dtype': xtype, + 'data': x, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + y = { + 'dtype': ytype, + 'data': y, + 'shape': shape, + 'strides': shape2strides( shape, order ), + 'offset': 0, + 'order': order + }; + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + unary( x, y, identity ); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y.data[ i%len ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var sh; + var t1; + var t2; + var f; + var i; + var j; + + min = 1; // 10^min + max = 6; // 10^max + + for ( j = 0; j < types.length; j++ ) { + t1 = types[ j ]; + t2 = types[ j ]; + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + + sh = [ len/2, 2, 1, 1, 1, 1, 1, 1, 1 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + sh = [ 1, 1, 1, 1, 1, 1, 1, 2, len/2 ]; + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + + len = floor( pow( len, 1.0/9.0 ) ); + sh = [ len, len, len, len, len, len, len, len, len ]; + len *= pow( len, 8 ); + f = createBenchmark( len, sh, t1, t2 ); + bench( pkg+':ndims='+sh.length+',len='+len+',shape=['+sh.join(',')+'],xorder='+order+',yorder='+order+',xtype='+t1+',ytype='+t2, f ); + } + } +} + +main(); diff --git a/base/unary/examples/c/b_b/Makefile b/base/unary/examples/c/b_b/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/b_b/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/b_b/example.c b/base/unary/examples/c/b_b/example.c new file mode 100644 index 00000000..783dcd60 --- /dev/null +++ b/base/unary/examples/c/b_b/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t i; + uint8_t v; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_uint8( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %hhu\n", i, v ); + } +} + +uint8_t scale( const uint8_t x ) { + return x * 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_UINT8; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 4, 2, 1 }; + int64_t sy[] = { 4, 2, 1 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_b_b( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/c_c/Makefile b/base/unary/examples/c/c_c/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/c_c/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/c_c/example.c b/base/unary/examples/c/c_c/example.c new file mode 100644 index 00000000..4c22a9f9 --- /dev/null +++ b/base/unary/examples/c/c_c/example.c @@ -0,0 +1,113 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + float complex v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_complex64( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %f + %fi\n", i, crealf( v ), cimagf( v ) ); + } +} + +float complex scale( const float complex x ) { + float re = crealf( x ); + float im = cimagf( x ); + return ( re+10.0f ) + ( im+10.0f )*I; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_COMPLEX64; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 32, 16, 8 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_c_c( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/c_z/Makefile b/base/unary/examples/c/c_z/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/c_z/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/c_z/example.c b/base/unary/examples/c/c_z/example.c new file mode 100644 index 00000000..65657322 --- /dev/null +++ b/base/unary/examples/c/c_z/example.c @@ -0,0 +1,114 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + double complex v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_complex128( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lf + %lfi\n", i, creal( v ), cimag( v ) ); + } +} + +float complex scale( const float complex x ) { + float re = crealf( x ); + float im = cimagf( x ); + return ( re+10.0f ) + ( im+10.0f )*I; +} + +int main() { + // Define the ndarray data types: + enum STDLIB_NDARRAY_DTYPE xdtype = STDLIB_NDARRAY_COMPLEX64; + enum STDLIB_NDARRAY_DTYPE ydtype = STDLIB_NDARRAY_COMPLEX128; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 64, 32, 16 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( xdtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( ydtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_c_z( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/d_d/Makefile b/base/unary/examples/c/d_d/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/d_d/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/d_d/example.c b/base/unary/examples/c/d_d/example.c new file mode 100644 index 00000000..3627387c --- /dev/null +++ b/base/unary/examples/c/d_d/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t i; + int8_t s; + double v; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_float64( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lf\n", i, v ); + } +} + +double scale( const double x ) { + return x + 10.0; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_FLOAT64; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 32, 16, 8 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_d_d( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/d_z/Makefile b/base/unary/examples/c/d_z/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/d_z/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/d_z/example.c b/base/unary/examples/c/d_z/example.c new file mode 100644 index 00000000..72a0e1f5 --- /dev/null +++ b/base/unary/examples/c/d_z/example.c @@ -0,0 +1,112 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + double complex v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_complex128( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lf + %lfi\n", i, creal( v ), cimag( v ) ); + } +} + +double scale( const double x ) { + return x + 10.0; +} + +int main() { + // Define the ndarray data types: + enum STDLIB_NDARRAY_DTYPE xdtype = STDLIB_NDARRAY_FLOAT64; + enum STDLIB_NDARRAY_DTYPE ydtype = STDLIB_NDARRAY_COMPLEX128; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 64, 32, 16 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( xdtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( ydtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_d_z( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/d_z_as_z_z/Makefile b/base/unary/examples/c/d_z_as_z_z/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/d_z_as_z_z/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/d_z_as_z_z/example.c b/base/unary/examples/c/d_z_as_z_z/example.c new file mode 100644 index 00000000..ae23c48d --- /dev/null +++ b/base/unary/examples/c/d_z_as_z_z/example.c @@ -0,0 +1,114 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + double complex v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_complex128( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lf + %lfi\n", i, creal( v ), cimag( v ) ); + } +} + +double complex scale( const double complex x ) { + double re = creal( x ); + double im = cimag( x ); + return ( re+10.0 ) + ( im+10.0 )*I; +} + +int main() { + // Define the ndarray data types: + enum STDLIB_NDARRAY_DTYPE xdtype = STDLIB_NDARRAY_FLOAT64; + enum STDLIB_NDARRAY_DTYPE ydtype = STDLIB_NDARRAY_COMPLEX128; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 64, 32, 16 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( xdtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( ydtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_d_z_as_z_z( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/f_f/Makefile b/base/unary/examples/c/f_f/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/f_f/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/f_f/example.c b/base/unary/examples/c/f_f/example.c new file mode 100644 index 00000000..5c4fed08 --- /dev/null +++ b/base/unary/examples/c/f_f/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t i; + int8_t s; + float v; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_float32( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %f\n", i, v ); + } +} + +float scale( const float x ) { + return x + 10.0f; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_FLOAT32; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 16, 8, 4 }; + int64_t sy[] = { 16, 8, 4 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_f_f( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/i_i/Makefile b/base/unary/examples/c/i_i/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/i_i/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/i_i/example.c b/base/unary/examples/c/i_i/example.c new file mode 100644 index 00000000..fcba1d75 --- /dev/null +++ b/base/unary/examples/c/i_i/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int32_t v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_int32( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %i\n", i, v ); + } +} + +int32_t scale( const int32_t x ) { + return x + 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_INT32; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 16, 8, 4 }; + int64_t sy[] = { 16, 8, 4 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_i_i( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/k_k/Makefile b/base/unary/examples/c/k_k/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/k_k/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/k_k/example.c b/base/unary/examples/c/k_k/example.c new file mode 100644 index 00000000..6ad4d8de --- /dev/null +++ b/base/unary/examples/c/k_k/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int16_t v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_int16( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %d\n", i, v ); + } +} + +int16_t scale( const int16_t x ) { + return x + 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_INT16; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 8, 4, 2 }; + int64_t sy[] = { 8, 4, 2 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_k_k( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/l_l/Makefile b/base/unary/examples/c/l_l/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/l_l/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/l_l/example.c b/base/unary/examples/c/l_l/example.c new file mode 100644 index 00000000..2ea189e2 --- /dev/null +++ b/base/unary/examples/c/l_l/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_int64( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lli\n", i, v ); + } +} + +int64_t scale( const int64_t x ) { + return x + 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_INT64; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 32, 16, 8 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_l_l( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/s_s/Makefile b/base/unary/examples/c/s_s/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/s_s/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/s_s/example.c b/base/unary/examples/c/s_s/example.c new file mode 100644 index 00000000..4b1063c4 --- /dev/null +++ b/base/unary/examples/c/s_s/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t i; + int8_t v; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_int8( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %hhi\n", i, v ); + } +} + +int8_t scale( const int8_t x ) { + return x * 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_INT8; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 4, 2, 1 }; + int64_t sy[] = { 4, 2, 1 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_s_s( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/t_t/Makefile b/base/unary/examples/c/t_t/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/t_t/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/t_t/example.c b/base/unary/examples/c/t_t/example.c new file mode 100644 index 00000000..9c20d73b --- /dev/null +++ b/base/unary/examples/c/t_t/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + uint16_t v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_uint16( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %u\n", i, v ); + } +} + +uint16_t scale( const uint16_t x ) { + return x + 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_UINT16; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 8, 4, 2 }; + int64_t sy[] = { 8, 4, 2 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_t_t( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/u_u/Makefile b/base/unary/examples/c/u_u/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/u_u/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/u_u/example.c b/base/unary/examples/c/u_u/example.c new file mode 100644 index 00000000..9b57208d --- /dev/null +++ b/base/unary/examples/c/u_u/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + uint32_t v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_uint32( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lu\n", i, v ); + } +} + +uint32_t scale( const uint32_t x ) { + return x + 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_UINT32; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 16, 8, 4 }; + int64_t sy[] = { 16, 8, 4 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_u_u( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/v_v/Makefile b/base/unary/examples/c/v_v/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/v_v/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/v_v/example.c b/base/unary/examples/c/v_v/example.c new file mode 100644 index 00000000..c490371e --- /dev/null +++ b/base/unary/examples/c/v_v/example.c @@ -0,0 +1,110 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + uint64_t v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_uint64( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %llu\n", i, v ); + } +} + +uint64_t scale( const uint64_t x ) { + return x + 10; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_UINT64; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 32, 16, 8 }; + int64_t sy[] = { 32, 16, 8 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_v_v( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/x_x/Makefile b/base/unary/examples/c/x_x/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/x_x/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/x_x/example.c b/base/unary/examples/c/x_x/example.c new file mode 100644 index 00000000..54a2e073 --- /dev/null +++ b/base/unary/examples/c/x_x/example.c @@ -0,0 +1,111 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t i; + int8_t s; + bool v; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_bool( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %d\n", i, v ); + } +} + +bool negate( const bool x ) { + return !x; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_BOOL; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 1, 0, 1, 0, 1, 0, 1 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 4, 2, 1 }; + int64_t sy[] = { 4, 2, 1 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_x_x( arrays, (void *)negate ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/c/z_z/Makefile b/base/unary/examples/c/z_z/Makefile new file mode 100644 index 00000000..f10799ab --- /dev/null +++ b/base/unary/examples/c/z_z/Makefile @@ -0,0 +1,148 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2021 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic \ + -march=native \ + -flto + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/unary/examples/c/z_z/example.c b/base/unary/examples/c/z_z/example.c new file mode 100644 index 00000000..fb24d481 --- /dev/null +++ b/base/unary/examples/c/z_z/example.c @@ -0,0 +1,113 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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/ndarray/base/unary.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/ctor.h" +#include +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + double complex v; + int64_t i; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_complex128( x, i, &v ); + if ( s != 0 ) { + fprintf( stderr, "Unable to resolve data element.\n" ); + exit( EXIT_FAILURE ); + } + fprintf( stdout, "data[%lld] = %lf + %lfi\n", i, creal( v ), cimag( v ) ); + } +} + +double complex scale( const double complex x ) { + double re = creal( x ); + double im = cimag( x ); + return ( re+10.0 ) + ( im+10.0 )*I; +} + +int main() { + // Define the ndarray data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_COMPLEX128; + + // Create underlying byte arrays: + uint8_t xbuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ybuf[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Define the number of dimensions: + int64_t ndims = 3; + + // Define the array shapes: + int64_t shape[] = { 2, 2, 2 }; + + // Define the strides: + int64_t sx[] = { 64, 32, 16 }; + int64_t sy[] = { 64, 32, 16 }; + + // Define the offsets: + int64_t ox = 0; + int64_t oy = 0; + + // Define the array order: + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + int64_t nsubmodes = 1; + + // Create an input ndarray: + struct ndarray *x = stdlib_ndarray_allocate( dtype, xbuf, ndims, shape, sx, ox, order, imode, nsubmodes, submodes ); + if ( x == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Create an output ndarray: + struct ndarray *y = stdlib_ndarray_allocate( dtype, ybuf, ndims, shape, sy, oy, order, imode, nsubmodes, submodes ); + if ( y == NULL ) { + fprintf( stderr, "Error allocating memory.\n" ); + exit( EXIT_FAILURE ); + } + + // Define an array containing the ndarrays: + struct ndarray *arrays[] = { x, y }; + + // Apply the callback: + int8_t status = stdlib_ndarray_z_z( arrays, (void *)scale ); + if ( status != 0 ) { + fprintf( stderr, "Error during computation.\n" ); + exit( EXIT_FAILURE ); + } + + // Print the results: + print_ndarray_contents( y ); + fprintf( stdout, "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x ); + stdlib_ndarray_free( y ); +} diff --git a/base/unary/examples/index.js b/base/unary/examples/index.js new file mode 100644 index 00000000..be87703f --- /dev/null +++ b/base/unary/examples/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ).factory; +var filledarray = require( '@stdlib/array/filled' ); +var gfillBy = require( '@stdlib/blas/ext/base/gfill-by' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +var unary = require( './../lib' ); + +function scale( x ) { + return x * 10; +} + +var N = 10; + +var xbuf = filledarray( 0, N, 'generic' ); +gfillBy( xbuf.length, xbuf, 1, discreteUniform( -100, 100 ) ); + +var x = { + 'dtype': 'generic', + 'data': xbuf, + 'shape': [ 5, 2 ], + 'strides': [ 2, 1 ], + 'offset': 0, + 'order': 'row-major' +}; +var y = { + 'dtype': 'generic', + 'data': filledarray( 0, N, 'generic' ), + 'shape': x.shape.slice(), + 'strides': shape2strides( x.shape, 'column-major' ), + 'offset': 0, + 'order': 'column-major' +}; + +unary( [ x, y ], scale ); +console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); +console.log( ndarray2array( y.data, y.shape, y.strides, y.offset, y.order ) ); diff --git a/base/unary/test/test.js b/base/unary/test/test.js new file mode 100644 index 00000000..e5042c7f --- /dev/null +++ b/base/unary/test/test.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var unary = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof unary, 'function', 'main export is a function' ); + t.end(); +}); diff --git a/base/vind2bind/benchmark/benchmark.js b/base/vind2bind/benchmark/benchmark.js new file mode 100644 index 00000000..3e11de9d --- /dev/null +++ b/base/vind2bind/benchmark/benchmark.js @@ -0,0 +1,424 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var pkg = require( './../package.json' ).name; +var vind2bind = require( './../lib' ); + + +// MAIN // + +bench( pkg+':mode=throw,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = vind2bind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = vind2bind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,offset=0,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = vind2bind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw,offset=0,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = vind2bind( shape, strides, offset, order, idx, 'throw' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,offset=0,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap,offset=0,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'wrap' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + strides[ 1 ] *= -1; + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,offset=0,order=row-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'row-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp,offset=0,order=column-major', function benchmark( b ) { + var strides; + var offset; + var shape; + var order; + var out; + var len; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + order = 'column-major'; + strides = shape2strides( shape, order ); + offset = strides2offset( shape, strides ); + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len*2.0 ) - len; + out = vind2bind( shape, strides, offset, order, idx, 'clamp' ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/vind2bind/benchmark/c/Makefile b/base/vind2bind/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/vind2bind/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/vind2bind/benchmark/c/benchmark.c b/base/vind2bind/benchmark/c/benchmark.c new file mode 100644 index 00000000..8be7ec52 --- /dev/null +++ b/base/vind2bind/benchmark/c/benchmark.c @@ -0,0 +1,600 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `vind2bind`. +*/ +#include +#include +#include +#include +#include +#include +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/base/vind2bind.h" + +#define NAME "vind2bind" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark3() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark4() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_ERROR ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark5() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark6() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark7() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark8() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_WRAP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark9() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, -10, 1 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark10() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, -10, 100 }; + int64_t offset = 90; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark11() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 100, 10, 1 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark12() { + double elapsed; + int64_t idx; + int64_t ind; + double t; + int i; + + int64_t ndims = 3; + int64_t shape[] = { 10, 10, 10 }; + int64_t strides[] = { 1, 10, 100 }; + int64_t offset = 0; + int64_t len = 1000; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*len*2.0)-len ); + ind = stdlib_ndarray_vind2bind( ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, idx, STDLIB_NDARRAY_INDEX_CLAMP ); + if ( ind < -1 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( ind < -1 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=row-major\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=column-major\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=row-major,offset=0\n", NAME ); + elapsed = benchmark3(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=error,order=column-major,offset=0\n", NAME ); + elapsed = benchmark4(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=row-major\n", NAME ); + elapsed = benchmark5(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=column-major\n", NAME ); + elapsed = benchmark6(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=row-major,offset=0\n", NAME ); + elapsed = benchmark7(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=wrap,order=column-major,offset=0\n", NAME ); + elapsed = benchmark8(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=row-major\n", NAME ); + elapsed = benchmark9(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=column-major\n", NAME ); + elapsed = benchmark10(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=row-major,offset=0\n", NAME ); + elapsed = benchmark11(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s:mode=clamp,order=column-major,offset=0\n", NAME ); + elapsed = benchmark12(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/base/vind2bind/examples/index.js b/base/vind2bind/examples/index.js new file mode 100644 index 00000000..32d3e3c8 --- /dev/null +++ b/base/vind2bind/examples/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var randu = require( '@stdlib/random/base/randu' ); +var vind2bind = require( './../lib' ); + +// Specify array meta data: +var shape = [ 3, 3, 3 ]; +var order = 'row-major'; + +// Compute array meta data: +var len = numel( shape ); +var strides = shape2strides( shape, order ); + +// Randomly flip the sign of strides... +var i; +for ( i = 0; i < shape.length; i++ ) { + if ( randu() < 0.5 ) { + strides[ i ] *= -1; + } +} + +// Compute the underlying data buffer index offset: +var offset = strides2offset( shape, strides ); + +// Print array info: +console.log( 'Dims: %s', shape.join( 'x' ) ); +console.log( 'Strides: %s', strides.join( ',' ) ); +console.log( 'Offset: %d', offset ); + +// For each view index, determine the corresponding index into an array's underlying data buffer... +var ind; +for ( i = 0; i < len; i++ ) { + ind = vind2bind( shape, strides, offset, order, i, 'throw' ); + console.log( 'view[%d] => buffer[%d]', i, ind ); +} diff --git a/base/vind2bind/test/test.js b/base/vind2bind/test/test.js new file mode 100644 index 00000000..abd362b3 --- /dev/null +++ b/base/vind2bind/test/test.js @@ -0,0 +1,577 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var vind2bind = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof vind2bind, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a view linear index to a linear index in an underlying data buffer (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + idx = vind2bind( shape, strides, offset, order, 0, 'throw' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 1, 'throw' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 2, 'throw' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 3, 'throw' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + t.throws( foo, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + vind2bind( shape, strides, offset, order, 999999, 'throw' ); + } +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + t.throws( foo, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + vind2bind( shape, strides, offset, order, 999999, 'throw' ); + } +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (offset=0,order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + idx = vind2bind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + idx = vind2bind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (offset=0,order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + idx = vind2bind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + idx = vind2bind( shape, strides, offset, order, 1, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -2, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 5, 'wrap' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -6, 'wrap' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -9, 'wrap' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -4, 'wrap' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (offset=0,order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + idx = vind2bind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + idx = vind2bind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (offset=0,order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + idx = vind2bind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var strides; + var offset; + var order; + var shape; + var idx; + + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + idx = vind2bind( shape, strides, offset, order, 4, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 0, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -8, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, -3, 'clamp' ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = vind2bind( shape, strides, offset, order, 15, 'clamp' ); + t.strictEqual( idx, 1, 'returns expected value' ); + + t.end(); +}); diff --git a/base/wrap-index/benchmark/benchmark.js b/base/wrap-index/benchmark/benchmark.js new file mode 100644 index 00000000..7eb18345 --- /dev/null +++ b/base/wrap-index/benchmark/benchmark.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var wrapIndex = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var idx; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*100.0 ) - 50.0; + out = wrapIndex( idx, 10 ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( out ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/wrap-index/benchmark/c/Makefile b/base/wrap-index/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/base/wrap-index/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/base/wrap-index/benchmark/c/benchmark.c b/base/wrap-index/benchmark/c/benchmark.c new file mode 100644 index 00000000..a6588988 --- /dev/null +++ b/base/wrap-index/benchmark/c/benchmark.c @@ -0,0 +1,138 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `wrap_index`. +*/ +#include +#include +#include +#include +#include +#include +#include "stdlib/ndarray/base/wrap_index.h" + +#define NAME "wrap-index" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + int64_t idx; + int64_t max; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( rand_double()*100.0 ); + max = (int64_t)( rand_double()*100.0 ); + idx = stdlib_ndarray_wrap_index( idx, max ); + if ( idx < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + if ( idx < 0 ) { + printf( "unexpected result\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/base/wrap-index/examples/index.js b/base/wrap-index/examples/index.js new file mode 100644 index 00000000..a27df530 --- /dev/null +++ b/base/wrap-index/examples/index.js @@ -0,0 +1,32 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var wrapIndex = require( './../lib' ); + +var idx; +var out; +var i; + +for ( i = 0; i < 100; i++ ) { + idx = discreteUniform( -20, 20 ); + out = wrapIndex( idx, 9 ); + console.log( '%d => [%d,%d] => %d', idx, 0, 9, out ); +} diff --git a/base/wrap-index/test/test.js b/base/wrap-index/test/test.js new file mode 100644 index 00000000..5b961701 --- /dev/null +++ b/base/wrap-index/test/test.js @@ -0,0 +1,60 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var wrapIndex = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof wrapIndex, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function wraps an index on the interval [0,max]', function test( t ) { + var expected; + var values; + var i; + + values = [ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; // eslint-disable-line max-len + expected = [ 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 ]; // eslint-disable-line max-len + + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( wrapIndex( values[ i ], 9 ), expected[ i ], 'returns expected value. idx: '+values[ i ]+'. expected: '+expected[ i ]+'.' ); + } + t.end(); +}); + +tape( 'the function wraps an index on the interval [0,max]', function test( t ) { + t.strictEqual( wrapIndex( 2, 10 ), 2, 'returns expected value' ); + t.strictEqual( wrapIndex( 12, 10 ), 1, 'returns expected value' ); + t.strictEqual( wrapIndex( -2, 10 ), 9, 'returns expected value' ); + t.strictEqual( wrapIndex( 21, 10 ), 10, 'returns expected value' ); + t.strictEqual( wrapIndex( 22, 10 ), 0, 'returns expected value' ); + t.strictEqual( wrapIndex( 26, 10 ), 4, 'returns expected value' ); + t.strictEqual( wrapIndex( -21, 10 ), 1, 'returns expected value' ); + t.strictEqual( wrapIndex( -22, 10 ), 0, 'returns expected value' ); + t.strictEqual( wrapIndex( -26, 10 ), 7, 'returns expected value' ); + t.end(); +}); diff --git a/casting-modes/benchmark/benchmark.js b/casting-modes/benchmark/benchmark.js new file mode 100644 index 00000000..8129ed5c --- /dev/null +++ b/casting-modes/benchmark/benchmark.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var pkg = require( './../package.json' ).name; +var modes = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = modes(); + if ( out.length !== 5 ) { + b.fail( 'should return an array of length 5' ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/casting-modes/examples/index.js b/casting-modes/examples/index.js new file mode 100644 index 00000000..bd80c548 --- /dev/null +++ b/casting-modes/examples/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var indexOf = require( '@stdlib/utils/index-of' ); +var modes = require( './../lib' ); + +var MODES = modes(); +var bool; + +function isMode( str ) { + if ( indexOf( MODES, str ) === -1 ) { + return false; + } + return true; +} + +bool = isMode( 'none' ); +console.log( bool ); +// => true + +bool = isMode( 'equiv' ); +console.log( bool ); +// => true + +bool = isMode( 'safe' ); +console.log( bool ); +// => true + +bool = isMode( 'same-kind' ); +console.log( bool ); +// => true + +bool = isMode( 'unsafe' ); +console.log( bool ); +// => true + +bool = isMode( 'beep' ); +console.log( bool ); +// => false diff --git a/casting-modes/test/test.js b/casting-modes/test/test.js new file mode 100644 index 00000000..977a70dd --- /dev/null +++ b/casting-modes/test/test.js @@ -0,0 +1,79 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var modes = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof modes, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a list of ndarray casting modes', function test( t ) { + var expected; + var actual; + + expected = [ + 'none', + 'equiv', + 'safe', + 'same-kind', + 'unsafe' + ]; + actual = modes(); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'attached to the main function is an `enum` method to return an object mapping casting modes to integer values for C inter-operation', function test( t ) { + var obj; + var o; + var i; + + t.strictEqual( hasOwnProp( modes, 'enum' ), true, 'has property' ); + t.strictEqual( typeof modes.enum, 'function', 'has method' ); + + obj = modes.enum(); + t.strictEqual( typeof obj, 'object', 'returns expected value type' ); + + // List of casting modes which should be supported... + o = [ + 'none', + 'equiv', + 'safe', + 'same-kind', + 'unsafe' + ]; + for ( i = 0; i < o.length; i++ ) { + t.strictEqual( hasOwnProp( obj, o[ i ] ), true, 'has property `' + o[ i ] + '`' ); + t.strictEqual( isNonNegativeInteger( obj[ o[i] ] ), true, 'returns expected value' ); + } + + t.end(); +}); diff --git a/ctor/benchmark/benchmark.js b/ctor/benchmark/benchmark.js new file mode 100644 index 00000000..dacc68d2 --- /dev/null +++ b/ctor/benchmark/benchmark.js @@ -0,0 +1,2785 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var pkg = require( './../package.json' ).name; +var ndarray = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::2d,instantiation', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,instantiation,new', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = new ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d,instantiation,new', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = new ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d,instantiation,new', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = new ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d,instantiation', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d,instantiation,new', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 0 ] = randu(); + out = new ndarray( 'generic', buffer, shape, strides, offset, order ); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + } + b.toc(); + if ( out.length === 0 ) { + b.fail( 'should have a length greater than 0' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:byteLength', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.byteLength; + if ( v !== null ) { + b.fail( 'should return null' ); + } + } + b.toc(); + if ( v !== null ) { + b.fail( 'should return null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_byteLength', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._byteLength; // eslint-disable-line no-underscore-dangle + if ( v !== null ) { + b.fail( 'should return null' ); + } + } + b.toc(); + if ( v !== null ) { + b.fail( 'should return null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:BYTES_PER_ELEMENT', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.BYTES_PER_ELEMENT; + if ( v !== null ) { + b.fail( 'should return null' ); + } + } + b.toc(); + if ( v !== null ) { + b.fail( 'should return null' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:data', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.data; + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_buffer', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._buffer; // eslint-disable-line no-underscore-dangle + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== 6 ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:dtype', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.dtype; + if ( v !== 'generic' ) { + b.fail( 'should return expected data type' ); + } + } + b.toc(); + if ( v !== 'generic' ) { + b.fail( 'should return expected data type' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:flags', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.flags; + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_flags', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._flags; // eslint-disable-line no-underscore-dangle + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:length', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.length; + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_length', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._length; // eslint-disable-line no-underscore-dangle + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v !== buffer.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:ndims', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.ndims; + if ( v !== shape.length ) { + b.fail( 'should return expected number of dimensions' ); + } + } + b.toc(); + if ( v !== shape.length ) { + b.fail( 'should return expected number of dimensions' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:offset', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.offset; + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + } + b.toc(); + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_offset', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._offset; // eslint-disable-line no-underscore-dangle + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + } + b.toc(); + if ( v !== offset ) { + b.fail( 'should return expected offset' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:order', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.order; + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + } + b.toc(); + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_order', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._order; // eslint-disable-line no-underscore-dangle + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + } + b.toc(); + if ( v !== order ) { + b.fail( 'should return expected order' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:shape', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.shape; + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_shape', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._shape; // eslint-disable-line no-underscore-dangle + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== shape.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:strides', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out.strides; + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:_strides', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = out._strides; // eslint-disable-line no-underscore-dangle + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + } + b.toc(); + if ( v.length !== strides.length ) { + b.fail( 'should return expected length' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:get', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:get:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*20.0 ) - 10.0 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:get:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*20.0 ) - 10.0 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d:get', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*3.0 ), 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d:get:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d:get:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d:get', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, floor( randu()*3.0 ), 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d:get:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d:get:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d:get', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, 0, floor( randu()*3.0 ), 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d:get:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, 0, floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d:get:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, 0, floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d:get', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, 0, 0, floor( randu()*3.0 ), 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d:get:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, 0, 0, floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d:get:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.get( 0, 0, 0, floor( randu()*30.0 ) - 15.0, 1 ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:iget', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:iget:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:iget:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var v; + var i; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_positive_strides:iget:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_positive_strides:iget:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_negative_strides:iget:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 5; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_negative_strides:iget:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 5; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,mixed_sign_strides:iget:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 4; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,mixed_sign_strides:iget:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 4; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.iget( floor( randu()*6.0 ) ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:set', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.set( j, v ); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:set:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*20.0 ) - 10.0; + tmp = out.set( j, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:set:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*20.0 ) - 10.0; + tmp = out.set( j, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d:set', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*3.0 ); + out.set( j, 1, v ); + if ( buffer[ (2*j) + (1*1) ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ (2*j) + 1 ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d:set:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d:set:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d:set', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*3.0 ); + out.set( 0, j, 1, v ); + if ( buffer[ (2*j) + (1*1) ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ (2*j) + 1 ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d:set:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( 0, j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( 0, j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::3d:set:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 3, 2 ]; + strides = [ 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( 0, j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( 0, j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d:set', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*3.0 ); + out.set( 0, 0, j, 1, v ); + if ( buffer[ (2*j) + (1*1) ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ (2*j) + 1 ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d:set:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( 0, 0, j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( 0, 0, j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::4d:set:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 3, 2 ]; + strides = [ 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( 0, 0, j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( 0, 0, j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d:set', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*3.0 ); + out.set( 0, 0, 0, j, 1, v ); + if ( buffer[ (2*j) + (1*1) ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ (2*j) + 1 ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d:set:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( 0, 0, 0, j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( 0, 0, 0, j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::5d:set:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 1, 1, 1, 3, 2 ]; + strides = [ 6, 6, 6, 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.set( 0, 0, 0, j, 1, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.get( 0, 0, 0, j, 1 ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:iset', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:iset:mode=wrap', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'wrap' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.iset( j, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.iget( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::1d:iset:mode=clamp', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var opts; + var out; + var tmp; + var v; + var i; + var j; + + opts = { + 'mode': 'clamp' + }; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 6 ]; + strides = [ 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order, opts ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*30.0 ) - 15.0; + tmp = out.iset( j, v ); + if ( typeof tmp !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( out.iget( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_positive_strides:iset:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_positive_strides:iset:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_negative_strides:iset:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 5; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ 5-j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ 5-j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,all_negative_strides:iset:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, -1 ]; + offset = 5; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ 5-j ] !== v ) { + b.fail( 'should set value' ); + } + } + b.toc(); + if ( buffer[ 5-j ] !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,mixed_sign_strides:iset:order=row-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 4; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ 0 ] !== buffer[ 0 ] ) { + b.fail( 'should not be NaN' ); + } + } + b.toc(); + if ( out.iget( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::2d,mixed_sign_strides:iset:order=column-major', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + var j; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ -2, 1 ]; + offset = 4; + order = 'column-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = randu(); + j = floor( randu()*6.0 ); + out.iset( j, v ); + if ( buffer[ 0 ] !== buffer[ 0 ] ) { + b.fail( 'should not be NaN' ); + } + } + b.toc(); + if ( out.iget( j ) !== v ) { + b.fail( 'should set value' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':toJSON', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.toJSON(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':toString', function benchmark( b ) { + var strides; + var buffer; + var offset; + var shape; + var order; + var out; + var v; + var i; + + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + shape = [ 3, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + out = ndarray( 'generic', buffer, shape, strides, offset, order ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buffer[ 1 ] = randu(); + v = out.toString(); + if ( typeof v !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( typeof v !== 'string' ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/ctor/benchmark/c/Makefile b/ctor/benchmark/c/Makefile new file mode 100644 index 00000000..c12ea191 --- /dev/null +++ b/ctor/benchmark/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} SOURCE_FILES - list of C source files +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lpthread -lblas`) +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} SOURCE_FILES - list of C source files +# @param {(string|void)} INCLUDE - list of includes (e.g., `-I /foo/bar -I /beep/boop`) +# @param {(string|void)} LIBRARIES - list of libraries (e.g., `-lpthread -lblas`) +# @param {(string|void)} LIBPATH - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled benchmarks. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/ctor/benchmark/c/benchmark.c b/ctor/benchmark/c/benchmark.c new file mode 100644 index 00000000..877a3885 --- /dev/null +++ b/ctor/benchmark/c/benchmark.c @@ -0,0 +1,3642 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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. +*/ + +/** +* Benchmark `ndarray`. +*/ +#include "stdlib/ndarray/ctor.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include +#include +#include +#include +#include +#include + +#define NAME "ndarray" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random double on the interval [0,1]. +* +* @return random double +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark1() { + double elapsed; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL || arr->ndims != 2 ) { + printf( "unexpected result\n" ); + break; + } + if ( i < ITERATIONS-1 ) { + stdlib_ndarray_free( arr ); + } + } + elapsed = tic() - t; + + if ( arr == NULL || arr->ndims != 2 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark2() { + double elapsed; + int64_t v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_bytelength( arr ); + if ( v != 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark3() { + double elapsed; + uint8_t *v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + buffer[ 0 ] = i % 255; + v = stdlib_ndarray_data( arr ); + if ( v[ 0 ] != (i%255) ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v[ 0 ] != ((i-1)%255) ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark4() { + enum STDLIB_NDARRAY_DTYPE v; + double elapsed; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_dtype( arr ); + if ( v != STDLIB_NDARRAY_UINT8 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != STDLIB_NDARRAY_UINT8 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark5() { + double elapsed; + int64_t v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + v = stdlib_ndarray_flags( arr ); + if ( v < 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v < 0 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark6() { + double elapsed; + int64_t v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_length( arr ); + if ( v != (arr->length) ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != (arr->length) ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark7() { + double elapsed; + int64_t v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_ndims( arr ); + if ( v != ndims ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != ndims ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark8() { + double elapsed; + int64_t v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_offset( arr ); + if ( v != offset ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != offset ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark9() { + enum STDLIB_NDARRAY_ORDER v; + double elapsed; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_order( arr ); + if ( v != STDLIB_NDARRAY_ROW_MAJOR ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != STDLIB_NDARRAY_ROW_MAJOR ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark10() { + double elapsed; + int64_t *v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_shape( arr ); + if ( v[ 0 ] != shape[ 0 ] || v[ 1 ] != shape[ 1 ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v[ 0 ] != shape[ 0 ] || v[ 1 ] != shape[ 1 ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark11() { + double elapsed; + int64_t *v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_strides( arr ); + if ( v[ 0 ] != strides[ 0 ] || v[ 1 ] != strides[ 1 ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v[ 0 ] != strides[ 0 ] || v[ 1 ] != strides[ 1 ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark12() { + double elapsed; + int64_t sub[1]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( rand_double()*shape[0] ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v != buffer[ sub[0] ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v != buffer[ sub[0] ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark13() { + double elapsed; + int64_t sub[1]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*20.0)-10.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark14() { + double elapsed; + int64_t sub[1]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*20.0)-10.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 ) { + printf( "unexpected result\n" ); + } else if ( sub[0] < 0 && v != buffer[ 0 ] ) { + printf( "unexpected result when negative subscript: %u != %u\n", buffer[ 0 ], v ); + } else if ( sub[0] >= shape[0] && v != buffer[ shape[0]-1 ] ) { + printf( "unexpected result when subscript exceeds dimensions: %u != %u\n", buffer[ shape[0]-1 ], v ); + } else if ( sub[0] >= 0 && sub[0] < shape[0] && v != buffer[ sub[0] ] ) { + printf( "unexpected result for normal subscript: %u != %u\n", buffer[ sub[0] ], v ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark15() { + double elapsed; + int64_t sub[2]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 1 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( rand_double()*shape[0] ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark16() { + double elapsed; + int64_t sub[2]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 1 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark17() { + double elapsed; + int64_t sub[2]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 1 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark18() { + double elapsed; + int64_t sub[3]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 3; + int64_t shape[] = { 1, 3, 2 }; + int64_t strides[] = { 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 2 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 1 ] = (int64_t)( (rand_double()*shape[1])-0.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark19() { + double elapsed; + int64_t sub[3]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 3; + int64_t shape[] = { 1, 3, 2 }; + int64_t strides[] = { 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 2 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 1 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark20() { + double elapsed; + int64_t sub[3]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 3; + int64_t shape[] = { 1, 3, 2 }; + int64_t strides[] = { 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 2 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 1 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark21() { + double elapsed; + int64_t sub[4]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 4; + int64_t shape[] = { 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 3 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*shape[2])-0.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark22() { + double elapsed; + int64_t sub[4]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 4; + int64_t shape[] = { 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 3 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark23() { + double elapsed; + int64_t sub[4]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 4; + int64_t shape[] = { 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 3 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark24() { + double elapsed; + int64_t sub[5]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 5; + int64_t shape[] = { 1, 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 2 ] = 0; + sub[ 4 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 3 ] = (int64_t)( (rand_double()*shape[3])-0.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark25() { + double elapsed; + int64_t sub[5]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 5; + int64_t shape[] = { 1, 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 2 ] = 0; + sub[ 4 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 3 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark26() { + double elapsed; + int64_t sub[5]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 5; + int64_t shape[] = { 1, 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 2 ] = 0; + sub[ 4 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 3 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_get( arr, sub, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark27() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*shape[0])-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark28() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result: idx=%lld, v=%u\n", idx, v ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark29() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*30.0)-15.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark30() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark31() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 1, 3 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark32() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark33() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -1, -3 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark34() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, 1 }; + int64_t offset = 4; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark35() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 1, -3 }; + int64_t offset = 3; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + s = stdlib_ndarray_iget( arr, idx, (void *)&v ); + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || v > 6 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark36() { + double elapsed; + int64_t sub[1]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( rand_double()*shape[0] ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 || buffer[ sub[0] ] != v ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || buffer[ sub[0] ] != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark37() { + double elapsed; + int64_t sub[1]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark38() { + double elapsed; + int64_t sub[1]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 ) { + printf( "unexpected result\n" ); + } else if ( sub[0] < 0 && buffer[ 0 ] != v ) { + printf( "unexpected result when negative subscript: %u != %u\n", buffer[ 0 ], v ); + } else if ( sub[0] >= shape[0] && buffer[ shape[0]-1 ] != v ) { + printf( "unexpected result when subscript exceeds dimensions: %u != %u\n", buffer[ shape[0]-1 ], v ); + } else if ( sub[0] >= 0 && sub[0] < shape[0] && buffer[ sub[0] ] != v ) { + printf( "unexpected result for normal subscript: %u != %u\n", buffer[ sub[0] ], v ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark39() { + double elapsed; + int64_t sub[2]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 1 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( rand_double()*shape[0] ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark40() { + double elapsed; + int64_t sub[2]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 1 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark41() { + double elapsed; + int64_t sub[2]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 1 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 0 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark42() { + double elapsed; + int64_t sub[3]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 3; + int64_t shape[] = { 1, 3, 2 }; + int64_t strides[] = { 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 2 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 1 ] = (int64_t)( rand_double()*shape[1] ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark43() { + double elapsed; + int64_t sub[3]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 3; + int64_t shape[] = { 1, 3, 2 }; + int64_t strides[] = { 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 2 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 1 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark44() { + double elapsed; + int64_t sub[3]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 3; + int64_t shape[] = { 1, 3, 2 }; + int64_t strides[] = { 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 2 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 1 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark45() { + double elapsed; + int64_t sub[4]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 4; + int64_t shape[] = { 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 3 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( rand_double()*shape[2] ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark46() { + double elapsed; + int64_t sub[4]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 4; + int64_t shape[] = { 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 3 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark47() { + double elapsed; + int64_t sub[4]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 4; + int64_t shape[] = { 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 3 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 2 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark48() { + double elapsed; + int64_t sub[5]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 5; + int64_t shape[] = { 1, 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 2 ] = 0; + sub[ 4 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 3 ] = (int64_t)( rand_double()*shape[3] ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark49() { + double elapsed; + int64_t sub[5]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 5; + int64_t shape[] = { 1, 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 2 ] = 0; + sub[ 4 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 3 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark50() { + double elapsed; + int64_t sub[5]; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 5; + int64_t shape[] = { 1, 1, 1, 3, 2 }; + int64_t strides[] = { 6, 6, 6, 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + sub[ 0 ] = 0; + sub[ 1 ] = 0; + sub[ 2 ] = 0; + sub[ 4 ] = 1; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + sub[ 3 ] = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_set( arr, sub, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_get_ptr( arr, sub )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark51() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*shape[0])-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 || buffer[ idx ] != v ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || buffer[ idx ] != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark52() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_WRAP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx)) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark53() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 1; + int64_t shape[] = { 6 }; + int64_t strides[] = { 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_CLAMP; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*30.0)-15.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 ) { + printf( "unexpected result\n" ); + } else if ( idx < 0 && buffer[ 0 ] != v ) { + printf( "unexpected result when negative linear index: %u != %u\n", buffer[ 0 ], v ); + } else if ( idx >= shape[0] && buffer[ shape[0]-1 ] != v ) { + printf( "unexpected result when linear index exceeds dimensions: %u != %u\n", buffer[ shape[0]-1 ], v ); + } else if ( idx >= 0 && idx < shape[0] && buffer[ idx ] != v ) { + printf( "unexpected result for normal linear index: %u != %u\n", buffer[ idx ], v ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark54() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark55() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 1, 3 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark56() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx)) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark57() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -1, -3 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark58() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, 1 }; + int64_t offset = 4; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark59() { + double elapsed; + int64_t idx; + uint8_t v; + double t; + int8_t s; + int i; + + uint8_t buffer[] = { 1, 2, 3, 4, 5, 6 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 1, -3 }; + int64_t offset = 3; + int64_t nsubmodes = 1; + enum STDLIB_NDARRAY_INDEX_MODE mode = STDLIB_NDARRAY_INDEX_ERROR; + int8_t submodes[] = { mode }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_COLUMN_MAJOR, mode, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + idx = (int64_t)( (rand_double()*6.0)-0.0 ); + v = (uint8_t)( rand_double()*255.0 ); + s = stdlib_ndarray_iset( arr, idx, (void *)&v ); + if ( s != 0 ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( s != 0 || *(stdlib_ndarray_iget_ptr( arr, idx )) != v ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark60() { + double elapsed; + int64_t v; + int64_t j; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + j = (int64_t)( rand_double()*ndims ); + v = stdlib_ndarray_dimension( arr, j ); + if ( v != shape[ j ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != shape[ j ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark61() { + double elapsed; + int64_t v; + int64_t j; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + j = (int64_t)( rand_double()*ndims ); + v = stdlib_ndarray_stride( arr, j ); + if ( v != strides[ j ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != strides[ j ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark62() { + enum STDLIB_NDARRAY_INDEX_MODE v; + double elapsed; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_index_mode( arr ); + if ( v != STDLIB_NDARRAY_INDEX_ERROR ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != STDLIB_NDARRAY_INDEX_ERROR ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark63() { + double elapsed; + int8_t *v; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { 2, 1 }; + int64_t offset = 0; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + // NOTE: this is likely to be optimized away by a modern compiler, making this benchmark meaningless. + v = stdlib_ndarray_submodes( arr ); + if ( v[ 0 ] != submodes[ 0 ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v[ 0 ] != submodes[ 0 ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark64() { + enum STDLIB_NDARRAY_INDEX_MODE v; + double elapsed; + int64_t j; + double t; + int i; + + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0 }; + int64_t ndims = 2; + int64_t shape[] = { 3, 2 }; + int64_t strides[] = { -2, -1 }; + int64_t offset = 5; + int64_t nsubmodes = 1; + int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; + + struct ndarray *arr = stdlib_ndarray_allocate( STDLIB_NDARRAY_UINT8, buffer, ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, nsubmodes, submodes ); + if ( arr == NULL ) { + printf( "unable to allocate memory\n" ); + exit( 1 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + j = (int64_t)( rand_double()*ndims ); + v = stdlib_ndarray_submode( arr, j ); + if ( v != submodes[ 0 ] ) { + printf( "unexpected result\n" ); + break; + } + } + elapsed = tic() - t; + + if ( v != submodes[ 0 ] ) { + printf( "unexpected result\n" ); + } + stdlib_ndarray_free( arr ); + + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int count; + int i; + + count = 0; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::instantiation\n", NAME ); + elapsed = benchmark1(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:byteLength\n", NAME ); + elapsed = benchmark2(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:data\n", NAME ); + elapsed = benchmark3(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:dtype\n", NAME ); + elapsed = benchmark4(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:flags\n", NAME ); + elapsed = benchmark5(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:length\n", NAME ); + elapsed = benchmark6(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:ndims\n", NAME ); + elapsed = benchmark7(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:offset\n", NAME ); + elapsed = benchmark8(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:order\n", NAME ); + elapsed = benchmark9(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:shape\n", NAME ); + elapsed = benchmark10(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:strides\n", NAME ); + elapsed = benchmark11(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:get:mode=error\n", NAME ); + elapsed = benchmark12(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:get:mode=wrap\n", NAME ); + elapsed = benchmark13(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:get:mode=clamp\n", NAME ); + elapsed = benchmark14(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d:get:mode=error\n", NAME ); + elapsed = benchmark15(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d:get:mode=wrap\n", NAME ); + elapsed = benchmark16(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d:get:mode=clamp\n", NAME ); + elapsed = benchmark17(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::3d:get:mode=error\n", NAME ); + elapsed = benchmark18(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::3d:get:mode=wrap\n", NAME ); + elapsed = benchmark19(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::3d:get:mode=clamp\n", NAME ); + elapsed = benchmark20(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::4d:get:mode=error\n", NAME ); + elapsed = benchmark21(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::4d:get:mode=wrap\n", NAME ); + elapsed = benchmark22(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::4d:get:mode=clamp\n", NAME ); + elapsed = benchmark23(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::5d:get:mode=error\n", NAME ); + elapsed = benchmark24(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::5d:get:mode=wrap\n", NAME ); + elapsed = benchmark25(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::5d:get:mode=clamp\n", NAME ); + elapsed = benchmark26(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:iget:mode=error\n", NAME ); + elapsed = benchmark27(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:iget:mode=wrap\n", NAME ); + elapsed = benchmark28(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:iget:mode=clamp\n", NAME ); + elapsed = benchmark29(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_positive_strides:iget:mode=error,order=row-major\n", NAME ); + elapsed = benchmark30(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_positive_strides:iget:mode=error,order=column-major\n", NAME ); + elapsed = benchmark31(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_negative_strides:iget:mode=error,order=row-major\n", NAME ); + elapsed = benchmark32(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_negative_strides:iget:mode=error,order=column-major\n", NAME ); + elapsed = benchmark33(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,mixed_sign_strides:iget:mode=error,order=row-major\n", NAME ); + elapsed = benchmark34(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,mixed_sign_strides:iget:mode=error,order=column-major\n", NAME ); + elapsed = benchmark35(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:set:mode=error\n", NAME ); + elapsed = benchmark36(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:set:mode=wrap\n", NAME ); + elapsed = benchmark37(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:set:mode=clamp\n", NAME ); + elapsed = benchmark38(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d:set:mode=error\n", NAME ); + elapsed = benchmark39(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d:set:mode=wrap\n", NAME ); + elapsed = benchmark40(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d:set:mode=clamp\n", NAME ); + elapsed = benchmark41(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::3d:set:mode=error\n", NAME ); + elapsed = benchmark42(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::3d:set:mode=wrap\n", NAME ); + elapsed = benchmark43(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::3d:set:mode=clamp\n", NAME ); + elapsed = benchmark44(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::4d:set:mode=error\n", NAME ); + elapsed = benchmark45(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::4d:set:mode=wrap\n", NAME ); + elapsed = benchmark46(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::4d:set:mode=clamp\n", NAME ); + elapsed = benchmark47(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::5d:set:mode=error\n", NAME ); + elapsed = benchmark48(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::5d:set:mode=wrap\n", NAME ); + elapsed = benchmark49(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::5d:set:mode=clamp\n", NAME ); + elapsed = benchmark50(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:iset:mode=error\n", NAME ); + elapsed = benchmark51(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:iset:mode=wrap\n", NAME ); + elapsed = benchmark52(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::1d:iset:mode=clamp\n", NAME ); + elapsed = benchmark53(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_positive_strides:iset:mode=error,order=row-major\n", NAME ); + elapsed = benchmark54(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_positive_strides:iset:mode=error,order=column-major\n", NAME ); + elapsed = benchmark55(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_negative_strides:iset:mode=error,order=row-major\n", NAME ); + elapsed = benchmark56(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,all_negative_strides:iset:mode=error,order=column-major\n", NAME ); + elapsed = benchmark57(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,mixed_sign_strides:iset:mode=error,order=row-major\n", NAME ); + elapsed = benchmark58(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::2d,mixed_sign_strides:iset:mode=error,order=column-major\n", NAME ); + elapsed = benchmark59(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:dimension\n", NAME ); + elapsed = benchmark60(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:stride\n", NAME ); + elapsed = benchmark61(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:index_mode\n", NAME ); + elapsed = benchmark62(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:submodes\n", NAME ); + elapsed = benchmark63(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + for ( i = 0; i < REPEATS; i++ ) { + count += 1; + printf( "# c::native::%s::get:submode\n", NAME ); + elapsed = benchmark64(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + print_summary( count, count ); +} diff --git a/ctor/benchmark/julia/REQUIRE b/ctor/benchmark/julia/REQUIRE new file mode 100644 index 00000000..98645e19 --- /dev/null +++ b/ctor/benchmark/julia/REQUIRE @@ -0,0 +1,2 @@ +julia 1.5 +BenchmarkTools 0.5.0 diff --git a/ctor/benchmark/julia/benchmark.jl b/ctor/benchmark/julia/benchmark.jl new file mode 100644 index 00000000..4ae2dc70 --- /dev/null +++ b/ctor/benchmark/julia/benchmark.jl @@ -0,0 +1,342 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +import BenchmarkTools +using Printf + +# Benchmark variables: +repeats = 3; +samples = 1e4; +count = 0; + +""" + print_version() + +Prints the TAP version. + +# Examples + +``` julia +julia> print_version() +``` +""" +function print_version() + @printf( "TAP version 13\n" ); +end + +""" + print_summary( total, passing ) + +Print the benchmark summary. + +# Arguments + +* `total`: total number of tests +* `passing`: number of passing tests + +# Examples + +``` julia +julia> print_summary( 3, 3 ) +``` +""" +function print_summary( total, passing ) + @printf( "#\n" ); + @printf( "1..%d\n", total ); # TAP plan + @printf( "# total %d\n", total ); + @printf( "# pass %d\n", passing ); + @printf( "#\n" ); + @printf( "# ok\n" ); +end + +""" + print_results( iterations, elapsed ) + +Print benchmark results. + +# Arguments + +* `iterations`: number of iterations +* `elapsed`: elapsed time (in seconds) + +# Examples + +``` julia +julia> print_results( 1000000, 0.131009101868 ) +``` +""" +function print_results( iterations, elapsed ) + rate = iterations / elapsed + + @printf( " ---\n" ); + @printf( " iterations: %d\n", iterations ); + @printf( " elapsed: %0.9f\n", elapsed ); + @printf( " rate: %0.9f\n", rate ); + @printf( " ...\n" ); +end + +""" + benchmark( setup, expr ) + +Run a benchmark. + +# Notes + +* Benchmark results are returned as a two-element array: [ iterations, elapsed ]. +* The number of iterations is not the true number of iterations. Instead, an 'iteration' is defined as a 'sample', which is a computed estimate for a single evaluation. +* The elapsed time is in seconds. + +# Arguments + +* `setup`: setup expression +* `expr`: expression to benchmark + +# Examples + +``` julia +julia> out = benchmark( :(), :( sin( 3.14 ) ) ); +``` +""" +function benchmark( setup, expr ) + t = eval( :( BenchmarkTools.@benchmark $expr samples=$samples setup=($setup) ) ) + + # Compute the total "elapsed" time and convert from nanoseconds to seconds: + s = sum( t.times ) / 1.0e9; + + # Determine the number of "iterations": + iter = length( t.times ); + + # Return the results: + [ iter, s ]; +end + +""" + bench( name, setup, expr ) + +Run a named benchmark. + +# Arguments + +* `name`: benchmark name (suffix) +* `setup`: setup expression +* `expr`: expression to benchmark + +# Examples + +``` julia +julia> bench( "sin", :(), :( sin( 3.14 ) ) ); +``` +""" +function bench( name, setup, expr ) + for i in 1:repeats + @printf( "# julia::%s\n", name ); + global count += 1; + results = benchmark( setup, expr ); + print_results( results[ 1 ], results[ 2 ] ); + @printf( "ok %d benchmark finished\n", count ); + end +end + +""" + main() + +Run benchmarks. + +# Examples + +``` julia +julia> main(); +``` +""" +function main() + print_version(); + + name = "ndarray::instantiation"; + setup = :(); + stmt = :( A = Array{Float64}( undef, 3, 2 ) ); + bench( name, setup, stmt ); + + name = "ndarray::get::dtype"; + setup = :( A = Array{Float64}( undef, 3, 2 ) ); + stmt = quote + d = eltype( A ); + if d != Float64 + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::get::length"; + setup = :( A = Array{Float64}( undef, 3, 2 ) ); + stmt = quote + N = length( A ); + if N != 6 + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::get::ndims"; + setup = :( A = Array{Float64}( undef, 3, 2 ) ); + stmt = quote + M = ndims( A ); + if M != 2 + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::get::shape"; + setup = :( A = Array{Float64}( undef, 3, 2 ) ); + stmt = quote + shape = size( A ); + if shape[ 1 ] != 3 + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::get::strides"; + setup = :( A = Array{Float64}( undef, 3, 2 ) ); + stmt = quote + s = strides( A ); + if s[ 1 ] != 1 + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::1d:get"; + setup = :( A = rand( Float64, 6 ) ); + stmt = quote + j = Int( floor( rand()*6.0 ) ) + 1; + v = A[ j ]; + if v != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::2d:get"; + setup = :( A = rand( Float64, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = A[ j, 2 ]; + if v != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::3d:get"; + setup = :( A = rand( Float64, 1, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = A[ 1, j, 2 ]; + if v != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::4d:get"; + setup = :( A = rand( Float64, 1, 1, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = A[ 1, 1, j, 2 ]; + if v != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::5d:get"; + setup = :( A = rand( Float64, 1, 1, 1, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = A[ 1, 1, 1, j, 2 ]; + if v != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::1d:set"; + setup = :( A = rand( Float64, 6 ) ); + stmt = quote + j = Int( floor( rand()*6.0 ) ) + 1; + v = rand(); + A[ j ] = v; + if A[ j ] != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::2d:set"; + setup = :( A = rand( Float64, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = rand(); + A[ j, 2 ] = v; + if A[ j, 2 ] != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::3d:set"; + setup = :( A = rand( Float64, 1, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = rand(); + A[ 1, j, 2 ] = v; + if A[ 1, j, 2 ] != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::4d:set"; + setup = :( A = rand( Float64, 1, 1, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = rand(); + A[ 1, 1, j, 2 ] = v; + if A[ 1, 1, j, 2 ] != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + name = "ndarray::5d:set"; + setup = :( A = rand( Float64, 1, 1, 1, 3, 2 ) ); + stmt = quote + j = Int( floor( rand()*3.0 ) ) + 1; + v = rand(); + A[ 1, 1, 1, j, 2 ] = v; + if A[ 1, 1, 1, j, 2 ] != v + throw( error( "unexpected value" ) ); + end + end + bench( name, setup, stmt ); + + print_summary( count, count ); +end + +main(); diff --git a/ctor/benchmark/python/numpy/benchmark.py b/ctor/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..39b1520b --- /dev/null +++ b/ctor/benchmark/python/numpy/benchmark.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.ndarray.""" + +from __future__ import print_function +import timeit + +REPEATS = 3 +COUNT = [0] # use a list to allow modification within nested scopes + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(iterations, elapsed): + """Print benchmark results. + + # Arguments + + * `iterations`: number of iterations + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(100000, 0.131009101868) + ``` + """ + rate = iterations / elapsed + + print(" ---") + print(" iterations: " + str(iterations)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(name, setup, stmt, iterations): + """Run a benchmark and print benchmark results. + + # Arguments + + * `name`: benchmark name (suffix) + * `setup`: benchmark setup + * `stmt`: statement to benchmark + * `iterations`: number of iterations + + # Examples + + ``` python + python> benchmark("::random", "from random import random;", "y = random()", 1000000) + ``` + """ + t = timeit.Timer(stmt, setup=setup) + + i = 0 + while i < REPEATS: + print("# python::numpy" + name) + COUNT[0] += 1 + elapsed = t.timeit(number=iterations) + print_results(iterations, elapsed) + print("ok " + str(COUNT[0]) + " benchmark finished") + i += 1 + + +def main(): + """Run the benchmarks.""" + # pylint: disable=too-many-statements + print_version() + + name = "::instantiation" + setup = "import numpy as np; x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], dtype='float64'); shape = [3, 2]; strides = [2, 1]; offset = 0; order = 'C';" + stmt = "y = np.ndarray(buffer=x, shape=shape, strides=strides, offset=offset, order=order)" + iterations = 100000 + benchmark(name, setup, stmt, iterations) + + name = "::get:data" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.data" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:dtype" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.dtype" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:flags" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.flags" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:length" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.size" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:BYTES_PER_ELEMENT" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.itemsize" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:byteLength" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.nbytes" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:ndims" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.ndim" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:shape" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.shape" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::get:strides" + setup = "import numpy as np; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape);" + stmt = "z = y.strides" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::1d:get" + setup = "import numpy as np; from math import floor; from random import random; shape = [6]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y[int(floor(random()*6.0))]" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::2d:get" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y[int(floor(random()*3.0)), 1]" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::3d:get" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y[0, int(floor(random()*3.0)), 1]" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::4d:get" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y[0, 0, int(floor(random()*3.0)), 1]" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::5d:get" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y[0, 0, 0, int(floor(random()*3.0)), 1]" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::1d:set" + setup = "import numpy as np; from math import floor; from random import random; shape = [6]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y[int(floor(random()*6.0))] = random()" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::2d:set" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y[int(floor(random()*3.0)), 1] = random()" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::3d:set" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y[0, int(floor(random()*3.0)), 1] = random()" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::4d:set" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y[0, 0, int(floor(random()*3.0)), 1] = random()" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::5d:set" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y[0, 0, 0, int(floor(random()*3.0)), 1] = random()" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::1d:iget" + setup = "import numpy as np; from math import floor; from random import random; shape = [6]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y.item(int(floor(random()*6.0)))" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::2d:iget" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y.item(int(floor(random()*6.0)))" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::3d:iget" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y.item(int(floor(random()*6.0)))" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::4d:iget" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y.item(int(floor(random()*6.0)))" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::5d:iget" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "z = y.item(int(floor(random()*6.0)))" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::1d:iset" + setup = "import numpy as np; from math import floor; from random import random; shape = [6]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y.itemset(int(floor(random()*6.0)), random())" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::2d:iset" + setup = "import numpy as np; from math import floor; from random import random; shape = [3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y.itemset(int(floor(random()*6.0)), random())" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::3d:iset" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y.itemset(int(floor(random()*6.0)), random())" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::4d:iset" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y.itemset(int(floor(random()*6.0)), random())" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + name = "::5d:iset" + setup = "import numpy as np; from math import floor; from random import random; shape = [1, 1, 1, 3, 2]; y = np.ndarray(buffer=np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), shape=shape, dtype='float64');" + stmt = "y.itemset(int(floor(random()*6.0)), random())" + iterations = 1000000 + benchmark(name, setup, stmt, iterations) + + print_summary(COUNT[0], COUNT[0]) + + +if __name__ == "__main__": + main() diff --git a/ctor/docs/repl.txt b/ctor/docs/repl.txt index ca32b827..ea2b039d 100644 --- a/ctor/docs/repl.txt +++ b/ctor/docs/repl.txt @@ -239,7 +239,7 @@ 0 -{{alias}}.prototype.order: string +{{alias}}.prototype.order Array order. The array order is either row-major (C-style) or column-major (Fortran- diff --git a/ctor/docs/types/index.d.ts b/ctor/docs/types/index.d.ts new file mode 100644 index 00000000..28afd312 --- /dev/null +++ b/ctor/docs/types/index.d.ts @@ -0,0 +1,152 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +// TypeScript Version: 2.0 + +/// + +import { ArrayLike } from '@stdlib/types/array'; +import { ndarray, DataType, Mode, Order } from '@stdlib/types/ndarray'; +import { Buffer } from 'buffer'; + +/** +* Interface defining function options. +*/ +interface Options { + /** + * Specifies how to handle a linear index which exceeds array dimensions (default: 'throw'). + */ + mode?: Mode; + + /** + * Specifies how to handle subscripts which exceed array dimensions on a per dimension basis (default: ['throw']). + */ + submode?: Array; +} + +/** +* Interface defining a ndarray constructor which is both "newable" and "callable". +*/ +interface Constructor { + /** + * ndarray constructor. + * + * @param dtype - data type + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @param options - function options + * @param options.mode - specifies how to handle indices which exceed array dimensions (default: 'throw') + * @param options.submode - specifies how to handle subscripts which exceed array dimensions on a per dimension basis (default: ['throw']) + * @throws `buffer` argument `get` and `set` properties must be functions + * @throws `shape` argument must be an array-like object containing nonnegative integers + * @throws `shape` argument length must equal the number of dimensions + * @throws `strides` argument must be an array-like object containing integers + * @throws `strides` argument length must equal the number of dimensions (except for zero-dimensional arrays; in which case, the `strides` argument length must be equal to `1`) + * @throws for zero-dimensional ndarrays, the `strides` argument must contain a single element equal to `0` + * @throws `offset` argument must be a nonnegative integer + * @throws `buffer` argument must be compatible with specified meta data + * @throws must provide valid options + * @throws too many dimensions + * @returns ndarray instance + * + * @example + * var buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + * var shape = [ 3, 2 ]; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = new ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + */ + new( dtype: DataType, buffer: ArrayLike | Buffer, shape: ArrayLike, strides: ArrayLike, offset: number, order: Order, options?: Options ): ndarray; // tslint-disable-line max-line-length + + /** + * ndarray constructor. + * + * @param dtype - data type + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @param options - function options + * @param options.mode - specifies how to handle indices which exceed array dimensions (default: 'throw') + * @param options.submode - specifies how to handle subscripts which exceed array dimensions on a per dimension basis (default: ['throw']) + * @throws `buffer` argument `get` and `set` properties must be functions + * @throws `shape` argument must be an array-like object containing nonnegative integers + * @throws `shape` argument length must equal the number of dimensions + * @throws `strides` argument must be an array-like object containing integers + * @throws `strides` argument length must equal the number of dimensions (except for zero-dimensional arrays; in which case, the `strides` argument length must be equal to `1`) + * @throws for zero-dimensional ndarrays, the `strides` argument must contain a single element equal to `0` + * @throws `offset` argument must be a nonnegative integer + * @throws `buffer` argument must be compatible with specified meta data + * @throws must provide valid options + * @throws too many dimensions + * @returns ndarray instance + * + * @example + * var buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + * var shape = [ 3, 2 ]; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + */ + ( dtype: DataType, buffer: ArrayLike | Buffer, shape: ArrayLike, strides: ArrayLike, offset: number, order: Order, options?: Options ): ndarray; // tslint-disable-line max-line-length +} + +/** +* ndarray constructor. +* +* @param dtype - data type +* @param buffer - data buffer +* @param shape - array shape +* @param strides - array strides +* @param offset - index offset +* @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) +* @param options - function options +* @param options.mode - specifies how to handle indices which exceed array dimensions (default: 'throw') +* @param options.submode - specifies how to handle subscripts which exceed array dimensions on a per dimension basis (default: ['throw']) +* @throws `buffer` argument `get` and `set` properties must be functions +* @throws `shape` argument must be an array-like object containing nonnegative integers +* @throws `shape` argument length must equal the number of dimensions +* @throws `strides` argument must be an array-like object containing integers +* @throws `strides` argument length must equal the number of dimensions (except for zero-dimensional arrays; in which case, the `strides` argument length must be equal to `1`) +* @throws for zero-dimensional ndarrays, the `strides` argument must contain a single element equal to `0` +* @throws `offset` argument must be a nonnegative integer +* @throws `buffer` argument must be compatible with specified meta data +* @throws must provide valid options +* @throws too many dimensions +* @returns ndarray instance +* +* @example +* var buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; +* var shape = [ 3, 2 ]; +* var strides = [ 2, 1 ]; +* var offset = 0; +* +* var out = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); +*/ +declare var ctor: Constructor; + + +// EXPORTS // + +export = ctor; diff --git a/ctor/docs/types/test.ts b/ctor/docs/types/test.ts new file mode 100644 index 00000000..e2c9791f --- /dev/null +++ b/ctor/docs/types/test.ts @@ -0,0 +1,184 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +import ndarray = require( './index' ); + + +// TESTS // + +// The function returns an ndarray... +{ + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + + ndarray( 'float64', [ 1, 2, 3, 4 ], shape, strides, 0, 'row-major' ); // $ExpectType ndarray + new ndarray( 'float64', [ 1, 2, 3, 4 ], shape, strides, 0, 'row-major' ); // $ExpectType ndarray + + const buffer = new Int32Array( [ 1, 2, 3 ] ); + const order = 'column-major'; + + ndarray( 'int32', buffer, shape, strides, 0, order ); // $ExpectType ndarray + new ndarray( 'int32', buffer, shape, strides, 0, order ); // $ExpectType ndarray + + ndarray( 'int32', buffer, shape, strides, 0, order, { 'mode': 'clamp' } ); // $ExpectType ndarray + new ndarray( 'int32', buffer, shape, strides, 0, order, { 'mode': 'clamp' } ); // $ExpectType ndarray + + ndarray( 'int32', buffer, shape, strides, 0, order, { 'submode': [ 'throw' ] } ); // $ExpectType ndarray + new ndarray( 'int32', buffer, shape, strides, 0, order, { 'submode': [ 'throw' ] } ); // $ExpectType ndarray +} + +// The function does not compile if provided a first argument which is not a recognized data type... +{ + const buffer = [ 1, 2, 3, 4 ]; + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const offset = 0; + const order = 'row-major'; + + ndarray( 'abc', buffer, shape, strides, offset, order ); // $ExpectError + ndarray( 123, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( true, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( false, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( null, buffer, shape, strides, offset, order ); // $ExpectError + ndarray( undefined, buffer, shape, strides, offset, order ); // $ExpectError +} + +// The function does not compile if provided a second argument which is not an array-like object or buffer... +{ + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const offset = 0; + const order = 'row-major'; + ndarray( 'float64', 123, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', true, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', false, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', null, shape, strides, offset, order ); // $ExpectError + ndarray( 'float64', undefined, shape, strides, offset, order ); // $ExpectError +} + +// The function does not compile if provided a third argument which is not an array-like object containing numbers... +{ + const buffer = [ 1, 2, 3, 4 ]; + const strides = [ 2, 1 ]; + const offset = 0; + const order = 'row-major'; + ndarray( 'float64', buffer, true, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, false, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, null, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, undefined, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, '5', strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, [ '1', '2' ], strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, {}, strides, offset, order ); // $ExpectError + ndarray( 'float64', buffer, ( x: number ): number => x, strides, offset, order ); // $ExpectError +} + +// The function does not compile if provided a fourth argument which is not an array-like object containing numbers... +{ + const buffer = [ 1, 2, 3, 4 ]; + const shape = [ 2, 2 ]; + const offset = 0; + const order = 'row-major'; + ndarray( 'float32', buffer, shape, true, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, false, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, null, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, undefined, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, '5', offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, [ '1', '2' ], offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, {}, offset, order ); // $ExpectError + ndarray( 'float32', buffer, shape, ( x: number ): number => x, offset, order ); // $ExpectError +} + +// The function does not compile if provided a fifth argument which is not a number... +{ + const buffer = [ 1, 2, 3, 4 ]; + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const order = 'row-major'; + ndarray( 'int32', buffer, shape, strides, true, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, false, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, null, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, undefined, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, '5', order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, [ '1', '2' ], order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, {}, order ); // $ExpectError + ndarray( 'int32', buffer, shape, strides, ( x: number ): number => x, order ); // $ExpectError +} + +// The function does not compile if provided a sixth argument which is not a known array order... +{ + const buffer = [ 1, 2, 3, 4 ]; + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const offset = 0; + ndarray( 'int8', buffer, shape, strides, offset, true ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, false ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, null ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, undefined ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, '5' ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, [ '1', '2' ] ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, {} ); // $ExpectError + ndarray( 'int8', buffer, shape, strides, offset, ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided a `mode` option which is not a recognized mode... +{ + const buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const offset = 0; + const order = 'row-major'; + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': 'abc' } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': 123 } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': true } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': false } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': null } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': [] } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': {} } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'mode': ( x: number ): number => x } ); // $ExpectError +} + +// The compiler throws an error if the function is provided an `submode` option which is not an ndarray of strings... +{ + const buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const offset = 0; + const order = 'row-major'; + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': 'abc' } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': 123 } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': true } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': false } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': null } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': {} } ); // $ExpectError + ndarray( 'float64', buffer, shape, strides, offset, order, { 'submode': ( x: number ): number => x } ); // $ExpectError +} + +// The function does not compile if provided and invalid number of arguments... +{ + const buffer = [ 1, 2, 3, 4 ]; + const shape = [ 2, 2 ]; + const strides = [ 2, 1 ]; + const offset = 0; + ndarray(); // $ExpectError + ndarray( 'uint32' ); // $ExpectError + ndarray( 'int8', buffer ); // $ExpectError + ndarray( 'uint8c', buffer, shape ); // $ExpectError + ndarray( 'uint8', buffer, shape, strides ); // $ExpectError + ndarray( 'uint16', buffer, shape, strides, offset ); // $ExpectError + ndarray( 'uint16', buffer, shape, strides, offset, 'row-major', {}, {} ); // $ExpectError +} diff --git a/ctor/examples/c/Makefile b/ctor/examples/c/Makefile new file mode 100644 index 00000000..95c16647 --- /dev/null +++ b/ctor/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2018 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. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := example.out + + +# RULES # + +#/ +# Compiles source files. +# +# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`) +# @param {string} [CFLAGS] - C compiler options +# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`) +# @param {string} [SOURCE_FILES] - list of source files +# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`) +# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`) +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler (e.g., `gcc`) +# @param {string} CFLAGS - C compiler options +# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`) +# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`) +# @param {string} SOURCE_FILES - list of source files +# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`) +# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`) +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) + +#/ +# Runs compiled examples. +# +# @example +# make run +#/ +run: $(c_targets) + $(QUIET) ./$< + +.PHONY: run + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: + $(QUIET) -rm -f *.o *.out + +.PHONY: clean diff --git a/ctor/examples/c/example.c b/ctor/examples/c/example.c new file mode 100644 index 00000000..3a29312b --- /dev/null +++ b/ctor/examples/c/example.c @@ -0,0 +1,205 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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/ndarray/ctor.h" +#include "stdlib/ndarray/dtypes.h" +#include "stdlib/ndarray/index_modes.h" +#include "stdlib/ndarray/orders.h" +#include "stdlib/ndarray/base/bytes_per_element.h" +#include "stdlib/ndarray/base/dtype_char.h" +#include +#include +#include + +void print_ndarray_contents( const struct ndarray *x ) { + int64_t i; + double v; + int8_t s; + + for ( i = 0; i < stdlib_ndarray_length( x ); i++ ) { + s = stdlib_ndarray_iget_float64( x, i, &v ); // WARNING: assumes `x->dtype` is float64 + if ( s != 0 ) { + printf( "Unable to resolve data element.\n" ); + exit( 1 ); + } + printf( "data[%lld] = %f\n", i, v ); + } +} + +int main() { + // Manually create an ndarray (WARNING: this is for illustration purposes only, as the fields of an ndarray are subject to change; for ABI compatibility, use utility functions for accessing ndarray data)... + struct ndarray *x1 = malloc( sizeof( struct ndarray ) ); + if ( x1 == NULL ) { + printf( "Error allocating memory.\n" ); + exit( 1 ); + } + + // Specify the underlying data type: + enum STDLIB_NDARRAY_DTYPE dtype = STDLIB_NDARRAY_FLOAT64; + x1->dtype = dtype; + + // Create an underlying byte array: + uint8_t buffer[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + x1->data = buffer; + + // Explicitly specify the number of bytes per element: + x1->BYTES_PER_ELEMENT = STDLIB_NDARRAY_FLOAT64_BYTES_PER_ELEMENT; + + // Specify the array shape: + int64_t shape[] = { 3 }; // vector consisting of 3 doubles + x1->shape = shape; + + // Specify the array strides: + int64_t strides[] = { x1->BYTES_PER_ELEMENT }; + x1->strides = strides; + + // Specify the byte offset: + x1->offset = 0; + + // Specify the array order (note: this does not matter for a 1-dimensional array): + enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR; + x1->order = order; + + // Specify the index mode: + enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR; + x1->imode = imode; + + // Specify the subscript index modes: + int8_t submodes[] = { imode }; + x1->submodes = submodes; + x1->nsubmodes = 1; + + // Explicitly specify the number of array dimensions: + x1->ndims = 1; // vector + + // Explicitly specify the number of array elements (doubles): + x1->length = x1->shape[ 0 ]; + + // Explicitly specify the number of bytes: + x1->byteLength = (x1->length) * (x1->BYTES_PER_ELEMENT); + + // Explicitly set the array flags: + x1->flags = stdlib_ndarray_flags( x1 ); + + printf( "dtype = %d\n", stdlib_ndarray_dtype( x1 ) ); + printf( "length = %lld\n", stdlib_ndarray_length( x1 ) ); + printf( "byteLength = %lld\n", stdlib_ndarray_bytelength( x1 ) ); + printf( "ltr = %u\n", stdlib_ndarray_dtype_char( stdlib_ndarray_dtype( x1 ) ) ); + printf( "\n" ); + + // Use the function interface to create an ndarray (NOTE: for future ABI compatibility, using the following function interface should be preferred)... + struct ndarray *x2 = stdlib_ndarray_allocate( dtype, buffer, 1, shape, strides, 0, order, imode, 1, submodes ); + if ( x2 == NULL ) { + printf( "Error allocating memory.\n" ); + exit( 1 ); + } + + printf( "dtype = %d\n", stdlib_ndarray_dtype( x2 ) ); + printf( "length = %lld\n", stdlib_ndarray_length( x2 ) ); + printf( "byteLength = %lld\n", stdlib_ndarray_bytelength( x2 ) ); + printf( "ltr = %u\n", stdlib_ndarray_dtype_char( stdlib_ndarray_dtype( x2 ) ) ); + printf( "\n" ); + + // Set values in the underlying byte array using pointers: + int64_t sub[] = { 0 }; + uint8_t *ptr = stdlib_ndarray_get_ptr( x2, sub ); + if ( ptr == NULL ) { + printf( "Unable to resolve data pointer.\n" ); + exit( 1 ); + } + *(double *)ptr = 1.0; + + sub[ 0 ] = 1; + ptr = stdlib_ndarray_get_ptr( x2, sub ); + if ( ptr == NULL ) { + printf( "Unable to resolve data pointer.\n" ); + exit( 1 ); + } + *(double *)ptr = 2.0; + + sub[ 0 ] = 2; + ptr = stdlib_ndarray_get_ptr( x2, sub ); + if ( ptr == NULL ) { + printf( "Unable to resolve data pointer.\n" ); + exit( 1 ); + } + *(double *)ptr = 3.0; + + // Print out the current ndarray elements: + print_ndarray_contents( x2 ); + printf( "\n" ); + + // Set values in the underlying byte array using a "generic" function: + sub[ 0 ] = 0; + double v = 4.0; + int8_t status = stdlib_ndarray_set( x2, sub, (void *)&v ); + if ( status != 0 ) { + printf( "Unable to set data element.\n" ); + exit( 1 ); + } + + sub[ 0 ] = 1; + v = 5.0; + status = stdlib_ndarray_set( x2, sub, (void *)&v ); + if ( status != 0 ) { + printf( "Unable to set data element.\n" ); + exit( 1 ); + } + + sub[ 0 ] = 2; + v = 6.0; + status = stdlib_ndarray_set( x2, sub, (void *)&v ); + if ( status != 0 ) { + printf( "Unable to set data element.\n" ); + exit( 1 ); + } + + // Print out the current ndarray elements: + print_ndarray_contents( x2 ); + printf( "\n" ); + + // Set values in the underlying byte array using a specialized function: + sub[ 0 ] = 0; + status = stdlib_ndarray_set_float64( x2, sub, 7.0 ); + if ( status != 0 ) { + printf( "Unable to set data element.\n" ); + exit( 1 ); + } + + sub[ 0 ] = 1; + status = stdlib_ndarray_set_float64( x2, sub, 8.0 ); + if ( status != 0 ) { + printf( "Unable to set data element.\n" ); + exit( 1 ); + } + + sub[ 0 ] = 2; + status = stdlib_ndarray_set_float64( x2, sub, 9.0 ); + if ( status != 0 ) { + printf( "Unable to set data element.\n" ); + exit( 1 ); + } + + // Print out the current ndarray elements: + print_ndarray_contents( x2 ); + printf( "\n" ); + + // Free allocated memory: + stdlib_ndarray_free( x1 ); + stdlib_ndarray_free( x2 ); +} diff --git a/ctor/examples/index.js b/ctor/examples/index.js new file mode 100644 index 00000000..31c64331 --- /dev/null +++ b/ctor/examples/index.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var Float32Array = require( '@stdlib/array/float32' ); +var ndarray = require( './../lib' ); + +// Create a data buffer: +var buffer = new Float32Array( (3*3*3*3) + 100 ); + +// Specify the array shape: +var shape = [ 3, 3, 3, 3 ]; + +// Specify the array strides: +var strides = [ 27, 9, 3, 1 ]; + +// Specify the index offset: +var offset = 4; + +// Specify the order: +var order = 'row-major'; // C-style + +// Create a new ndarray: +var arr = ndarray( 'float32', buffer, shape, strides, offset, order ); + +// Retrieve an array value: +var v = arr.get( 1, 2, 1, 2 ); +console.log( v ); +// => 0.0 + +// Set an array value: +arr.set( 1, 2, 1, 2, 10.0 ); + +// Retrieve the array value: +v = arr.get( 1, 2, 1, 2 ); +console.log( v ); +// => 10.0 + +// Serialize the array as a string: +console.log( arr.toString() ); +// => "ndarray( 'float32', new Float32Array( [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ), [ 3, 3, 3, 3 ], [ 27, 9, 3, 1 ], 0, 'row-major' )" + +// Serialize the array as JSON: +console.log( JSON.stringify( arr.toJSON() ) ); +// => '{"type":"ndarray","dtype":"float32","flags":{},"order":"row-major","shape":[3,3,3,3],"strides":[27,9,3,1],"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}' diff --git a/ctor/package.json b/ctor/package.json index a12d922f..9f4a1940 100644 --- a/ctor/package.json +++ b/ctor/package.json @@ -23,6 +23,7 @@ "src": "./src", "test": "./test" }, + "types": "./docs/types", "scripts": {}, "homepage": "https://github.com/stdlib-js/stdlib", "repository": { diff --git a/ctor/test/test.argument_validation.js b/ctor/test/test.argument_validation.js new file mode 100644 index 00000000..d1f483ac --- /dev/null +++ b/ctor/test/test.argument_validation.js @@ -0,0 +1,998 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the constructor throws an error if not provided a valid `dtype` argument', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var order; + var shape; + var i; + + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( value, buffer, shape, strides, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `dtype` argument (options)', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var order; + var shape; + var i; + + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( value, buffer, shape, strides, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `buffer` argument', function test( t ) { + var strides; + var values; + var offset; + var dtype; + var order; + var shape; + var i; + + dtype = 'generic'; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + { + 'length': 10, + 'get': function noop() {}, + 'set': true + }, + { + 'length': 10, + 'get': true, + 'set': function noop() {} + }, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, value, shape, strides, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `buffer` argument (options)', function test( t ) { + var strides; + var values; + var offset; + var dtype; + var order; + var shape; + var i; + + dtype = 'generic'; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + { + 'length': 10, + 'get': function noop() {}, + 'set': true + }, + { + 'length': 10, + 'get': true, + 'set': function noop() {} + }, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, value, shape, strides, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `shape` argument', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var order; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [ 1, 3.14 ], + [ -1, -2 ], + [ 1, '1' ], + [ 1, null ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, value, strides, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `shape` argument (options)', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var order; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [ 1, 3.14 ], + [ -1, -2 ], + [ 1, '1' ], + [ 1, null ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, value, strides, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if the number of ndarray dimensions may cause stack limits to be exceeded', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var order; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 0.0, 1.0, 2.0, 3.0 ] ); + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + 1e5, + 1e6 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var shape = new Float64Array( value ); + ndarray( dtype, buffer, shape, strides, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if the number of ndarray dimensions may cause stack limits to be exceeded (options)', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var order; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 0.0, 1.0, 2.0, 3.0 ] ); + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + 1e5, + 1e6 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var shape = new Float64Array( value ); + ndarray( dtype, buffer, shape, strides, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = [ 2, 2 ]; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 3.14 ], + [ -1, -3.14 ], + [ 1, '1' ], + [ 1, null ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (0d)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = []; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + [ 1.1 ], + [ 1, 3.14 ], + [ -1, -3.14 ], + [ 1, '1' ], + [ 1, null ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (0d)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = []; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + [ 1 ], + [ 2 ], + [ 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (options)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = [ 2, 2 ]; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 3.14 ], + [ -1, -3.14 ], + [ 1, '1' ], + [ 1, null ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (options; 0d)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = []; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + [ 1.1 ], + [ 1, 3.14 ], + [ -1, -3.14 ], + [ 1, '1' ], + [ 1, null ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (number of dimensions)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = [ 2, 2 ]; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + [ 1 ], + [ 4, 2, 1 ], + [ 4, 4, 2, 1 ], + [ 4, 4, 4, 2, 1 ], + [ 4, 4, 4, 4, 2, 1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (number of dimensions; 0d)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = []; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + [], + [ 2, 1 ], + [ 4, 2, 1 ], + [ 4, 4, 2, 1 ], + [ 4, 4, 4, 2, 1 ], + [ 4, 4, 4, 4, 2, 1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (number of dimensions; options)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = [ 2, 2 ]; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + [ 1 ], + [ 4, 2, 1 ], + [ 4, 4, 2, 1 ], + [ 4, 4, 4, 2, 1 ], + [ 4, 4, 4, 4, 2, 1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `strides` argument (number of dimensions; options; 0d)', function test( t ) { + var values; + var offset; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + shape = []; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + order = 'row-major'; + offset = 0; + + values = [ + [], + [ 2, 1 ], + [ 4, 2, 1 ], + [ 4, 4, 2, 1 ], + [ 4, 4, 4, 2, 1 ], + [ 4, 4, 4, 4, 2, 1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, value, offset, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `offset` argument', function test( t ) { + var strides; + var values; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + + values = [ + '5', + -5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, strides, value, order ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `offset` argument (options)', function test( t ) { + var strides; + var values; + var buffer; + var shape; + var dtype; + var order; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + + values = [ + '5', + -5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, strides, value, order, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `order` argument', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var shape; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + 'c', + 'f', + 'c-style', + 'fortran', + 'fortran-style', + 'row', + 'column', + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, strides, offset, value ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid `order` argument (options)', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var shape; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + 'c', + 'f', + 'c-style', + 'fortran', + 'fortran-style', + 'row', + 'column', + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, strides, offset, value, {} ); + }; + } +}); + +tape( 'the constructor throws an error if not provided a valid options argument', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var shape; + var order; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray( dtype, buffer, shape, strides, offset, order, value ); + }; + } +}); + +tape( 'the constructor throws an error if provided an invalid option', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var dtype; + var shape; + var order; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + strides = [ 2, 1 ]; + offset = 0; + order = 'row-major'; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var opts = { + 'mode': value + }; + ndarray( dtype, buffer, shape, strides, offset, order, opts ); + }; + } +}); + +tape( 'the constructor throws an error if not provided compatible input arguments', function test( t ) { + var strides; + var values; + var offset; + var buffer; + var order; + var dtype; + var shape; + var i; + + dtype = 'generic'; + buffer = [ 0.0, 1.0, 2.0, 3.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + values = [ + [ dtype, [ 0.0 ], shape, strides, offset, order ], + [ dtype, buffer, [ 3, 2 ], strides, offset, order ], + [ dtype, buffer, shape, [ 2, 2 ], offset, order ], + [ dtype, buffer, shape, strides, 2, order ], + [ dtype, buffer, shape, strides, 20, order ], + [ dtype, buffer, shape, [ 2, -1 ], offset, order ], + [ dtype, buffer, shape, [ -2, 1 ], offset, order ], + [ dtype, buffer, shape, [ -2, 1 ], 1, order ], + [ dtype, buffer, shape, [ -2, -1 ], offset, order ], + [ dtype, buffer, shape, [ -2, -1 ], 1, order ], + [ dtype, buffer, shape, [ -2, -1 ], 2, order ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + JSON.stringify( values[ i ] ) ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ndarray.apply( null, value ); + }; + } +}); diff --git a/ctor/test/test.copy_array.js b/ctor/test/test.copy_array.js new file mode 100644 index 00000000..5efc6fc2 --- /dev/null +++ b/ctor/test/test.copy_array.js @@ -0,0 +1,66 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var copy = require( './../lib/copy_array.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof copy, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function copies the elements of an array-like input value and returns an output array', function test( t ) { + var arr; + var out; + + arr = [ 1.0, 2.0, 3.0 ]; + out = copy( arr, arr.length ); + + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.notEqual( out, arr, 'returns a new instance' ); + t.deepEqual( arr, out, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function copies the elements of an array-like input value and returns an output array (>64K elements)', function test( t ) { + var arr; + var out; + var i; + + arr = []; + for ( i = 0; i < 1e6; i++ ) { + arr.push( i ); + } + out = copy( arr, arr.length ); + + t.strictEqual( isArray( out ), true, 'returns an array' ); + t.notEqual( out, arr, 'returns a new instance' ); + t.deepEqual( arr, out, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.get.js b/ctor/test/test.instance.get.js new file mode 100644 index 00000000..63086a5c --- /dev/null +++ b/ctor/test/test.instance.get.js @@ -0,0 +1,85 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'get' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( arr.get ), true, 'has method' ); + t.end(); +}); diff --git a/ctor/test/test.instance.get_0d.js b/ctor/test/test.instance.get_0d.js new file mode 100644 index 00000000..4507670c --- /dev/null +++ b/ctor/test/test.instance.get_0d.js @@ -0,0 +1,131 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var real = require( '@stdlib/complex/real' ); +var imag = require( '@stdlib/complex/imag' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method which throws an error if provided any arguments (0d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 0, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get(), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element (0d; complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + v = arr.get(); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.get_1d.js b/ctor/test/test.instance.get_1d.js new file mode 100644 index 00000000..a78e74c5 --- /dev/null +++ b/ctor/test/test.instance.get_1d.js @@ -0,0 +1,983 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var real = require( '@stdlib/complex/real' ); +var imag = require( '@stdlib/complex/imag' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method which throws an error if not provided an integer value (1d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + v = arr.get( 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.get( 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.get( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( 3 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var v; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + v = arr.get( 0 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.get( 1 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.get( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( 3 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=wrap; complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + var v; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + v = arr.get( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( 4 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.get( 5 ); + t.strictEqual( real( v ), 3.0, 'returns expected value' ); + t.strictEqual( imag( v ), 4.0, 'returns expected value' ); + v = arr.get( -2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( -1 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=clamp; complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + var v; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + v = arr.get( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + v = arr.get( 4 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + v = arr.get( 5 ); + t.strictEqual( real( v ), 7.0, 'returns expected value' ); + t.strictEqual( imag( v ), 8.0, 'returns expected value' ); + v = arr.get( -2 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + v = arr.get( -1 ); + t.strictEqual( real( v ), 1.0, 'returns expected value' ); + t.strictEqual( imag( v ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=throw; complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var v; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + v = arr.get( 2 ); + t.strictEqual( real( v ), 5.0, 'returns expected value' ); + t.strictEqual( imag( v ), 6.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'clamp', + 'submode': [ 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'wrap', + 'submode': [ 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; submode=[wrap,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; row-major; submode=[clamp,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (1d; column-major; submode=[clamp,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.get_2d.js b/ctor/test/test.instance.get_2d.js new file mode 100644 index 00000000..4d1f4856 --- /dev/null +++ b/ctor/test/test.instance.get_2d.js @@ -0,0 +1,872 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method which throws an error if not provided an integer value (2d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ], 0 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 1 ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value, dim ) { + if ( dim === 0 ) { + return i; + } + return j; + + function i() { + arr.get( value, 0 ); + } + + function j() { + arr.get( 0, value ); + } + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 2, 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2, 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 4 ], + [ -2, -3 ], + [ 9, 10 ], + [ 3, 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + + values = [ + [ 2, 4 ], + [ -2, -3 ], + [ 9, 10 ], + [ 3, 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 4 ], + [ -2, -3 ], + [ 9, 10 ], + [ 3, 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + + values = [ + [ 2, 4 ], + [ -2, -3 ], + [ 9, 10 ], + [ 3, 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; submode=[clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 2, 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2, 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'wrap', + 'submode': [ 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 4 ], + [ -2, -3 ], + [ 9, 10 ], + [ 3, 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; submode=[throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'clamp', + 'submode': [ 'throw', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + + values = [ + [ 2, 4 ], + [ -2, -3 ], + [ 9, 10 ], + [ 3, 3 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; row-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 2, 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (2d; column-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, -3 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 9, 10 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 3, 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.get_3d.js b/ctor/test/test.instance.get_3d.js new file mode 100644 index 00000000..45d31930 --- /dev/null +++ b/ctor/test/test.instance.get_3d.js @@ -0,0 +1,696 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method which throws an error if not provided an integer value (3d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ], 0 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 1 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 2 ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value, dim ) { + if ( dim === 0 ) { + return i; + } + if ( dim === 1 ) { + return j; + } + return k; + + function i() { + arr.get( value, 0, 0 ); + } + + function j() { + arr.get( 0, value, 0 ); + } + + function k() { + arr.get( 0, 0, value ); + } + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 6, 100 ], + [ 0, -2, -4 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 6, 100 ], + [ 0, -2, -4 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 6, 100 ], + [ 0, -2, -4 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 6, 100 ], + [ 0, -2, -4 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; submode=[clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'clamp', + 'submode': [ 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'row-major'; + strides = [ 3, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 6, 100 ], + [ 0, -2, -4 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; submode=[throw,throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'wrap', + 'submode': [ 'throw', 'throw', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = [ 1, 3, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 3 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + values = [ + [ 2, 6, 100 ], + [ 0, -2, -4 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; row-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (3d; column-major; submode=[wrap,wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 2, 6, 100 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -2, -4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 2, 0 ), 1.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.get_4d.js b/ctor/test/test.instance.get_4d.js new file mode 100644 index 00000000..62918fb8 --- /dev/null +++ b/ctor/test/test.instance.get_4d.js @@ -0,0 +1,716 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method which throws an error if not provided an integer value (4d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ], 0 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 1 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 2 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 3 ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value, dim ) { + if ( dim === 0 ) { + return i; + } + if ( dim === 1 ) { + return j; + } + if ( dim === 2 ) { + return k; + } + return l; + + function i() { + arr.get( value, 0, 0, 0 ); + } + + function j() { + arr.get( 0, value, 0, 0 ); + } + + function k() { + arr.get( 0, 0, value, 0 ); + } + + function l() { + arr.get( 0, 0, 0, value ); + } + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 10, 2, 2, 0 ], + [ -2, 6, -1, 9 ], + [ -5, -3, 4, -5 ], + [ 5, 5, 5, 5 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 10, 2, 2, 0 ], + [ -2, 6, -1, 9 ], + [ -5, -3, 4, -5 ], + [ 5, 5, 5, 5 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 10, 2, 2, 0 ], + [ -2, 6, -1, 9 ], + [ -5, -3, 4, -5 ], + [ 5, 5, 5, 5 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 10, 2, 2, 0 ], + [ -2, 6, -1, 9 ], + [ -5, -3, 4, -5 ], + [ 5, 5, 5, 5 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; submode=[clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; submode=[clamp,clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; submode=[throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'wrap', + 'submode': [ 'throw', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 10, 2, 2, 0 ], + [ -2, 6, -1, 9 ], + [ -5, -3, 4, -5 ], + [ 5, 5, 5, 5 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'clamp', + 'submode': [ 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 10, 2, 2, 0 ], + [ -2, 6, -1, 9 ], + [ -5, -3, 4, -5 ], + [ 5, 5, 5, 5 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; row-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (4d; column-major; submode=[wrap,wrap,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 10, 2, 2, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( -2, 6, -1, 9 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( -5, -3, 4, -5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 5, 5, 5, 5 ), 4.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.get_nd.js b/ctor/test/test.instance.get_nd.js new file mode 100644 index 00000000..72a638af --- /dev/null +++ b/ctor/test/test.instance.get_nd.js @@ -0,0 +1,703 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method which throws an error if not provided an integer value (>4d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + var j; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + for ( j = 0; j < shape.length; j++ ) { + t.throws( badValue( values[ i ], j ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + } + t.end(); + + function badValue( value, dim ) { + return function badValue() { + var args = new Array( shape.length ); + var i; + + for ( i = 0; i < args.length; i++ ) { + if ( i === dim ) { + args[ i ] = value; + } else { + args[ i ] = 0; + } + } + arr.get.apply( arr, args ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1, 0, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 0, 10, 10, 0, 0 ], + [ 0, 0, 5, 0, 0 ], + [ 0, 5, 6, 0, 0 ], + [ 0, -1, -1, 0, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 0, 10, 10, 0, 0 ], + [ 0, 0, 5, 0, 0 ], + [ 0, 5, 6, 0, 0 ], + [ 0, -1, -1, 0, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 0, 10, 10, 0, 0 ], + [ 0, 0, 5, 0, 0 ], + [ 0, 5, 6, 0, 0 ], + [ 0, -1, -1, 0, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 0, 10, 10, 0, 0 ], + [ 0, 0, 5, 0, 0 ], + [ 0, 5, 6, 0, 0 ], + [ 0, -1, -1, 0, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; submode=[clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; submode=[clamp,clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; submode=[throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'clamp', + 'submode': [ 'throw', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 0, 10, 10, 0, 0 ], + [ 0, 0, 5, 0, 0 ], + [ 0, 5, 6, 0, 0 ], + [ 0, -1, -1, 0, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; submode=[throw,throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'wrap', + 'submode': [ 'throw', 'throw', 'throw' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 0, 10, 10, 0, 0 ], + [ 0, 0, 5, 0, 0 ], + [ 0, 5, 6, 0, 0 ], + [ 0, -1, -1, 0, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.get.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; row-major; submode=[wrap,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'row-major'; + strides = [ 4, 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `get` method for retrieving an array element using subscripts (>4d; column-major; submode=[wrap,wrap,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap', 'clamp', 'clamp' ] + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2, 1, 1 ]; + order = 'column-major'; + strides = [ 1, 1, 2, 4, 4 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.get( 0, 10, 10, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 5, 0, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 5, 6, 0, 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, -1, -1, 0, 0 ), 2.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.iget.js b/ctor/test/test.instance.iget.js new file mode 100644 index 00000000..1bfbcfb5 --- /dev/null +++ b/ctor/test/test.instance.iget.js @@ -0,0 +1,87 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iget' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iget' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iget ), true, 'has method' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.iget_0d.js b/ctor/test/test.instance.iget_0d.js new file mode 100644 index 00000000..16fc8e27 --- /dev/null +++ b/ctor/test/test.instance.iget_0d.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget(), 2.0, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.iget_1d.js b/ctor/test/test.instance.iget_1d.js new file mode 100644 index 00000000..9a06b0d5 --- /dev/null +++ b/ctor/test/test.instance.iget_1d.js @@ -0,0 +1,755 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method which throws an error if not provided an integer value (1d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 6 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (1d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 5 ], + [ 6 ], + [ -1 ], + [ -2 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iget_2d.js b/ctor/test/test.instance.iget_2d.js new file mode 100644 index 00000000..8ac848f0 --- /dev/null +++ b/ctor/test/test.instance.iget_2d.js @@ -0,0 +1,1431 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method which throws an error if not provided an integer value (2d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iget_3d.js b/ctor/test/test.instance.iget_3d.js new file mode 100644 index 00000000..df29e6b9 --- /dev/null +++ b/ctor/test/test.instance.iget_3d.js @@ -0,0 +1,1431 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method which throws an error if not provided an integer value (3d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iget_4d.js b/ctor/test/test.instance.iget_4d.js new file mode 100644 index 00000000..d1546a4f --- /dev/null +++ b/ctor/test/test.instance.iget_4d.js @@ -0,0 +1,1431 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method which throws an error if not provided an integer value (4d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iget_nd.js b/ctor/test/test.instance.iget_nd.js new file mode 100644 index 00000000..ded89ce8 --- /dev/null +++ b/ctor/test/test.instance.iget_nd.js @@ -0,0 +1,1431 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method which throws an error if not provided an integer value (>4d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget( value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 1.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 2.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 3.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + t.strictEqual( arr.iget( 4 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 5 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( -2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( -1 ), 4.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iget` method for retrieving an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4 ], + [ 5 ], + [ -2 ], + [ -1 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iget.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iset.js b/ctor/test/test.instance.iset.js new file mode 100644 index 00000000..5dc3cd86 --- /dev/null +++ b/ctor/test/test.instance.iset.js @@ -0,0 +1,87 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'iset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'iset' ), true, 'has property' ); + t.strictEqual( isFunction( arr.iset ), true, 'has method' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.iset_0d.js b/ctor/test/test.instance.iset_0d.js new file mode 100644 index 00000000..d32a6c37 --- /dev/null +++ b/ctor/test/test.instance.iset_0d.js @@ -0,0 +1,60 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 5.0 ); + + t.strictEqual( arr.iget(), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 5.0, 3.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.iset_1d.js b/ctor/test/test.instance.iset_1d.js new file mode 100644 index 00000000..c58159c6 --- /dev/null +++ b/ctor/test/test.instance.iset_1d.js @@ -0,0 +1,895 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method which throws an error if not provided an integer value for the first argument (1d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset( value, 0.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 7.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 7.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 7.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 7.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -1, 7.0 ); + arr.iset( -2, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (1d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iset_2d.js b/ctor/test/test.instance.iset_2d.js new file mode 100644 index 00000000..c2b26fed --- /dev/null +++ b/ctor/test/test.instance.iset_2d.js @@ -0,0 +1,1711 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method which throws an error if not provided an integer value for the first argument (2d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset( value, 0.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7, 8, 5, 6 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iset_3d.js b/ctor/test/test.instance.iset_3d.js new file mode 100644 index 00000000..b9a21826 --- /dev/null +++ b/ctor/test/test.instance.iset_3d.js @@ -0,0 +1,1711 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method which throws an error if not provided an integer value for the first argument (3d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset( value, 0.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7, 8, 5, 6 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iset_4d.js b/ctor/test/test.instance.iset_4d.js new file mode 100644 index 00000000..f22fa0e3 --- /dev/null +++ b/ctor/test/test.instance.iset_4d.js @@ -0,0 +1,1711 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method which throws an error if not provided an integer value for the first argument (4d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset( value, 0.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7, 8, 5, 6 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.iset_nd.js b/ctor/test/test.instance.iset_nd.js new file mode 100644 index 00000000..b7f17d03 --- /dev/null +++ b/ctor/test/test.instance.iset_nd.js @@ -0,0 +1,1711 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method which throws an error if not provided an integer value for the first argument (>4d)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset( value, 0.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.iset( 0, 5.0 ); + arr.iset( 1, 6.0 ); + arr.iset( 2, 7.0 ); + arr.iset( 3, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7, 8, 5, 6 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.iset( 4, 5.0 ); + arr.iset( 5, 6.0 ); + arr.iset( -2, 7.0 ); + arr.iset( -1, 8.0 ); + + t.strictEqual( arr.iget( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 2.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 3.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 2.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has an `iset` method for setting an array element using a linear index (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -2, 7.0 ], + [ -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.iget( 0 ), 4.0, 'returns expected value' ); + t.strictEqual( arr.iget( 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.iget( 2 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.iget( 3 ), 1.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.iset.apply( arr, value ); + }; + } +}); diff --git a/ctor/test/test.instance.properties.js b/ctor/test/test.instance.properties.js new file mode 100644 index 00000000..e71ca0df --- /dev/null +++ b/ctor/test/test.instance.properties.js @@ -0,0 +1,1128 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive; +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var isPlainObject = require( '@stdlib/assert/is-plain-object' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `byteLength` property specifying the size (in bytes) of the array (typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `byteLength` property specifying the size (in bytes) of the array (typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `byteLength` property specifying the size (in bytes) of the array (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `byteLength` property specifying the size (in bytes) of the array (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.byteLength ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.byteLength, 8*buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `byteLength` property specifying the size (in bytes) of an array (generic)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( arr.byteLength, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `byteLength` property specifying the size (in bytes) of an array (generic; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'byteLength' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'byteLength' ), true, 'has property' ); + t.strictEqual( arr.byteLength, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.BYTES_PER_ELEMENT ), true, 'is a positive integer' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 8, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (generic)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `BYTES_PER_ELEMENT` property specifying the size (in bytes) of each array element (generic; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'BYTES_PER_ELEMENT' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( arr.BYTES_PER_ELEMENT, null, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `data` property pointing to the underlying data buffer', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `data` property pointing to the underlying data buffer (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `data` property pointing to the underlying data buffer (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `data` property pointing to the underlying data buffer (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'data' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'data' ), true, 'has property' ); + t.strictEqual( arr.data, buffer, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `dtype` property specifying the underlying data type', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `dtype` property specifying the underlying data type (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `dtype` property specifying the underlying data type (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `dtype` property specifying the underlying data type (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'dtype' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'dtype' ), true, 'has property' ); + t.strictEqual( arr.dtype, dtype, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `flags` property providing information regarding the memory layout of the array (row-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `flags` property providing information regarding the memory layout of the array (column-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `flags` property providing information regarding the memory layout of the array (row-major and column-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `flags` property providing information regarding the memory layout of the array (row-major and column-major contiguous; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, true, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `flags` property providing information regarding the memory layout the array (neither row-major nor column-major contiguous)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + shape = [ 2, 2, 2 ]; + order = 'column-major'; + strides = [ 4, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'flags' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'flags' ), true, 'has property' ); + t.strictEqual( isPlainObject( arr.flags ), true, 'is an object' ); + + t.strictEqual( hasOwnProp( arr.flags, 'ROW_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.ROW_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.strictEqual( hasOwnProp( arr.flags, 'COLUMN_MAJOR_CONTIGUOUS' ), true, 'has own property' ); + t.strictEqual( arr.flags.COLUMN_MAJOR_CONTIGUOUS, false, 'has expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `length` property specifying the number of array elements', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `length` property specifying the number of array elements (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `length` property specifying the number of array elements (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `length` property specifying the number of array elements (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'length' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'length' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.length ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.length, buffer.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `ndims` property specifying the number of array dimensions', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'ndims' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'ndims' ), true, 'has property' ); + t.strictEqual( isPositiveInteger( arr.ndims ), true, 'is a positive integer' ); + t.strictEqual( arr.ndims, shape.length, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `ndims` property specifying the number of array dimensions (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'ndims' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'ndims' ), true, 'has property' ); + t.strictEqual( arr.ndims, 0, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `offset` property specifying the location of the first indexed element', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `offset` property specifying the location of the first indexed element (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `offset` property specifying the location of the first indexed element (complex typed)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ] ); // eslint-disable-line max-len + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `offset` property specifying the location of the first indexed element (complex typed; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'offset' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'offset' ), true, 'has property' ); + t.strictEqual( isNonNegativeInteger( arr.offset ), true, 'is a nonnegative integer' ); + t.strictEqual( arr.offset, offset, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `order` property specifying the array order (row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `order` property specifying the array order (row-major; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `order` property specifying the array order (column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has an `order` property specifying the array order (column-major; 0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'order' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'order' ), true, 'has property' ); + t.strictEqual( arr.order, order, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `shape` property specifying the array shape (dimensions)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'shape' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'shape' ), true, 'has property' ); + t.notEqual( arr.shape, shape, 'returns a copy' ); + t.deepEqual( arr.shape, shape, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `shape` property specifying the array shape (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'shape' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'shape' ), true, 'has property' ); + t.notEqual( arr.shape, shape, 'returns a copy' ); + t.deepEqual( arr.shape, shape, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `strides` property specifying how to access array elements along corresponding dimensions', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'strides' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'strides' ), true, 'has property' ); + t.notEqual( arr.strides, strides, 'returns a copy' ); + t.deepEqual( arr.strides, strides, 'has expected value' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `strides` property specifying how to access array elements along corresponding dimensions (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'strides' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'strides' ), true, 'has property' ); + t.notEqual( arr.strides, strides, 'returns a copy' ); + t.deepEqual( arr.strides, strides, 'has expected value' ); + t.end(); +}); diff --git a/ctor/test/test.instance.set.js b/ctor/test/test.instance.set.js new file mode 100644 index 00000000..ffe25d3d --- /dev/null +++ b/ctor/test/test.instance.set.js @@ -0,0 +1,85 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'set' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( arr.set ), true, 'has method' ); + t.end(); +}); diff --git a/ctor/test/test.instance.set_0d.js b/ctor/test/test.instance.set_0d.js new file mode 100644 index 00000000..8e23dcd1 --- /dev/null +++ b/ctor/test/test.instance.set_0d.js @@ -0,0 +1,106 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method which throws an error if provided index arguments (0d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 0, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set( value, 10.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 5.0 ); + + t.strictEqual( arr.get(), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 5.0, 4.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.set_1d.js b/ctor/test/test.instance.set_1d.js new file mode 100644 index 00000000..5e14e409 --- /dev/null +++ b/ctor/test/test.instance.set_1d.js @@ -0,0 +1,816 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method which throws an error if not provided an integer value for a dimension index (1d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set( value, 10.0 ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 5.0 ); + arr.set( 1, 6.0 ); + arr.set( 2, 7.0 ); + arr.set( 3, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 5.0 ); + arr.set( 1, 6.0 ); + arr.set( 2, 7.0 ); + arr.set( 3, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( 6, 7.0 ); + arr.set( 7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( 6, 7.0 ); + arr.set( 7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( -1, 7.0 ); + arr.set( -2, 8.0 ); + + t.strictEqual( arr.get( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( -1, 7.0 ); + arr.set( -7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( 6, 7.0 ); + arr.set( 7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( 6, 7.0 ); + arr.set( 7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( -1, 7.0 ); + arr.set( -2, 8.0 ); + + t.strictEqual( arr.get( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( -1, 7.0 ); + arr.set( -7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'wrap', + 'submode': [ 'throw' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; submode=[throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'clamp', + 'submode': [ 'throw', 'throw' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 4, 5.0 ], + [ 5, 6.0 ], + [ -1, 7.0 ], + [ -2, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided ' + values[ i ] ); + } + t.strictEqual( arr.get( 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; row-major; submode=[wrap,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'throw' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( 6, 7.0 ); + arr.set( 7, 8.0 ); + + t.strictEqual( arr.get( 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (1d; column-major; submode=[clamp,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'throw' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 4 ]; + order = 'column-major'; + strides = [ 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 4, 5.0 ); + arr.set( 5, 6.0 ); + arr.set( -1, 7.0 ); + arr.set( -2, 8.0 ); + + t.strictEqual( arr.get( 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 2 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 3 ), 6.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 2.0, 3.0, 6.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.set_2d.js b/ctor/test/test.instance.set_2d.js new file mode 100644 index 00000000..050a3e05 --- /dev/null +++ b/ctor/test/test.instance.set_2d.js @@ -0,0 +1,1024 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method which throws an error if not provided an integer value for a dimension index (2d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ], 0 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 1 ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value, dim ) { + if ( dim === 0 ) { + return i; + } + return j; + + function i() { + arr.set( value, 0, 10.0 ); + } + + function j() { + arr.set( 0, value, 10.0 ); + } + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, -1 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 5.0, 8.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ -2, -1 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 7.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, 2 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 5.0, 8.0, 6.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, -2 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 6.0, 8.0, 5.0, 7.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 5.0 ); + arr.set( 0, 1, 6.0 ); + arr.set( 1, 0, 7.0 ); + arr.set( 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 8.0, 6.0, 7.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 1, 0, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 6.0, 5.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 1, 0, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 5.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 1, 10, 5.0 ], + [ -2, 3, 6.0 ], + [ -1, -2, 7.0 ], + [ 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 1, 10, 5.0 ], + [ -2, 3, 6.0 ], + [ -1, -2, 7.0 ], + [ 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 1, 10, 5.0 ], + [ -2, 3, 6.0 ], + [ -1, -2, 7.0 ], + [ 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 1, 10, 5.0 ], + [ -2, 3, 6.0 ], + [ -1, -2, 7.0 ], + [ 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; submode=[clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 1, 0, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 6.0, 5.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 1, 0, 5.0 ); + arr.set( -2, 3, 6.0 ); + arr.set( -1, -2, 7.0 ); + arr.set( 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 5.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; submode=[throw,throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw', 'throw', 'throw' ], + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 1, 10, 5.0 ], + [ -2, 3, 6.0 ], + [ -1, -2, 7.0 ], + [ 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw' ], + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 1, 10, 5.0 ], + [ -2, 3, 6.0 ], + [ -1, -2, 7.0 ], + [ 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; row-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 5.0 ); // (0,1) + arr.set( -2, 3, 6.0 ); // (0,1) + arr.set( -1, -2, 7.0 ); // (1,0) + arr.set( 5, 5, 8.0 ); // (1,1) + + t.strictEqual( arr.get( 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (2d; column-major; submode=[clamp,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 5.0 ); // (1,0) + arr.set( -2, 3, 6.0 ); // (0,1) + arr.set( -1, -2, 7.0 ); // (0,0) + arr.set( 5, 5, 8.0 ); // (1,1) + + t.strictEqual( arr.get( 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 5.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.set_3d.js b/ctor/test/test.instance.set_3d.js new file mode 100644 index 00000000..20442dea --- /dev/null +++ b/ctor/test/test.instance.set_3d.js @@ -0,0 +1,834 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method which throws an error if not provided an integer value for a dimension index (3d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ], 0 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 1 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 2 ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value, dim ) { + if ( dim === 0 ) { + return i; + } + if ( dim === 1 ) { + return j; + } + return k; + + function i() { + arr.set( value, 0, 0, 10.0 ); + } + + function j() { + arr.set( 0, value, 0, 10.0 ); + } + + function k() { + arr.set( 0, 0, value, 10.0 ); + } + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 0, 5.0 ); + arr.set( 0, 0, 1, 6.0 ); + arr.set( 0, 1, 0, 7.0 ); + arr.set( 0, 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 0, 5.0 ); + arr.set( 0, 0, 1, 6.0 ); + arr.set( 0, 1, 0, 7.0 ); + arr.set( 0, 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 5.0 ], + [ -4, -2, 11, 6.0 ], + [ 0, 5, 0, 7.0 ], + [ 0, 15, -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 5.0 ], + [ -4, -2, 11, 6.0 ], + [ 0, 5, 0, 7.0 ], + [ 0, 15, -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 2, 2, 2, 5.0 ], + [ -4, -2, 11, 6.0 ], + [ 0, 5, 0, 7.0 ], + [ 0, 15, -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 2, 2, 2, 5.0 ], + [ -4, -2, 11, 6.0 ], + [ 0, 5, 0, 7.0 ], + [ 0, 15, -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; submode=[clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; submode=[clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); + arr.set( -4, -2, 11, 6.0 ); + arr.set( 0, 5, 0, 7.0 ); + arr.set( 0, 15, -1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; submode=[throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw', 'throw' ], + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 5.0 ], + [ -4, -2, 11, 6.0 ], + [ 0, 5, 0, 7.0 ], + [ 0, 15, -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw' ], + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 5.0 ], + [ -4, -2, 11, 6.0 ], + [ 0, 5, 0, 7.0 ], + [ 0, 15, -1, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; row-major; submode=[wrap,wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); // (0,0,1) + arr.set( -4, -2, 11, 6.0 ); // (0,0,1) + arr.set( 0, 5, 0, 7.0 ); // (0,1,0) + arr.set( 0, 15, -1, 8.0 ); // (0,1,0) + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 8.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (3d; column-major; submode=[clamp,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 5.0 ); // (0,0,1) + arr.set( -4, -2, 11, 6.0 ); // (0,0,1) + arr.set( 0, 5, 0, 7.0 ); // (0,1,0) + arr.set( 0, 15, -1, 8.0 ); // (0,1,0) + + t.strictEqual( arr.get( 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 0 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 8.0, 6.0, 4.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.set_4d.js b/ctor/test/test.instance.set_4d.js new file mode 100644 index 00000000..909b1fae --- /dev/null +++ b/ctor/test/test.instance.set_4d.js @@ -0,0 +1,842 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method which throws an error if not provided an integer value for a dimension index (4d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ], 0 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 1 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 2 ), TypeError, 'throws an error when provided ' + values[ i ] ); + t.throws( badValue( values[ i ], 3 ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value, dim ) { + if ( dim === 0 ) { + return i; + } + if ( dim === 1 ) { + return j; + } + if ( dim === 2 ) { + return k; + } + return l; + + function i() { + arr.set( value, 0, 0, 0, 10.0 ); + } + + function j() { + arr.set( 0, value, 0, 0, 10.0 ); + } + + function k() { + arr.set( 0, 0, value, 0, 10.0 ); + } + + function l() { + arr.set( 0, 0, 0, value, 10.0 ); + } + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 0, 0, 5.0 ); + arr.set( 0, 0, 0, 1, 6.0 ); + arr.set( 0, 0, 1, 0, 7.0 ); + arr.set( 0, 0, 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 0, 0, 5.0 ); + arr.set( 0, 0, 0, 1, 6.0 ); + arr.set( 0, 0, 1, 0, 7.0 ); + arr.set( 0, 0, 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 6.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 2.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 11, 6.0 ], + [ 0, 0, -1, 0, 7.0 ], + [ 0, 0, 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 11, 6.0 ], + [ 0, 0, -1, 0, 7.0 ], + [ 0, 0, 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 11, 6.0 ], + [ 0, 0, -1, 0, 7.0 ], + [ 0, 0, 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 11, 6.0 ], + [ 0, 0, -1, 0, 7.0 ], + [ 0, 0, 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; submode=[clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 6.0, 3.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; submode=[clamp,clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, -1, 0, 7.0 ); + arr.set( 0, 0, 5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 2.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw' ], + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 11, 6.0 ], + [ 0, 0, -1, 0, 7.0 ], + [ 0, 0, 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; submode=[throw,throw,throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw', 'throw', 'throw', 'throw' ], + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 11, 6.0 ], + [ 0, 0, -1, 0, 7.0 ], + [ 0, 0, 5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; row-major; submode=[wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); // (0,0,0,1) + arr.set( 0, 0, 0, 11, 6.0 ); // (0,0,0,1) + arr.set( 0, 0, -1, 0, 7.0 ); // (0,0,1,0) + arr.set( 0, 0, 5, 5, 8.0 ); // (0,0,1,1) + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (4d; column-major; submode=[wrap,clamp,clamp,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'clamp', 'clamp', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 5.0 ); // (0,0,1,0) + arr.set( 0, 0, 0, 11, 6.0 ); // (0,0,0,1) + arr.set( 0, 0, -1, 0, 7.0 ); // (0,0,0,0) + arr.set( 0, 0, 5, 5, 8.0 ); // (0,0,1,1) + + t.strictEqual( arr.get( 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 5.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.set_nd.js b/ctor/test/test.instance.set_nd.js new file mode 100644 index 00000000..6df48735 --- /dev/null +++ b/ctor/test/test.instance.set_nd.js @@ -0,0 +1,830 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method which throws an error if not provided an integer value for a dimension index (>4d)', function test( t ) { + var strides; + var values; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + var i; + var j; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1, 1, 1, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + for ( j = 0; j < shape.length; j++ ) { + t.throws( badValue( values[ i ], j ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + } + t.end(); + + function badValue( value, dim ) { + return function badValue() { + var args = new Array( shape.length+1 ); + var i; + + for ( i = 0; i < shape.length; i++ ) { + if ( i === dim ) { + args[ i ] = value; + } else { + args[ i ] = 0; + } + } + args[ i ] = 10.0; + arr.set.apply( arr, args ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 0, 0, 0, 5.0 ); + arr.set( 0, 0, 0, 0, 1, 6.0 ); + arr.set( 0, 0, 0, 1, 0, 7.0 ); + arr.set( 0, 0, 0, 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + arr.set( 0, 0, 0, 0, 0, 5.0 ); + arr.set( 0, 0, 0, 0, 1, 6.0 ); + arr.set( 0, 0, 0, 1, 0, 7.0 ); + arr.set( 0, 0, 0, 1, 1, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; mode=wrap)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 3.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; mode=clamp)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 2.0, 8.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 0, 11, 6.0 ], + [ 0, 0, 0, -1, -10, 7.0 ], + [ 0, 0, 0, -5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; mode=throw)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'mode': 'throw' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 0, 11, 6.0 ], + [ 0, 0, 0, -1, -10, 7.0 ], + [ 0, 0, 0, -5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 2, 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 0, 11, 6.0 ], + [ 0, 0, 0, -1, -10, 7.0 ], + [ 0, 0, 0, -5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; mode=default)', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var arr; + var i; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + values = [ + [ 2, 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 0, 11, 6.0 ], + [ 0, 0, 0, -1, -10, 7.0 ], + [ 0, 0, 0, -5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; submode=[wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 6.0, 7.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; submode=[wrap,wrap])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 5.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; submode=[clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 3.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; submode=[clamp,clamp,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'clamp', 'clamp', 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); + arr.set( 0, 0, 0, 0, 11, 6.0 ); + arr.set( 0, 0, 0, -1, -10, 7.0 ); + arr.set( 0, 0, 0, -5, 5, 8.0 ); + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 5.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 2.0, 8.0, 5.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; submode=[throw,throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw', 'throw' ], + 'mode': 'wrap' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 0, 11, 6.0 ], + [ 0, 0, 0, -1, -10, 7.0 ], + [ 0, 0, 0, -5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; submode=[throw])', function test( t ) { + var strides; + var buffer; + var offset; + var values; + var dtype; + var order; + var shape; + var opts; + var arr; + var i; + + opts = { + 'submode': [ 'throw' ], + 'mode': 'clamp' + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + values = [ + [ 2, 2, 2, 2, 2, 5.0 ], + [ 0, 0, 0, 0, 11, 6.0 ], + [ 0, 0, 0, -1, -10, 7.0 ], + [ 0, 0, 0, -5, 5, 8.0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided arguments: ' + values[ i ] ); + } + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 3.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 2.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 2.0, 3.0, 4.0 ], 'has expected values' ); + + t.end(); + + function badValue( value ) { + return function badValue() { + arr.set.apply( arr, value ); + }; + } +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; row-major; submode=[wrap,wrap,clamp,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap', 'clamp', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'row-major'; + strides = [ 4, 4, 4, 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); // (0,0,0,1,0) + arr.set( 0, 0, 0, 0, 11, 6.0 ); // (0,0,0,0,1) + arr.set( 0, 0, 0, -1, -10, 7.0 ); // (0,0,0,0,0) + arr.set( 0, 0, 0, -5, 5, 8.0 ); // (0,0,0,0,1) + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 8.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 5.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 4.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 7.0, 8.0, 5.0, 4.0 ], 'has expected values' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a `set` method for setting an array element using subscripts (>4d; column-major; submode=[wrap,wrap,wrap,wrap,clamp])', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var opts; + var arr; + + opts = { + 'submode': [ 'wrap', 'wrap', 'wrap', 'wrap', 'clamp' ] + }; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 1, 1, 1, 2, 2 ]; + order = 'column-major'; + strides = [ 1, 1, 1, 1, 2 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, opts ); + + arr.set( 2, 2, 2, 2, 2, 5.0 ); // (0,0,0,0,1) + arr.set( 0, 0, 0, 0, 11, 6.0 ); // (0,0,0,0,1) + arr.set( 0, 0, 0, -1, -10, 7.0 ); // (0,0,0,1,0) + arr.set( 0, 0, 0, -5, 5, 8.0 ); // (0,0,0,1,1) + + t.strictEqual( arr.get( 0, 0, 0, 0, 0 ), 1.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 0, 1 ), 6.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 0 ), 7.0, 'returns expected value' ); + t.strictEqual( arr.get( 0, 0, 0, 1, 1 ), 8.0, 'returns expected value' ); + + t.deepEqual( buffer, [ 1.0, 7.0, 6.0, 8.0 ], 'has expected values' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.tojson.js b/ctor/test/test.instance.tojson.js new file mode 100644 index 00000000..722b0a31 --- /dev/null +++ b/ctor/test/test.instance.tojson.js @@ -0,0 +1,194 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toJSON()` method (row-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'float64'; + buffer = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'float64', + 'data': [ 3.0, 4.0, 5.0, 6.0 ], + 'shape': [ 2, 2 ], + 'strides': [ 2, 1 ], + 'order': 'row-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toJSON()` method (column-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'generic', + 'data': [ 4.0, 3.0, 2.0, 1.0 ], + 'shape': [ 2, 2 ], + 'strides': [ 1, 2 ], + 'order': 'column-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toJSON()` method (0d)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'generic', + 'data': [ 3.0 ], + 'shape': [], + 'strides': [ 0 ], + 'order': 'column-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toJSON()` method (complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toJSON' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toJSON' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toJSON ), true, 'has method' ); + + expected = { + 'type': 'ndarray', + 'dtype': 'complex64', + 'data': [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ], + 'shape': [ 2, 2 ], + 'strides': [ 2, 1 ], + 'order': 'row-major', + 'flags': {} + }; + actual = arr.toJSON(); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.instance.tostring.js b/ctor/test/test.instance.tostring.js new file mode 100644 index 00000000..46e8d2f6 --- /dev/null +++ b/ctor/test/test.instance.tostring.js @@ -0,0 +1,309 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var Complex128Array = require( '@stdlib/array/complex128' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var Complex64 = require( '@stdlib/complex/float32' ); +var Complex128 = require( '@stdlib/complex/float64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (order=row-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 2; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 3, 4, 5, 6 ], [ 2, 2 ], [ 2, 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (order=column-major)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'column-major'; + strides = [ -1, -2 ]; + offset = 3; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 4, 3, 2, 1 ], [ 2, 2 ], [ 1, 2 ], 0, \'column-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex64\', new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ), [ 2, 2 ], [ 2, 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex128'; + buffer = new Complex128Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex128\', new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ), [ 2, 2 ], [ 2, 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (large array)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = new Array( 1e4 ); + shape = [ buffer.length ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + buffer[ 0 ] = 1.0; + buffer[ 1 ] = 2.0; + buffer[ 2 ] = 3.0; + buffer[ buffer.length-3 ] = 4.0; + buffer[ buffer.length-2 ] = 5.0; + buffer[ buffer.length-1 ] = 6.0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 1, 2, 3, ..., 4, 5, 6 ], [ 10000 ], [ 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (large array; complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( 1e4 ); + shape = [ buffer.length ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + buffer.set( new Complex64( 1.0, 1.0 ), 0 ); + buffer.set( new Complex64( 2.0, 2.0 ), 1 ); + buffer.set( new Complex64( 3.0, 3.0 ), 2 ); + buffer.set( new Complex64( 4.0, 4.0 ), buffer.length-3 ); + buffer.set( new Complex64( 5.0, 5.0 ), buffer.length-2 ); + buffer.set( new Complex64( 6.0, 6.0 ), buffer.length-1 ); + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex64\', new Complex64Array( [ 1, 1, 2, 2, 3, 3, ..., 4, 4, 5, 5, 6, 6 ] ), [ 10000 ], [ 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (large array; complex type)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex128'; + buffer = new Complex128Array( 1e4 ); + shape = [ buffer.length ]; + order = 'row-major'; + strides = [ 1 ]; + offset = 0; + + buffer.set( new Complex128( 1.0, 1.0 ), 0 ); + buffer.set( new Complex128( 2.0, 2.0 ), 1 ); + buffer.set( new Complex128( 3.0, 3.0 ), 2 ); + buffer.set( new Complex128( 4.0, 4.0 ), buffer.length-3 ); + buffer.set( new Complex128( 5.0, 5.0 ), buffer.length-2 ); + buffer.set( new Complex128( 6.0, 6.0 ), buffer.length-1 ); + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'complex128\', new Complex128Array( [ 1, 1, 2, 2, 3, 3, ..., 4, 4, 5, 5, 6, 6 ] ), [ 10000 ], [ 1 ], 0, \'row-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'an ndarray constructor returns an instance which has a custom `toString()` method (0d)', function test( t ) { + var expected; + var strides; + var actual; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = []; + order = 'column-major'; + strides = [ 0 ]; + offset = 1; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( hasOwnProp( arr, 'toString' ), false, 'does not have own property' ); + t.strictEqual( hasProp( arr, 'toString' ), true, 'has property' ); + t.strictEqual( isFunction( arr.toString ), true, 'has method' ); + + expected = 'ndarray( \'generic\', [ 2 ], [], [ 0 ], 0, \'column-major\' )'; + actual = arr.toString(); + t.strictEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); diff --git a/ctor/test/test.js b/ctor/test/test.js new file mode 100644 index 00000000..5cfc65ac --- /dev/null +++ b/ctor/test/test.js @@ -0,0 +1,211 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var instanceOf = require( '@stdlib/assert/instance-of' ); +var Complex64Array = require( '@stdlib/array/complex64' ); +var ndarray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ndarray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor (complex dtype)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor (0d)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor (0d; complex dtype)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'complex64'; + buffer = new Complex64Array( [ 1.0, 1.0 ] ); + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor (options)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order, {} ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the function is an ndarray constructor (0d; options)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0 ]; + shape = []; + order = 'row-major'; + strides = [ 0 ]; + offset = 0; + + arr = new ndarray( dtype, buffer, shape, strides, offset, order, {} ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor does not require the `new` keyword', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor does not require the `new` keyword (options)', function test( t ) { + var strides; + var buffer; + var offset; + var dtype; + var order; + var shape; + var arr; + + dtype = 'generic'; + buffer = [ 1.0, 2.0, 3.0, 4.0 ]; + shape = [ 2, 2 ]; + order = 'row-major'; + strides = [ 2, 1 ]; + offset = 0; + + arr = ndarray( dtype, buffer, shape, strides, offset, order, {} ); + + t.strictEqual( instanceOf( arr, ndarray ), true, 'returns an instance' ); + t.end(); +}); diff --git a/ctor/test/test.validate.js b/ctor/test/test.validate.js new file mode 100644 index 00000000..82fbf913 --- /dev/null +++ b/ctor/test/test.validate.js @@ -0,0 +1,174 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var validate = require( './../lib/validate.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof validate, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an error if provided an `options` argument which is not an object', function test( t ) { + var values; + var err; + var i; + + values = [ + '5', + 5, + true, + false, + void 0, + null, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + err = validate( {}, values[ i ] ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an unrecognized/unsupported `mode` option', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 'throws', + 'wraps', + 'clamps', + 'clip', + 'clamped', + 'error', + 'err', + 5, + true, + false, + void 0, + null, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'mode': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided a `submode` option which is not an array containing recognized/supported modes', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 'throws', + 'wraps', + 'clamps', + 'clip', + 'clamped', + 'error', + 'err', + 5, + true, + false, + void 0, + null, + NaN, + [], + [ 'throw', 'wrap', 'clamp', 'foo' ], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'submode': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns `null` if all options are valid', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'mode': 'wrap', + 'submode': [ 'throw', 'wrap', 'clamp' ] + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, options, 'sets options' ); + + t.end(); +}); + +tape( 'the function will ignore unrecognized options', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'beep': true, + 'boop': 'bop' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, {}, 'ignores unrecognized options' ); + + t.end(); +}); diff --git a/dispatch/benchmark/benchmark.dispatch_size.js b/dispatch/benchmark/benchmark.dispatch_size.js new file mode 100644 index 00000000..3f7b03bf --- /dev/null +++ b/dispatch/benchmark/benchmark.dispatch_size.js @@ -0,0 +1,156 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var unary = require( '@stdlib/ndarray/base/unary' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var pkg = require( './../package.json' ).name; +var dispatch = require( './../lib/main.js' ); + + +// FUNCTIONS // + +/** +* Evaluates the identity function. +* +* @private +* @param {*} v - value +* @returns {*} input value +*/ +function identity( v ) { + return v; +} + +/** +* Dummy function which throws an error. +* +* @private +* @throws {Error} unexpected error +*/ +function throwError() { + throw new Error( 'unexpected error' ); +} + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} size - dispatch size +* @returns {Function} benchmark function +*/ +function createBenchmark( size ) { + var types; + var data; + var fcn; + var x; + var y; + var t; + var i; + + types = []; + + // Create dummy types... + for ( i = 0; i < (size-1)*2; i += 2 ) { + t = 'foo' + i; + types.push( t ); + types.push( t ); + } + // Append test types: + types.push( 'float64' ); + types.push( 'float64' ); + + // Define a list of callbacks: + data = []; + for ( i = 0; i < size-1; i++ ) { + data.push( throwError ); + } + // Append a test callback: + data.push( identity ); + + // Create the dispatcher: + fcn = dispatch( unary, types, data, 2, 1, 1 ); + + // Create sample arrays: + x = new Float64Array( 1 ); + y = new Float64Array( x.length ); + + x = ndarray( 'float64', x, [ 1 ], [ 1 ], 0, 'row-major' ); + y = ndarray( 'float64', y, [ 1 ], [ 1 ], 0, 'row-major' ); + + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var z; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + x[ 0 ] = i; + z = fcn( x, y ); + if ( isnan( z.data[ 0 ] ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( z.data[ 0 ] ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var size; + var min; + var max; + var f; + var i; + + min = 1; // 10^min + max = 6; // 10^max + + for ( i = min; i <= max; i++ ) { + size = pow( 2, i ); + f = createBenchmark( size ); + bench( pkg+':size='+size, f ); + } +} + +main(); diff --git a/dispatch/benchmark/benchmark.js b/dispatch/benchmark/benchmark.js new file mode 100644 index 00000000..0d5388c7 --- /dev/null +++ b/dispatch/benchmark/benchmark.js @@ -0,0 +1,81 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var unary = require( '@stdlib/ndarray/base/unary' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var pkg = require( './../package.json' ).name; +var dispatch = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::fcns_array', function benchmark( b ) { + var types; + var fcns; + var data; + var out; + var i; + + fcns = [ unary ]; + types = [ 'float64', 'float64' ]; + data = [ abs ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = dispatch( fcns, types, data, 2, 1, 1 ); + if ( typeof out !== 'function' ) { + b.fail( 'should return a function' ); + } + } + b.toc(); + if ( !isFunction( out ) ) { + b.fail( 'should return a function' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::fcn_arg', function benchmark( b ) { + var types; + var data; + var out; + var i; + + types = [ 'float64', 'float64' ]; + data = [ abs ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = dispatch( unary, types, data, 2, 1, 1 ); + if ( typeof out !== 'function' ) { + b.fail( 'should return a function' ); + } + } + b.toc(); + if ( !isFunction( out ) ) { + b.fail( 'should return a function' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/dispatch/examples/add.js b/dispatch/examples/add.js new file mode 100644 index 00000000..36e5197a --- /dev/null +++ b/dispatch/examples/add.js @@ -0,0 +1,120 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* eslint-disable array-element-newline */ + +'use strict'; + +var Float64Array = require( '@stdlib/array/float64' ); +var Int32Array = require( '@stdlib/array/int32' ); +var ind2sub = require( '@stdlib/ndarray/ind2sub' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var dispatch = require( './../lib' ); + +function add2( arrays ) { + var opts; + var xo; + var yo; + var zo; + var sx; + var sy; + var sz; + var sh; + var N; + var x; + var y; + var z; + var v; + var i; + + x = arrays[ 0 ]; + sh = x.shape; + N = numel( sh ); + if ( N <= 0 ) { + return; + } + y = arrays[ 1 ]; + z = arrays[ 2 ]; + xo = x.order; + yo = y.order; + zo = z.order; + opts = { + 'order': xo + }; + for ( i = 0; i < N; i++ ) { + opts.order = xo; + sx = ind2sub( sh, i, opts ); + opts.order = yo; + sy = ind2sub( sh, i, opts ); + v = x.get.apply( x, sx ) + y.get.apply( y, sy ); + + opts.order = zo; + sz = ind2sub( sh, i, opts ); + sz.push( v ); + z.set.apply( z, sz ); + } +} + +var fcns = [ + add2, + add2, + add2, + add2, + add2, + add2, + add2, + add2, + add2 +]; + +var types = [ + 'float64', 'float64', 'float64', + 'float32', 'float32', 'float32', + 'int32', 'int32', 'int32', + 'uint32', 'uint32', 'uint32', + 'int16', 'int16', 'int16', + 'uint16', 'uint16', 'uint16', + 'int8', 'int8', 'int8', + 'uint8', 'uint8', 'uint8', + 'uint8c', 'uint8c', 'uint8c' +]; + +var add = dispatch( fcns, types, null, 3, 2, 1 ); + +var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); +var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); +var zbuf = new Float64Array( xbuf.length ); + +var x = ndarray( 'float64', xbuf, [ 5 ], [ 1 ], 0, 'row-major' ); +var y = ndarray( 'float64', ybuf, [ 5 ], [ 1 ], 0, 'row-major' ); +var z = ndarray( 'float64', zbuf, [ 5 ], [ 1 ], 0, 'row-major' ); + +add( x, y, z ); +console.log( zbuf ); + +xbuf = new Int32Array( [ 10, 20, 30, 40, 50 ] ); +ybuf = new Int32Array( [ 10, 20, 30, 40, 50 ] ); +zbuf = new Int32Array( xbuf.length ); + +x = ndarray( 'int32', xbuf, [ 5 ], [ 1 ], 0, 'row-major' ); +y = ndarray( 'int32', ybuf, [ 5 ], [ 1 ], 0, 'row-major' ); +z = ndarray( 'int32', zbuf, [ 5 ], [ 1 ], 0, 'row-major' ); + +add( x, y, z ); +console.log( zbuf ); diff --git a/dispatch/examples/sin.js b/dispatch/examples/sin.js new file mode 100644 index 00000000..f353dd6d --- /dev/null +++ b/dispatch/examples/sin.js @@ -0,0 +1,141 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* eslint-disable array-element-newline */ + +'use strict'; + +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var Int8Array = require( '@stdlib/array/int8' ); +var sin = require( '@stdlib/math/base/special/sin' ); +var ind2sub = require( '@stdlib/ndarray/ind2sub' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var dispatch = require( './../lib' ); + +function apply( arrays, fcn ) { + var opts; + var xo; + var yo; + var sx; + var sy; + var sh; + var N; + var x; + var y; + var v; + var i; + + x = arrays[ 0 ]; + sh = x.shape; + N = numel( sh ); + if ( N <= 0 ) { + return; + } + y = arrays[ 1 ]; + xo = x.order; + yo = y.order; + opts = { + 'order': xo + }; + for ( i = 0; i < N; i++ ) { + opts.order = xo; + sx = ind2sub( sh, i, opts ); + v = fcn( x.get.apply( x, sx ) ); + + opts.order = yo; + sy = ind2sub( sh, i, opts ); + sy.push( v ); + y.set.apply( y, sy ); + } +} + +var fcns = [ + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply, + apply +]; + +var types = [ + 'float64', 'float64', + 'float32', 'float64', + 'float32', 'float32', + 'int32', 'float64', + 'uint32', 'float64', + 'int16', 'float64', + 'int16', 'float32', + 'uint16', 'float64', + 'uint16', 'float32', + 'int8', 'float64', + 'int8', 'float32', + 'uint8', 'float64', + 'uint8', 'float32', + 'uint8c', 'float64', + 'uint8c', 'float32' +]; + +var data = [ + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin, + sin +]; + +var sine = dispatch( fcns, types, data, 2, 1, 1 ); + +var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); +var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + +var x = ndarray( 'float64', xbuf, [ 5 ], [ 1 ], 0, 'row-major' ); +var y = ndarray( 'float64', ybuf, [ 5 ], [ 1 ], 0, 'row-major' ); + +sine( x, y ); +console.log( ybuf ); + +xbuf = new Int8Array( [ 1, 2, 3, 4, 5 ] ); +ybuf = new Float32Array( xbuf.length ); + +x = ndarray( 'int8', xbuf, [ 5 ], [ 1 ], 0, 'row-major' ); +y = ndarray( 'float32', ybuf, [ 5 ], [ 1 ], 0, 'row-major' ); + +sine( x, y ); +console.log( ybuf ); diff --git a/dispatch/examples/unary.js b/dispatch/examples/unary.js new file mode 100644 index 00000000..4bcb3111 --- /dev/null +++ b/dispatch/examples/unary.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var unary = require( '@stdlib/ndarray/base/unary' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var Float64Array = require( '@stdlib/array/float64' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var dispatch = require( './../lib' ); + +var types = [ 'float64', 'float64' ]; + +var data = [ + abs +]; + +var absolute = dispatch( unary, types, data, 2, 1, 1 ); + +var xbuf = new Float64Array( [ -1.0, -2.0, -3.0, -4.0, -5.0 ] ); +var ybuf = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] ); + +var x = ndarray( 'float64', xbuf, [ 5 ], [ 1 ], 0, 'row-major' ); +var y = ndarray( 'float64', ybuf, [ 5 ], [ 1 ], 0, 'row-major' ); + +absolute( x, y ); +console.log( ybuf ); +// => [ 1.0, 2.0, 3.0, 4.0, 5.0 ] diff --git a/dispatch/test/fixtures/binary.js b/dispatch/test/fixtures/binary.js new file mode 100644 index 00000000..a60dfa2d --- /dev/null +++ b/dispatch/test/fixtures/binary.js @@ -0,0 +1,38 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Binary callback. +* +* @private +* @param {number} x - input value +* @param {number} y - input value +* @returns {number} sum +*/ +function binary( x, y ) { + return x + y; +} + + +// EXPORTS // + +module.exports = binary; diff --git a/dispatch/test/fixtures/fill.js b/dispatch/test/fixtures/fill.js new file mode 100644 index 00000000..fca70eea --- /dev/null +++ b/dispatch/test/fixtures/fill.js @@ -0,0 +1,76 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var ind2sub = require( '@stdlib/ndarray/ind2sub' ); +var numel = require( '@stdlib/ndarray/base/numel' ); + + +// MAIN // + +/** +* Return an ndarray function which fills one or more ndarrays. +* +* @private +* @param {*} value - fill value +* @returns {Function} ndarray function +*/ +function fill( value ) { + return ndarrayFcn; + + /** + * ndarray function. + * + * @private + * @param {Array} arrays - ndarrays + */ + function ndarrayFcn( arrays ) { + var opts; + var sub; + var arr; + var sh; + var M; + var N; + var i; + var j; + + sh = arrays[ 0 ].shape; + N = numel( sh ); + M = arrays.length; + opts = { + 'order': '' + }; + for ( j = 0; j < M; j++ ) { + arr = arrays[ j ]; + opts.order = arrays[ j ].order; + for ( i = 0; i < N; i++ ) { + sub = ind2sub( sh, i, opts ); + sub.push( value ); + arr.set.apply( arr, sub ); + } + } + } +} + + +// EXPORTS // + +module.exports = fill; diff --git a/dispatch/test/fixtures/foreach.js b/dispatch/test/fixtures/foreach.js new file mode 100644 index 00000000..fc2334e6 --- /dev/null +++ b/dispatch/test/fixtures/foreach.js @@ -0,0 +1,72 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var ind2sub = require( '@stdlib/ndarray/ind2sub' ); +var numel = require( '@stdlib/ndarray/base/numel' ); + + +// MAIN // + +/** +* ndarray function. +* +* @private +* @param {Array} arrays - ndarrays +* @param {Function} fcn - callback +*/ +function forEach( arrays, fcn ) { + var opts; + var ords; + var args; + var sub; + var sh; + var M; + var N; + var i; + var j; + + sh = arrays[ 0 ].shape; + N = numel( sh ); + M = arrays.length; + ords = []; + args = []; + for ( j = 0; j < M; j++ ) { + ords.push( arrays[ j ].order ); + args.push( 0 ); + } + opts = { + 'order': '' + }; + for ( i = 0; i < N; i++ ) { + for ( j = 0; j < M; j++ ) { + opts.order = ords[ j ]; + sub = ind2sub( sh, i, opts ); + args[ j ] = arrays[ j ].get.apply( arrays[ j ], sub ); + } + fcn.apply( null, args ); + } +} + + +// EXPORTS // + +module.exports = forEach; diff --git a/dispatch/test/fixtures/map1n.js b/dispatch/test/fixtures/map1n.js new file mode 100644 index 00000000..23d2a229 --- /dev/null +++ b/dispatch/test/fixtures/map1n.js @@ -0,0 +1,74 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var ind2sub = require( '@stdlib/ndarray/ind2sub' ); +var numel = require( '@stdlib/ndarray/base/numel' ); + + +// MAIN // + +/** +* ndarray function which maps the return value of a callback to `N` arrays. +* +* @private +* @param {Array} arrays - ndarrays +* @param {Function} fcn - callback +*/ +function map1N( arrays, fcn ) { + var opts; + var ords; + var args; + var sub; + var sh; + var M; + var N; + var v; + var i; + var j; + + sh = arrays[ 0 ].shape; + N = numel( sh ); + M = arrays.length; + ords = []; + args = []; + for ( j = 0; j < M; j++ ) { + ords.push( arrays[ j ].order ); + args.push( 0 ); + } + opts = { + 'order': '' + }; + for ( i = 0; i < N; i++ ) { + v = fcn(); + for ( j = 0; j < M; j++ ) { + opts.order = ords[ j ]; + sub = ind2sub( sh, i, opts ); + sub.push( v ); + arrays[ j ].set.apply( arrays[ j ], sub ); + } + } +} + + +// EXPORTS // + +module.exports = map1N; diff --git a/dispatch/test/fixtures/nullary.js b/dispatch/test/fixtures/nullary.js new file mode 100644 index 00000000..4f221260 --- /dev/null +++ b/dispatch/test/fixtures/nullary.js @@ -0,0 +1,36 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Nullary callback. +* +* @private +* @returns {number} value +*/ +function nullary() { + return 3.0; +} + + +// EXPORTS // + +module.exports = nullary; diff --git a/dispatch/test/fixtures/quaternary.js b/dispatch/test/fixtures/quaternary.js new file mode 100644 index 00000000..548437bf --- /dev/null +++ b/dispatch/test/fixtures/quaternary.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Quaternary callback. +* +* @private +* @param {number} x - input value +* @param {number} y - input value +* @param {number} z - input value +* @param {number} w - input value +* @returns {number} sum +*/ +function quaternary( x, y, z, w ) { + return x + y + z + w; +} + + +// EXPORTS // + +module.exports = quaternary; diff --git a/dispatch/test/fixtures/quinary.js b/dispatch/test/fixtures/quinary.js new file mode 100644 index 00000000..36068de8 --- /dev/null +++ b/dispatch/test/fixtures/quinary.js @@ -0,0 +1,41 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Quinary callback. +* +* @private +* @param {number} x - input value +* @param {number} y - input value +* @param {number} z - input value +* @param {number} w - input value +* @param {number} u - input value +* @returns {number} sum +*/ +function quinary( x, y, z, w, u ) { + return x + y + z + w + u; +} + + +// EXPORTS // + +module.exports = quinary; diff --git a/dispatch/test/fixtures/sum.js b/dispatch/test/fixtures/sum.js new file mode 100644 index 00000000..f12eb981 --- /dev/null +++ b/dispatch/test/fixtures/sum.js @@ -0,0 +1,98 @@ +/** +* @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. +*/ + +'use strict'; + +// MODULES // + +var ind2sub = require( '@stdlib/ndarray/ind2sub' ); +var numel = require( '@stdlib/ndarray/base/numel' ); + + +// MAIN // + +/** +* Return an ndarray function which computes the sum across one or more ndarrays. +* +* @private +* @param {Object} ctx - context +* @param {number} ctx.sum - initial sum +* @returns {Function} ndarray function +*/ +function wrapper( ctx ) { + return ndarrayFcn; + + /** + * ndarray function. + * + * @private + * @param {Array} arrays - ndarrays + * @param {Function} [fcn] - callback + */ + function ndarrayFcn( arrays, fcn ) { + var opts; + var ords; + var args; + var sub; + var sh; + var M; + var N; + var f; + var i; + var j; + + if ( arguments.length > 1 ) { + f = fcn; + } + sh = arrays[ 0 ].shape; + N = numel( sh ); + M = arrays.length; + ords = []; + args = []; + for ( j = 0; j < M; j++ ) { + ords.push( arrays[ j ].order ); + args.push( 0 ); + } + opts = { + 'order': '' + }; + if ( f ) { + for ( i = 0; i < N; i++ ) { + for ( j = 0; j < M; j++ ) { + opts.order = ords[ j ]; + sub = ind2sub( sh, i, opts ); + args[ j ] = arrays[ j ].get.apply( arrays[ j ], sub ); + } + ctx.sum += f.apply( null, args ); + } + } else { + for ( i = 0; i < N; i++ ) { + for ( j = 0; j < M; j++ ) { + opts.order = ords[ j ]; + sub = ind2sub( sh, i, opts ); + ctx.sum += arrays[ j ].get.apply( arrays[ j ], sub ); + } + } + } + } +} + + +// EXPORTS // + +module.exports = wrapper; diff --git a/dispatch/test/fixtures/ternary.js b/dispatch/test/fixtures/ternary.js new file mode 100644 index 00000000..0595d5f0 --- /dev/null +++ b/dispatch/test/fixtures/ternary.js @@ -0,0 +1,39 @@ +/** +* @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. +*/ + +'use strict'; + +// MAIN // + +/** +* Ternary callback. +* +* @private +* @param {number} x - input value +* @param {number} y - input value +* @param {number} z - input value +* @returns {number} sum +*/ +function ternary( x, y, z ) { + return x + y + z; +} + + +// EXPORTS // + +module.exports = ternary; diff --git a/dispatch/test/test.js b/dispatch/test/test.js new file mode 100644 index 00000000..aee66ade --- /dev/null +++ b/dispatch/test/test.js @@ -0,0 +1,364 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var unary = require( '@stdlib/ndarray/base/unary' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var dispatch = require( './../lib' ); + + +// FIXTURES // + +var fill = require( './fixtures/fill.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dispatch, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided either a function or an array of functions as a first argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + var data = [ abs ]; + dispatch( value, types, data, 2, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided an array of strings as a second argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [ '5', 5 ], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var data = [ abs ]; + dispatch( unary, value, data, 2, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided either an array-like object or `null` as a third argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + void 0, + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + dispatch( unary, types, value, 2, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided a positive integer for a fourth argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 0, + -1, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + var data = [ abs ]; + dispatch( unary, types, data, value, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided a nonnegative integer for a fifth argument', function test( t ) { + var values; + var i; + + values = [ + '5', + -1, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + var data = [ abs ]; + dispatch( unary, types, data, 2, value, 1 ); + }; + } +}); + +tape( 'the function throws an error if not provided a nonnegative integer for a sixth argument', function test( t ) { + var values; + var i; + + values = [ + '5', + -1, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + var data = [ abs ]; + dispatch( unary, types, data, 2, 1, value ); + }; + } +}); + +tape( 'the function throws an error if the number of types is incompatible with the number of types indicated by other function parameters (function array)', function test( t ) { + var values; + var i; + + values = [ + [ 'float64' ], + [ 'float64', 'float64', 'float64' ], + [ 'float64', 'float32', 'float32' ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var fcns = [ unary, unary, unary ]; + var data = [ abs, abs, abs ]; + dispatch( fcns, value, data, 2, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if the number of types is incompatible with the number of types indicated by other function parameters (function argument)', function test( t ) { + var values; + var i; + + values = [ + [ 'float64' ], + [ 'float64', 'float64', 'float64' ], + [ 'float64', 'float32', 'float32' ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var data = [ abs, abs, abs ]; + dispatch( unary, value, data, 2, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if the length of `data` argument does not match the number of ndarray functions', function test( t ) { + var values; + var i; + + values = [ + [], + [ abs, abs ], + [ abs, abs, abs ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + var fcns = [ unary ]; + dispatch( fcns, types, value, 2, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if the fourth argument is incompatible with the number of input and output ndarrays', function test( t ) { + var values; + var i; + + values = [ + 0, + 1, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), Error, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var types = [ 'float64', 'float64' ]; + var data = [ abs ]; + dispatch( unary, types, data, value, 1, 1 ); + }; + } +}); + +tape( 'the function throws an error if the number of specified input and output ndarrays is zero', function test( t ) { + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + var types = [ 'float64' ]; + dispatch( fill( 3 ), types, null, 1, 0, 0 ); + } +}); + +tape( 'the function returns an ndarray function interface', function test( t ) { + var types; + var data; + var f; + + types = [ 'float64', 'float64' ]; + data = [ abs ]; + + f = dispatch( unary, types, data, 2, 1, 1 ); + t.strictEqual( isFunction( f ), true, 'returns expected value' ); + + f = dispatch( [ unary ], types, data, 2, 1, 1 ); + t.strictEqual( isFunction( f ), true, 'returns expected value' ); + + f = dispatch( fill( 3 ), types, null, 2, 1, 1 ); + t.strictEqual( isFunction( f ), true, 'returns expected value' ); + + f = dispatch( [ fill( 3 ) ], types, null, 2, 1, 1 ); + t.strictEqual( isFunction( f ), true, 'returns expected value' ); + + t.end(); +}); diff --git a/dispatch/test/test.two_arrays.js b/dispatch/test/test.two_arrays.js new file mode 100644 index 00000000..f6cb1a48 --- /dev/null +++ b/dispatch/test/test.two_arrays.js @@ -0,0 +1,808 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* eslint-disable array-element-newline */ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var unary = require( '@stdlib/ndarray/base/unary' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var Int32Array = require( '@stdlib/array/int32' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var dtype = require( '@stdlib/ndarray/base/buffer-dtype' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var dispatch = require( './../lib' ); + + +// FIXTURES // + +var forEach = require( './fixtures/foreach.js' ); +var map1N = require( './fixtures/map1n.js' ); +var fill = require( './fixtures/fill.js' ); +var sum = require( './fixtures/sum.js' ); + + +// TESTS // + +tape( 'the function returns a function which throws an error if not provided an ndarray for the first argument', function test( t ) { + var values; + var types; + var data; + var fcn; + var i; + + types = [ 'float64', 'float64' ]; + data = [ abs ]; + fcn = dispatch( unary, types, data, 2, 1, 1 ); + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var ybuf = new Float64Array( 10 ); + var y = ndarray( 'float64', ybuf, [ 10 ], [ 1 ], 0, 'row-major' ); + fcn( value, y ); + }; + } +}); + +tape( 'the function returns a function which throws an error if not provided an ndarray for the second argument', function test( t ) { + var values; + var types; + var data; + var fcn; + var i; + + types = [ 'float64', 'float64' ]; + data = [ abs ]; + fcn = dispatch( unary, types, data, 2, 1, 1 ); + + values = [ + '5', + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var xbuf = new Float64Array( 10 ); + var x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + fcn( x, value ); + }; + } +}); + +tape( 'the function returns a function which throws an error if provided insufficient arguments', function test( t ) { + var values; + var types; + var data; + var xbuf; + var f; + var x; + var i; + + types = [ 'float64', 'float64' ]; + data = [ abs ]; + f = dispatch( unary, types, data, 2, 1, 1 ); + + xbuf = new Float64Array( 10 ); + x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + values = [ + [], + [ x ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( wrapper( values[i] ), Error, 'throws an error when provided ' + values[ i ].length + ' arguments' ); + } + t.end(); + + function wrapper( args ) { + return function fcn() { + f.apply( null, args ); + }; + } +}); + +tape( 'the function returns a function which throws an error if provided too many arguments', function test( t ) { + var values; + var types; + var data; + var xbuf; + var ybuf; + var f; + var x; + var y; + var i; + + types = [ 'float64', 'float64' ]; + data = [ abs ]; + f = dispatch( unary, types, data, 2, 1, 1 ); + + xbuf = new Float64Array( 10 ); + x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + values = [ + [ x, y, y ], + [ x, y, y, y ], + [ x, y, y, y, y ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( wrapper( values[i] ), Error, 'throws an error when provided ' + values[ i ].length + ' arguments' ); + } + t.end(); + + function wrapper( args ) { + return function fcn() { + f.apply( null, args ); + }; + } +}); + +tape( 'the function returns a function which throws an error if unable to resolve a ndarray function supporting the provided array argument data types', function test( t ) { + var values; + var types; + var data; + var xbuf; + var fcn; + var x; + var i; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ abs, abs ]; + fcn = dispatch( unary, types, data, 2, 1, 1 ); + + xbuf = new Float64Array( 4 ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + values = [ + new Uint8Array( 4 ), + new Int32Array( 4 ), + [ 0, 0, 0, 0 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided an array having data type: ' + dtype( values[i] ) ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var y = ndarray( dtype( value ), value, [ value.length ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + }; + } +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function; no data; only input arrays)', function test( t ) { + var types; + var xbuf; + var ybuf; + var ctx; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + + ctx = { + 'sum': 0 + }; + fcn = dispatch( sum( ctx ), types, null, 2, 2, 0 ); + + ctx.sum = 0; + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + t.strictEqual( ctx.sum, 20.0, 'returns expected value' ); + + ctx.sum = 5; + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + t.strictEqual( ctx.sum, 25.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function; no data; only output arrays)', function test( t ) { + var expected; + var types; + var xbuf; + var ybuf; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + + fcn = dispatch( fill( 3.0 ), types, null, 2, 0, 2 ); + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ 3.0, 3.0, 3.0, 3.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( xbuf.length ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ 3.0, 3.0, 3.0, 3.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function array; no data; only input arrays)', function test( t ) { + var types; + var fcns; + var xbuf; + var ybuf; + var fcn; + var ctx; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + + ctx = { + 'sum': 0 + }; + fcns = [ + sum( ctx ), + sum( ctx ) + ]; + fcn = dispatch( fcns, types, null, 2, 2, 0 ); + + ctx.sum = 0; + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + t.strictEqual( ctx.sum, 20.0, 'returns expected value' ); + + ctx.sum = 5; + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + t.strictEqual( ctx.sum, 25.0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function array; no data; only output arrays)', function test( t ) { + var expected; + var types; + var fcns; + var xbuf; + var ybuf; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + + fcns = [ + fill( 3.0 ), + fill( 4.0 ) + ]; + fcn = dispatch( fcns, types, null, 2, 0, 2 ); + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ 3.0, 3.0, 3.0, 3.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( xbuf.length ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ 4.0, 4.0, 4.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function; data; only input arrays)', function test( t ) { + var expected; + var types; + var data; + var xbuf; + var ybuf; + var fcn; + var cnt; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ + clbk, + clbk + ]; + + fcn = dispatch( forEach, types, data, 2, 2, 0 ); + cnt = 0; + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + t.strictEqual( cnt, 4, 'returns expected value' ); + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + t.strictEqual( cnt, 8, 'returns expected value' ); + + t.end(); + + function clbk() { + cnt += 1; + } +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function; data; only output arrays)', function test( t ) { + var expected; + var types; + var data; + var xbuf; + var ybuf; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ + three, + four + ]; + + fcn = dispatch( map1N, types, data, 2, 0, 2 ); + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ 3.0, 3.0, 3.0, 3.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ 4.0, 4.0, 4.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + t.end(); + + function three() { + return 3.0; + } + + function four() { + return 4.0; + } +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function; data; input and output arrays)', function test( t ) { + var expected; + var types; + var data; + var xbuf; + var ybuf; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ + abs, + abs + ]; + + fcn = dispatch( unary, types, data, 2, 1, 1 ); + + xbuf = new Float64Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + + expected = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + xbuf = new Float32Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + + expected = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function array; data; only input arrays)', function test( t ) { + var expected; + var types; + var data; + var fcns; + var xbuf; + var ybuf; + var fcn; + var cnt; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ + clbk, + clbk + ]; + fcns = [ + forEach, + forEach + ]; + fcn = dispatch( fcns, types, data, 2, 2, 0 ); + cnt = 0; + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + t.strictEqual( cnt, 4, 'returns expected value' ); + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + t.strictEqual( cnt, 8, 'returns expected value' ); + + t.end(); + + function clbk() { + cnt += 1; + } +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function array; data; only output arrays)', function test( t ) { + var expected; + var types; + var data; + var fcns; + var xbuf; + var ybuf; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ + three, + four + ]; + fcns = [ + map1N, + map1N + ]; + fcn = dispatch( fcns, types, data, 2, 0, 2 ); + + xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ 3.0, 3.0, 3.0, 3.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + xbuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ 4.0, 4.0, 4.0, 4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + t.end(); + + function three() { + return 3.0; + } + + function four() { + return 4.0; + } +}); + +tape( 'the function returns a function which invokes a callback for indexed ndarray elements (function array; data; input and output arrays)', function test( t ) { + var expected; + var types; + var data; + var fcns; + var xbuf; + var ybuf; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + data = [ + abs, + abs + ]; + fcns = [ + unary, + unary + ]; + fcn = dispatch( fcns, types, data, 2, 1, 1 ); + + xbuf = new Float64Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + x = ndarray( 'float64', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + y = ndarray( 'float64', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float64Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + + expected = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + xbuf = new Float32Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + x = ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float32Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + y = ndarray( 'float32', ybuf, [ 4 ], [ 1 ], 0, 'row-major' ); + + fcn( x, y ); + + expected = new Float32Array( [ -1.0, -2.0, -3.0, -4.0 ] ); + t.deepEqual( xbuf, expected, 'returns expected value' ); + + expected = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + t.deepEqual( ybuf, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns a function which returns one or more output arrays, if one or more output arrays is specified, and otherwise returns `undefined`', function test( t ) { + var types; + var data; + var xbuf; + var ybuf; + var out; + var ctx; + var fcn; + var x; + var y; + + types = [ + 'float64', 'float64', + 'float32', 'float32' + ]; + + // No output arrays... + ctx = { + 'sum': 0 + }; + fcn = dispatch( sum( ctx ), types, null, 2, 2, 0 ); + + xbuf = new Float64Array( 10 ); + x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + out = fcn( x, y ); + t.strictEqual( out, void 0, 'returns expected value' ); + + // One output array... + data = [ + abs, + abs + ]; + fcn = dispatch( unary, types, data, 2, 1, 1 ); + + xbuf = new Float64Array( 10 ); + x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + out = fcn( x, y ); + t.strictEqual( out, y, 'returns expected value' ); + + fcn = dispatch( fill( 3.0 ), types, null, 2, 1, 1 ); + + xbuf = new Float64Array( 10 ); + x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + out = fcn( x, y ); + t.strictEqual( out, y, 'returns expected value' ); + + // Two output arrays... + fcn = dispatch( fill( 3.0 ), types, null, 2, 0, 2 ); + + xbuf = new Float64Array( 10 ); + x = ndarray( 'float64', xbuf, [ 10 ], [ 1 ], 0, 'row-major' ); + ybuf = new Float64Array( xbuf.length ); + y = ndarray( 'float64', ybuf, [ 10 ], [ 1 ], 0, 'row-major' ); + + out = fcn( x, y ); + t.strictEqual( out.length, 2, 'returns expected value' ); + t.strictEqual( out[ 0 ], x, 'returns expected value' ); + t.strictEqual( out[ 1 ], y, 'returns expected value' ); + + t.end(); +}); diff --git a/docs/types/index.d.ts b/docs/types/index.d.ts new file mode 100644 index 00000000..02b3a638 --- /dev/null +++ b/docs/types/index.d.ts @@ -0,0 +1,385 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +// TypeScript Version: 2.0 + +/* tslint:disable:max-line-length */ +/* tslint:disable:max-file-line-count */ + +import array = require( '@stdlib/ndarray/array' ); +import base = require( '@stdlib/ndarray/base' ); +import ndarrayCastingModes = require( '@stdlib/ndarray/casting-modes' ); +import ndarray = require( '@stdlib/ndarray/ctor' ); +import ndarrayDataTypes = require( '@stdlib/ndarray/dtypes' ); +import ind2sub = require( '@stdlib/ndarray/ind2sub' ); +import ndarrayIndexModes = require( '@stdlib/ndarray/index-modes' ); +import ndarrayMinDataType = require( '@stdlib/ndarray/min-dtype' ); +import ndarrayNextDataType = require( '@stdlib/ndarray/next-dtype' ); +import ndarrayOrders = require( '@stdlib/ndarray/orders' ); +import ndarrayPromotionRules = require( '@stdlib/ndarray/promotion-rules' ); +import ndarraySafeCasts = require( '@stdlib/ndarray/safe-casts' ); +import ndarraySameKindCasts = require( '@stdlib/ndarray/same-kind-casts' ); +import sub2ind = require( '@stdlib/ndarray/sub2ind' ); + +/** +* Interface describing the `ndarray` namespace. +*/ +interface Namespace { + /** + * Returns a multidimensional array. + * + * @param buffer - data source + * @param options - function options + * @param options.buffer - data source + * @param options.dtype - underlying storage data type (if the input data is not of the same type, this option specifies the data type to which to cast the input data) (default: 'float64') + * @param options.order - specifies the memory layout of the array as either row-major (C-style) or column-major (Fortran-style) (default: 'row-major') + * @param options.shape - array shape + * @param options.mode - specifies how to handle indices which exceed array dimensions (default: 'throw') + * @param options.submode - specifies how to handle subscripts which exceed array dimensions on a per dimension basis (default: ['throw']) + * @param options.copy - boolean indicating whether to copy source data to a new data buffer (default: false) + * @param options.flatten - boolean indicating whether to automatically flatten generic array data sources (default: true) + * @param options.ndmin - minimum number of dimensions (default: 0) + * @param options.casting - casting rule used to determine what constitutes an acceptable cast (default: 'safe') + * @throws must provide valid options + * @throws must provide either an array shape, data source, or both + * @throws invalid cast + * @throws data source must be compatible with specified meta data + * @returns ndarray instance + * + * @example + * var arr = ns.array( [ [ 1, 2 ], [ 3, 4 ] ] ); + * // returns + * + * var v = arr.get( 0, 0 ); + * // returns 1 + * + * @example + * var opts = { + * 'dtype': 'generic', + * 'flatten': false + * }; + * + * var arr = ns.array( [ [ 1, 2 ], [ 3, 4 ] ], opts ); + * // returns + * + * var v = arr.get( 0 ); + * // returns [ 1, 2 ] + * + * @example + * var Float64Array = require( '@stdlib/ns.array/float64' ); + * + * var opts = { + * 'shape': [ 2, 2 ] + * }; + * + * var arr = ns.array( new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ), opts ); + * // returns + * + * var v = arr.get( 0, 0 ); + * // returns 1.0 + */ + array: typeof array; + + /** + * Base ndarray. + */ + base: typeof base; + + /** + * Returns a list of ndarray casting modes. + * + * ## Notes + * + * - The output array contains the following modes: + * + * - 'none': only allow casting between identical types + * - 'equiv': allow casting between identical and byte swapped types + * - 'safe': only allow "safe" casts + * - 'same-kind': allow "safe" casts and casts within the same kind (e.g., + * between signed integers or between floats) + * - 'unsafe': allow casting between all types (including between integers and + * floats) + * + * @returns list of ndarray casting modes + * + * @example + * var list = ns.ndarrayCastingModes(); + * // returns [ 'none', 'equiv', 'safe', 'same-kind', 'unsafe' ] + */ + ndarrayCastingModes: typeof ndarrayCastingModes; + + /** + * ndarray constructor. + * + * @param dtype - data type + * @param buffer - data buffer + * @param shape - array shape + * @param strides - array strides + * @param offset - index offset + * @param order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) + * @param options - function options + * @param options.mode - specifies how to handle indices which exceed array dimensions (default: 'throw') + * @param options.submode - specifies how to handle subscripts which exceed array dimensions on a per dimension basis (default: ['throw']) + * @throws `buffer` argument `get` and `set` properties must be functions + * @throws `shape` argument must be an array-like object containing nonnegative integers + * @throws `shape` argument length must equal the number of dimensions + * @throws `strides` argument must be an array-like object containing integers + * @throws `strides` argument length must equal the number of dimensions (except for zero-dimensional arrays; in which case, the `strides` argument length must be equal to `1`) + * @throws for zero-dimensional ndarrays, the `strides` argument must contain a single element equal to `0` + * @throws `offset` argument must be a nonnegative integer + * @throws `buffer` argument must be compatible with specified meta data + * @throws must provide valid options + * @throws too many dimensions + * @returns ndarray instance + * + * @example + * var buffer = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ]; + * var shape = [ 3, 2 ]; + * var strides = [ 2, 1 ]; + * var offset = 0; + * + * var out = ns.ndarray( 'generic', buffer, shape, strides, offset, 'row-major' ); + */ + ndarray: typeof ndarray; + + /** + * Returns a list of ndarray data types. + * + * ## Notes + * + * - The output array contains the following data types: + * + * - `binary`: binary. + * - `complex64`: single-precision complex floating-point numbers. + * - `complex128`: double-precision complex floating-point numbers. + * - `float32`: single-precision floating-point numbers. + * - `float64`: double-precision floating-point numbers. + * - `generic`: values of any type. + * - `int16`: signed 16-bit integers. + * - `int32`: signed 32-bit integers. + * - `int8`: signed 8-bit integers. + * - `uint16`: unsigned 16-bit integers. + * - `uint32`: unsigned 32-bit integers. + * - `uint8`: unsigned 8-bit integers. + * - `uint8c`: unsigned clamped 8-bit integers. + * + * @returns list of ndarray data types + * + * @example + * var list = ns.ndarrayDataTypes(); + * // returns [...] + */ + ndarrayDataTypes: typeof ndarrayDataTypes; + + /** + * Converts a linear index to an array of subscripts. + * + * ## Notes + * + * - The function accepts the following "modes": + * + * - `throw`: throws an error when a linear index exceeds array dimensions. + * - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic. + * - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index. + * + * + * @param shape - array shape + * @param idx - linear index + * @param options - function options + * @param options.mode - specifies how to handle a linear index which exceeds array dimensions (default: 'throw') + * @param options.order - specifies whether an array is row-major (C-style) or column-major (Fortran-style) (default: 'row-major') + * @throws shape argument must be an array-like object containing nonnegative integers + * @throws must provide valid options + * @throws must provide a linear index which does not exceed array dimensions + * @returns subscripts + * + * @example + * var s = ns.ind2sub( [ 3, 3, 3 ], 17 ); + * // returns [ 1, 2, 2 ] + * + * @example + * var shape = [ 3, 3, 3 ]; + * var out = [ 0, 0, 0 ]; + * + * var s = ns.ind2sub.assign( shape, 17, out ); + * // returns [ 1, 2, 2 ] + * + * var bool = ( s === out ); + * // returns true + */ + ind2sub: typeof ind2sub; + + /** + * Returns a list of ndarray index modes. + * + * ## Notes + * + * - The output array contains the following modes: + * + * - throw: specifies that a function should throw an error when an index is + * outside a restricted interval. + * - wrap: specifies that a function should wrap around an index using modulo + * arithmetic. + * - clamp: specifies that a function should set an index less than zero to + * zero (minimum index) and set an index greater than a maximum index value to + * the maximum possible index. + * + * @returns list of ndarray index modes + * + * @example + * var list = ns.ndarrayIndexModes(); + * // returns [ 'throw', 'clamp', 'wrap' ] + */ + ndarrayIndexModes: typeof ndarrayIndexModes; + + /** + * Returns the minimum ndarray data type of the closest "kind" necessary for storing a provided scalar value. + * + * @param value - scalar value + * @returns ndarray data type + * + * @example + * var dt = ns.ndarrayMinDataType( 3.141592653589793 ); + * // returns 'float32' + * + * @example + * var dt = ns.ndarrayMinDataType( 3 ); + * // returns 'uint8' + */ + ndarrayMinDataType: typeof ndarrayMinDataType; + + /** + * Returns the next larger ndarray data type of the same kind. + * + * ## Notes + * + * - If not provided a data type, the function returns a table. + * - If a data type does not have a next larger data type or the next larger type is not supported, the function returns `-1`. + * - If provided an unrecognized data type, the function returns `null`. + * + * @param dtype - ndarray data type + * @returns next larger data type(s) or null + * + * @example + * var dt = ns.ndarrayNextDataType( 'float32' ); + * // returns 'float64' + */ + ndarrayNextDataType: typeof ndarrayNextDataType; + + /** + * Returns a list of ndarray orders. + * + * ## Notes + * + * - The output array contains the following orders: + * + * - row-major: row-major (C-style) order. + * - column-major: column-major (Fortran-style) order. + * + * @returns list of ndarray orders + * + * @example + * var list = ns.ndarrayOrders(); + * // returns [ 'row-major', 'column-major' ] + */ + ndarrayOrders: typeof ndarrayOrders; + + /** + * Returns a type promotion table displaying the ndarray data types with the smallest size and closest "kind" to which ndarray data types can be safely cast. + * + * @returns promotion rule table + * + * @example + * var table = ns.ndarrayPromotionRules(); + * // returns {...} + */ + ndarrayPromotionRules: typeof ndarrayPromotionRules; + + /** + * Returns a list of ndarray data types to which a provided ndarray data type can be safely cast. + * + * ## Notes + * + * - If not provided an ndarray data type, the function returns a casting table. + * - If provided an unrecognized ndarray data type, the function returns `null`. + * + * @param dtype - ndarray data type + * @returns list of ndarray data types or null + * + * @example + * var list = ns.ndarraySafeCasts( 'float32' ); + * // returns [...] + */ + ndarraySafeCasts: typeof ndarraySafeCasts; + + /** + * Returns a list of ndarray data types to which a provided ndarray data type can be safely cast or cast within the same "kind". + * + * ## Notes + * + * - If not provided an ndarray data type, the function returns a casting table. + * - If provided an unrecognized ndarray data type, the function returns `null`. + * + * @param dtype - ndarray data type + * @returns list of ndarray data types or null + * + * @example + * var list = ns.ndarraySameKindCasts( 'float32' ); + * // returns [...] + */ + ndarraySameKindCasts: typeof ndarraySameKindCasts; + + /** + * Converts subscripts to a linear index. + * + * ## Notes + * + * - The function accepts the following "modes": + * + * - `throw`: throws an error when a subscript exceeds array dimensions. + * - `wrap`: wrap around subscripts exceeding array dimensions using modulo arithmetic. + * - `clamp`: set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension. + * + * - If provided fewer modes than dimensions, the function recycles modes using modulo arithmetic. + * + * + * @param shape - array shape + * @param args - subscripts followed by an optional options object + * @throws first argument must be an array-like object containing nonnegative integers + * @throws subscripts must be integer valued + * @throws must provide valid options + * @throws must provide subscripts which do not exceed array dimensions + * @throws number of subscripts much match the number of dimensions + * @returns linear index + * + * @example + * var i = ns.sub2ind( [ 3, 3, 3 ], 1, 2, 2 ); + * // returns 17 + */ + sub2ind: typeof sub2ind; +} + +/** +* Multidimensional arrays. +*/ +declare var ns: Namespace; + + +// EXPORTS // + +export = ns; diff --git a/docs/types/test.ts b/docs/types/test.ts new file mode 100644 index 00000000..23cb79c9 --- /dev/null +++ b/docs/types/test.ts @@ -0,0 +1,29 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* tslint:disable:no-unused-expression */ + +import ndarray = require( './index' ); + + +// TESTS // + +// The exported value is the expected interface... +{ + ndarray; // $ExpectType Namespace +} diff --git a/dtypes/benchmark/benchmark.js b/dtypes/benchmark/benchmark.js new file mode 100644 index 00000000..25d9ac36 --- /dev/null +++ b/dtypes/benchmark/benchmark.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var pkg = require( './../package.json' ).name; +var dtypes = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = dtypes(); + if ( out.length !== 11 ) { + b.fail( 'should return an array of length 11' ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/dtypes/examples/index.js b/dtypes/examples/index.js new file mode 100644 index 00000000..441447aa --- /dev/null +++ b/dtypes/examples/index.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var indexOf = require( '@stdlib/utils/index-of' ); +var dtypes = require( './../lib' ); + +var DTYPES = dtypes(); +var bool; + +function isdtype( str ) { + if ( indexOf( DTYPES, str ) === -1 ) { + return false; + } + return true; +} + +bool = isdtype( 'float64' ); +console.log( bool ); +// => true + +bool = isdtype( 'int8' ); +console.log( bool ); +// => true + +bool = isdtype( 'uint16' ); +console.log( bool ); +// => true + +bool = isdtype( 'beep' ); +console.log( bool ); +// => false diff --git a/dtypes/test/test.js b/dtypes/test/test.js new file mode 100644 index 00000000..e75f54ef --- /dev/null +++ b/dtypes/test/test.js @@ -0,0 +1,94 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var dtypes = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dtypes, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a list of ndarray data types', function test( t ) { + var expected; + var actual; + + expected = [ + 'binary', + 'complex64', + 'complex128', + 'float32', + 'float64', + 'generic', + 'int16', + 'int32', + 'int8', + 'uint16', + 'uint32', + 'uint8', + 'uint8c' + ]; + actual = dtypes(); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'attached to the main function is an `enum` method to return an object mapping dtypes to integer values for C inter-operation', function test( t ) { + var obj; + var dt; + var i; + + t.strictEqual( hasOwnProp( dtypes, 'enum' ), true, 'has property' ); + t.strictEqual( typeof dtypes.enum, 'function', 'has method' ); + + obj = dtypes.enum(); + t.strictEqual( typeof obj, 'object', 'returns expected value type' ); + + // List of native C types which should be supported... + dt = [ + 'int8', + 'uint8', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'int64', + 'uint64', + 'float32', + 'float64', + 'complex64', + 'complex128' + ]; + for ( i = 0; i < dt.length; i++ ) { + t.strictEqual( hasOwnProp( obj, dt[ i ] ), true, 'has property `' + dt[ i ] + '`' ); + t.strictEqual( isNonNegativeInteger( obj[ dt[i] ] ), true, 'returns expected value' ); + } + + t.end(); +}); diff --git a/examples/index.js b/examples/index.js new file mode 100644 index 00000000..c7e940d8 --- /dev/null +++ b/examples/index.js @@ -0,0 +1,24 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var objectKeys = require( '@stdlib/utils/keys' ); +var ns = require( './../lib' ); + +console.log( objectKeys( ns ) ); diff --git a/ind2sub/benchmark/benchmark.js b/ind2sub/benchmark/benchmark.js new file mode 100644 index 00000000..852f58dd --- /dev/null +++ b/ind2sub/benchmark/benchmark.js @@ -0,0 +1,236 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var isNonNegativeIntegerArray = require( '@stdlib/assert/is-nonnegative-integer-array' ).primitives; +var numel = require( '@stdlib/ndarray/base/numel' ); +var pkg = require( './../package.json' ).name; +var ind2sub = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var shape; + var len; + var out; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, idx ); + if ( out.length !== shape.length ) { + b.fail( 'should return an array with expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::memory_reuse:assign', function benchmark( b ) { + var shape; + var len; + var out; + var idx; + var s; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + out = [ 0, 0, 0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + s = ind2sub.assign( shape, idx, out ); + if ( s !== out ) { + b.fail( 'should return output array' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( s ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap', function benchmark( b ) { + var shape; + var opts; + var len; + var out; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + opts = { + 'mode': 'wrap' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, idx, opts ); + if ( out.length !== shape.length ) { + b.fail( 'should return an array with expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp', function benchmark( b ) { + var shape; + var opts; + var len; + var out; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + opts = { + 'mode': 'clamp' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, idx, opts ); + if ( out.length !== shape.length ) { + b.fail( 'should return an array with expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw', function benchmark( b ) { + var shape; + var opts; + var len; + var out; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + opts = { + 'mode': 'throw' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, idx, opts ); + if ( out.length !== shape.length ) { + b.fail( 'should return an array with expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':order=row-major', function benchmark( b ) { + var shape; + var opts; + var len; + var out; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + opts = { + 'order': 'row-major' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, idx, opts ); + if ( out.length !== shape.length ) { + b.fail( 'should return an array with expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':order=column-major', function benchmark( b ) { + var shape; + var opts; + var len; + var out; + var idx; + var i; + + shape = [ 10, 10, 10 ]; + len = numel( shape ); + opts = { + 'order': 'column-major' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + idx = floor( randu()*len ); + out = ind2sub( shape, idx, opts ); + if ( out.length !== shape.length ) { + b.fail( 'should return an array with expected length' ); + } + } + b.toc(); + if ( !isNonNegativeIntegerArray( out ) ) { + b.fail( 'should return an array containing nonnegative integers' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/ind2sub/benchmark/julia/REQUIRE b/ind2sub/benchmark/julia/REQUIRE new file mode 100644 index 00000000..98645e19 --- /dev/null +++ b/ind2sub/benchmark/julia/REQUIRE @@ -0,0 +1,2 @@ +julia 1.5 +BenchmarkTools 0.5.0 diff --git a/ind2sub/benchmark/julia/benchmark.jl b/ind2sub/benchmark/julia/benchmark.jl new file mode 100644 index 00000000..f9805fc9 --- /dev/null +++ b/ind2sub/benchmark/julia/benchmark.jl @@ -0,0 +1,144 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +import BenchmarkTools +using Printf + +# Benchmark variables: +name = "ind2sub"; +repeats = 3; + +""" + print_version() + +Prints the TAP version. + +# Examples + +``` julia +julia> print_version() +``` +""" +function print_version() + @printf( "TAP version 13\n" ); +end + +""" + print_summary( total, passing ) + +Print the benchmark summary. + +# Arguments + +* `total`: total number of tests +* `passing`: number of passing tests + +# Examples + +``` julia +julia> print_summary( 3, 3 ) +``` +""" +function print_summary( total, passing ) + @printf( "#\n" ); + @printf( "1..%d\n", total ); # TAP plan + @printf( "# total %d\n", total ); + @printf( "# pass %d\n", passing ); + @printf( "#\n" ); + @printf( "# ok\n" ); +end + +""" + print_results( iterations, elapsed ) + +Print benchmark results. + +# Arguments + +* `iterations`: number of iterations +* `elapsed`: elapsed time (in seconds) + +# Examples + +``` julia +julia> print_results( 1000000, 0.131009101868 ) +``` +""" +function print_results( iterations, elapsed ) + rate = iterations / elapsed + + @printf( " ---\n" ); + @printf( " iterations: %d\n", iterations ); + @printf( " elapsed: %0.9f\n", elapsed ); + @printf( " rate: %0.9f\n", rate ); + @printf( " ...\n" ); +end + +""" + benchmark() + +Run a benchmark. + +# Notes + +* Benchmark results are returned as a two-element array: [ iterations, elapsed ]. +* The number of iterations is not the true number of iterations. Instead, an 'iteration' is defined as a 'sample', which is a computed estimate for a single evaluation. +* The elapsed time is in seconds. + +# Examples + +``` julia +julia> out = benchmark(); +``` +""" +function benchmark() + t = BenchmarkTools.@benchmark Base._ind2sub( (10,10,10), Int32( floor( rand()*1000.0 ) ) ) samples=1e6 + + # Compute the total "elapsed" time and convert from nanoseconds to seconds: + s = sum( t.times ) / 1.0e9; + + # Determine the number of "iterations": + iter = length( t.times ); + + # Return the results: + [ iter, s ]; +end + +""" + main() + +Run benchmarks. + +# Examples + +``` julia +julia> main(); +``` +""" +function main() + print_version(); + for i in 1:repeats + @printf( "# julia::%s\n", name ); + results = benchmark(); + print_results( results[ 1 ], results[ 2 ] ); + @printf( "ok %d benchmark finished\n", i ); + end + print_summary( repeats, repeats ); +end + +main(); diff --git a/ind2sub/benchmark/python/numpy/benchmark.py b/ind2sub/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..8dbf8198 --- /dev/null +++ b/ind2sub/benchmark/python/numpy/benchmark.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.unravel_index.""" + +from __future__ import print_function +import timeit + +NAME = "ind2sub" +REPEATS = 3 +ITERATIONS = 1000000 + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(elapsed): + """Print benchmark results. + + # Arguments + + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(0.131009101868) + ``` + """ + rate = ITERATIONS / elapsed + + print(" ---") + print(" iterations: " + str(ITERATIONS)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(): + """Run the benchmark and print benchmark results.""" + setup = "import numpy as np; from random import random;" + stmt = "y = np.unravel_index(int(random()*1000.0), (10,10,10))" + + t = timeit.Timer(stmt, setup=setup) + + print_version() + + for i in range(REPEATS): + print("# python::numpy::" + NAME) + elapsed = t.timeit(number=ITERATIONS) + print_results(elapsed) + print("ok " + str(i+1) + " benchmark finished") + + print_summary(REPEATS, REPEATS) + + +def main(): + """Run the benchmark.""" + benchmark() + + +if __name__ == "__main__": + main() diff --git a/ind2sub/examples/index.js b/ind2sub/examples/index.js new file mode 100644 index 00000000..d15f13fe --- /dev/null +++ b/ind2sub/examples/index.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var numel = require( '@stdlib/ndarray/base/numel' ); +var ind2sub = require( './../lib' ); + +var shape = [ 3, 3, 3 ]; +var len = numel( shape ); + +var arr = []; +var i; +for ( i = 0; i < len; i++ ) { + arr.push( i ); +} + +var opts = { + 'order': 'column-major' +}; + +console.log( '' ); +console.log( 'Dimensions: %s.', shape.join( 'x' ) ); +console.log( 'View (subscripts):' ); +console.log( '' ); + +var row; +var s; + +row = ' '; +for ( i = 0; i < len; i++ ) { + s = ind2sub( shape, i, opts ); + row += '(' + s.join( ',' ) + ')'; + if ( (i+1)%shape[0] === 0 ) { + console.log( row ); + row = ' '; + } else { + row += ', '; + } + if ( (i+1)%(shape[0]*shape[1]) === 0 ) { + console.log( '' ); + } +} diff --git a/ind2sub/test/test.assign.js b/ind2sub/test/test.assign.js new file mode 100644 index 00000000..a0756535 --- /dev/null +++ b/ind2sub/test/test.assign.js @@ -0,0 +1,778 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var Uint8Array = require( '@stdlib/array/uint8' ); +var ind2sub = require( './../lib/assign.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ind2sub, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided an output argument which is not an array, typed array, or object', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], 0, value ); + }; + } +}); + +tape( 'the function throws an error if not provided an output argument which is not an array, typed array, or object (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], 0, {}, value ); + }; + } +}); + +tape( 'the function throws an error if not provided an array-like object containing nonnegative integers as the shape argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 2, null ], + [ 1, 2, 3.14 ], + [ 1, 2, NaN ], + [ 1, 2, '3' ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( value, 0, [ 0, 0 ] ); + }; + } +}); + +tape( 'the function throws an error if not provided an array-like object containing nonnegative integers as the shape argument (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 2, null ], + [ 1, 2, 3.14 ], + [ 1, 2, NaN ], + [ 1, 2, '3' ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( value, 0, {}, [ 0, 0 ] ); + }; + } +}); + +tape( 'the function throws an error if provided a linear index argument which is not an integer value', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], value, [ 0, 0, 0 ] ); + }; + } +}); + +tape( 'the function throws an error if provided a linear index argument which is not an integer value (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], value, {}, [ 0, 0, 0 ] ); + }; + } +}); + +tape( 'the function throws an error if not provided an object for the options argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], 0, value, [ 0, 0, 0 ] ); + }; + } +}); + +tape( 'the function throws an error if provided an invalid option', function test( t ) { + var values; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var opts = { + 'mode': value + }; + ind2sub( [ 3, 3, 3 ], 0, opts, [ 0, 0, 0 ] ); + }; + } +}); + +tape( 'the function converts a linear index to an array of subscripts (2d)', function test( t ) { + var shape; + var out; + var s; + + shape = [ 2, 2 ]; + + out = [ 0, 0 ]; + s = ind2sub( shape, 0, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.strictEqual( out, s, 'returns output array' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + out = [ 0, 0 ]; + s = ind2sub( shape, 1, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.strictEqual( out, s, 'returns output array' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + out = [ 0, 0 ]; + s = ind2sub( shape, 2, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.strictEqual( out, s, 'returns output array' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + out = [ 0, 0 ]; + s = ind2sub( shape, 3, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.strictEqual( out, s, 'returns output array' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; typed array)', function test( t ) { + var shape; + var out; + var s; + + shape = [ 2, 2 ]; + + out = new Uint8Array( shape.length ); + s = ind2sub( shape, 0, out ); + t.strictEqual( out, s, 'returns output array' ); + t.strictEqual( s[ 0 ], 0, 'returns expected value' ); + t.strictEqual( s[ 1 ], 0, 'returns expected value' ); + + out = new Uint8Array( shape.length ); + s = ind2sub( shape, 1, out ); + t.strictEqual( out, s, 'returns output array' ); + t.strictEqual( s[ 0 ], 0, 'returns expected value' ); + t.strictEqual( s[ 1 ], 1, 'returns expected value' ); + + out = new Uint8Array( shape.length ); + s = ind2sub( shape, 2, out ); + t.strictEqual( out, s, 'returns output array' ); + t.strictEqual( s[ 0 ], 1, 'returns expected value' ); + t.strictEqual( s[ 1 ], 0, 'returns expected value' ); + + out = new Uint8Array( shape.length ); + s = ind2sub( shape, 3, out ); + t.strictEqual( out, s, 'returns output array' ); + t.strictEqual( s[ 0 ], 1, 'returns expected value' ); + t.strictEqual( s[ 1 ], 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; order=row-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'row-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 0, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; order=column-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'column-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 0, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d)', function test( t ) { + var shape; + var out; + var s; + + shape = [ 3, 3, 3 ]; + out = [ 0, 0, 0 ]; + + s = ind2sub( shape, 17, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 2, 2 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=row-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 3, 3, 3 ]; + opts = { + 'order': 'row-major' + }; + out = [ 0, 0, 0 ]; + + s = ind2sub( shape, 17, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 2, 2 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=column-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 3, 3, 3 ]; + opts = { + 'order': 'column-major' + }; + out = [ 0, 0, 0 ]; + + s = ind2sub( shape, 17, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 2, 2, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (order=row-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'row-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 0, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (order=column-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'column-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 0, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts, out ); + t.strictEqual( s, out, 'returns expected value' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (default)', function test( t ) { + t.throws( foo, RangeError, 'throws a range error' ); + t.end(); + + function foo() { + ind2sub( [ 2, 2 ], 999999, [ 0, 0 ] ); + } +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (option)', function test( t ) { + var opts = { + 'mode': 'throw' + }; + + t.throws( foo, RangeError, 'throws a range error' ); + t.end(); + + function foo() { + ind2sub( [ 2, 2 ], 999999, opts, [ 0, 0 ] ); + } +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 2, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap', + 'order': 'row-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 2, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap', + 'order': 'column-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 2, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 2, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp', + 'order': 'row-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 2, opts, out ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var shape; + var opts; + var out; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp', + 'order': 'column-major' + }; + out = [ 0, 0 ]; + + s = ind2sub( shape, 2, opts, out ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts, out ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts, out ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); diff --git a/ind2sub/test/test.js b/ind2sub/test/test.js new file mode 100644 index 00000000..812b7440 --- /dev/null +++ b/ind2sub/test/test.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var ind2sub = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ind2sub, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the main export is a method for assigning results to a specified output array', function test( t ) { + t.strictEqual( hasOwnProp( ind2sub, 'assign' ), true, 'has property' ); + t.strictEqual( typeof ind2sub.assign, 'function', 'has method' ); + t.end(); +}); diff --git a/ind2sub/test/test.main.js b/ind2sub/test/test.main.js new file mode 100644 index 00000000..8428ca1f --- /dev/null +++ b/ind2sub/test/test.main.js @@ -0,0 +1,657 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var ind2sub = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ind2sub, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided an array-like object containing nonnegative integers as the shape argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 2, null ], + [ 1, 2, 3.14 ], + [ 1, 2, NaN ], + [ 1, 2, '3' ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( value, 0 ); + }; + } +}); + +tape( 'the function throws an error if not provided an array-like object containing nonnegative integers as the shape argument (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 2, null ], + [ 1, 2, 3.14 ], + [ 1, 2, NaN ], + [ 1, 2, '3' ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( value, 0, {} ); + }; + } +}); + +tape( 'the function throws an error if provided a linear index argument which is not an integer value', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], value ); + }; + } +}); + +tape( 'the function throws an error if provided a linear index argument which is not an integer value (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], value, {} ); + }; + } +}); + +tape( 'the function throws an error if not provided an object for the options argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + ind2sub( [ 3, 3, 3 ], 0, value ); + }; + } +}); + +tape( 'the function throws an error if provided an invalid option', function test( t ) { + var values; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var opts = { + 'mode': value + }; + ind2sub( [ 3, 3, 3 ], 0, opts ); + }; + } +}); + +tape( 'the function converts a linear index to an array of subscripts (2d)', function test( t ) { + var shape; + var s; + + shape = [ 2, 2 ]; + + s = ind2sub( shape, 0 ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1 ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 2 ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 3 ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; order=row-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'row-major' + }; + + s = ind2sub( shape, 0, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (2d; order=column-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'column-major' + }; + + s = ind2sub( shape, 0, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d)', function test( t ) { + var shape; + var s; + + shape = [ 3, 3, 3 ]; + + s = ind2sub( shape, 17 ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 2, 2 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=row-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 3, 3, 3 ]; + opts = { + 'order': 'row-major' + }; + + s = ind2sub( shape, 17, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 2, 2 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (3d; order=column-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 3, 3, 3 ]; + opts = { + 'order': 'column-major' + }; + + s = ind2sub( shape, 17, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 2, 2, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (order=row-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'row-major' + }; + + s = ind2sub( shape, 0, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts a linear index to an array of subscripts (order=column-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'order': 'column-major' + }; + + s = ind2sub( shape, 0, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 1, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 2, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 3, opts ); + t.strictEqual( isArray( s ), true, 'returns an array' ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (default)', function test( t ) { + t.throws( foo, RangeError, 'throws a range error' ); + t.end(); + + function foo() { + ind2sub( [ 2, 2 ], 999999 ); + } +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a linear index which exceeds array dimensions (option)', function test( t ) { + var opts = { + 'mode': 'throw' + }; + + t.throws( foo, RangeError, 'throws a range error' ); + t.end(); + + function foo() { + ind2sub( [ 2, 2 ], 999999, opts ); + } +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap' + }; + + s = ind2sub( shape, 2, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap', + 'order': 'row-major' + }; + + s = ind2sub( shape, 2, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `wrap`, the function wraps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap', + 'order': 'column-major' + }; + + s = ind2sub( shape, 2, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp' + }; + + s = ind2sub( shape, 2, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=row-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp', + 'order': 'row-major' + }; + + s = ind2sub( shape, 2, opts ); + t.deepEqual( s, [ 1, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceeds array dimensions (order=column-major)', function test( t ) { + var shape; + var opts; + var s; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp', + 'order': 'column-major' + }; + + s = ind2sub( shape, 2, opts ); + t.deepEqual( s, [ 0, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 4, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, 5, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -2, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -8, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, 13, opts ); + t.deepEqual( s, [ 1, 1 ], 'returns expected value' ); + + s = ind2sub( shape, -5, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + s = ind2sub( shape, -7, opts ); + t.deepEqual( s, [ 0, 0 ], 'returns expected value' ); + + t.end(); +}); diff --git a/ind2sub/test/test.validate.js b/ind2sub/test/test.validate.js new file mode 100644 index 00000000..9659809b --- /dev/null +++ b/ind2sub/test/test.validate.js @@ -0,0 +1,160 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var validate = require( './../lib/validate.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof validate, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an error if provided an `options` argument which is not an object', function test( t ) { + var values; + var err; + var i; + + values = [ + '5', + 5, + true, + false, + void 0, + null, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + err = validate( {}, values[ i ] ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an unsupported/unrecognized `order` option', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + true, + false, + void 0, + null, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'order': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an unsupported/unrecognized `mode` option', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 'throws', + 5, + true, + false, + void 0, + null, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'mode': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns `null` if all options are valid', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'mode': 'wrap', + 'order': 'column-major' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, options, 'sets options' ); + + t.end(); +}); + +tape( 'the function will ignore unrecognized options', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'beep': true, + 'boop': 'bop' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, {}, 'ignores unrecognized options' ); + + t.end(); +}); diff --git a/index-modes/benchmark/benchmark.js b/index-modes/benchmark/benchmark.js new file mode 100644 index 00000000..86fa5b93 --- /dev/null +++ b/index-modes/benchmark/benchmark.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var pkg = require( './../package.json' ).name; +var modes = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = modes(); + if ( out.length !== 3 ) { + b.fail( 'should return an array of length 3' ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/index-modes/examples/index.js b/index-modes/examples/index.js new file mode 100644 index 00000000..39bfacba --- /dev/null +++ b/index-modes/examples/index.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var indexOf = require( '@stdlib/utils/index-of' ); +var modes = require( './../lib' ); + +var MODES = modes(); +var bool; + +function isMode( str ) { + if ( indexOf( MODES, str ) === -1 ) { + return false; + } + return true; +} + +bool = isMode( 'throw' ); +console.log( bool ); +// => true + +bool = isMode( 'clamp' ); +console.log( bool ); +// => true + +bool = isMode( 'wrap' ); +console.log( bool ); +// => true + +bool = isMode( 'beep' ); +console.log( bool ); +// => false diff --git a/index-modes/test/test.js b/index-modes/test/test.js new file mode 100644 index 00000000..94e9b2af --- /dev/null +++ b/index-modes/test/test.js @@ -0,0 +1,75 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var modes = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof modes, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a list of ndarray index modes', function test( t ) { + var expected; + var actual; + + expected = [ + 'throw', + 'clamp', + 'wrap' + ]; + actual = modes(); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'attached to the main function is an `enum` method to return an object mapping index modes to integer values for C inter-operation', function test( t ) { + var obj; + var m; + var i; + + t.strictEqual( hasOwnProp( modes, 'enum' ), true, 'has property' ); + t.strictEqual( typeof modes.enum, 'function', 'has method' ); + + obj = modes.enum(); + t.strictEqual( typeof obj, 'object', 'returns expected value type' ); + + // List of index modes which should be supported... + m = [ + 'throw', + 'clamp', + 'wrap' + ]; + for ( i = 0; i < m.length; i++ ) { + t.strictEqual( hasOwnProp( obj, m[ i ] ), true, 'has property `' + m[ i ] + '`' ); + t.strictEqual( isNonNegativeInteger( obj[ m[i] ] ), true, 'returns expected value' ); + } + + t.end(); +}); diff --git a/min-dtype/benchmark/benchmark.js b/min-dtype/benchmark/benchmark.js new file mode 100644 index 00000000..d2a78a5b --- /dev/null +++ b/min-dtype/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var minDataType = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var N; + var i; + + values = [ + -0.0, + 3.14, + 3.0, + -3.0, + 1.0e308, + 3.14e37, + NaN + ]; + N = values.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = minDataType( values[ i%N ] ); + if ( typeof out !== 'string' || out === 'generic' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) || out === 'generic' ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/min-dtype/benchmark/python/numpy/benchmark.py b/min-dtype/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..5e5718e5 --- /dev/null +++ b/min-dtype/benchmark/python/numpy/benchmark.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.min_scalar_type.""" + +from __future__ import print_function +import timeit + +NAME = "min-dtype" +REPEATS = 3 +ITERATIONS = 1000000 + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(elapsed): + """Print benchmark results. + + # Arguments + + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(0.131009101868) + ``` + """ + rate = ITERATIONS / elapsed + + print(" ---") + print(" iterations: " + str(ITERATIONS)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(): + """Run the benchmark and print benchmark results.""" + setup = "import numpy as np; from random import random;" + stmt = "y = np.min_scalar_type(random()*1000.0)" + + t = timeit.Timer(stmt, setup=setup) + + print_version() + + for i in range(REPEATS): + print("# python::numpy::" + NAME) + elapsed = t.timeit(number=ITERATIONS) + print_results(elapsed) + print("ok " + str(i+1) + " benchmark finished") + + print_summary(REPEATS, REPEATS) + + +def main(): + """Run the benchmark.""" + benchmark() + + +if __name__ == "__main__": + main() diff --git a/min-dtype/examples/index.js b/min-dtype/examples/index.js new file mode 100644 index 00000000..d3254b8c --- /dev/null +++ b/min-dtype/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var roundn = require( '@stdlib/math/base/special/roundn' ); +var randu = require( '@stdlib/random/base/randu' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var minDataType = require( './../lib' ); + +var dt; +var v; +var i; + +// Generate numbers of varying magnitudes and determine the minimum data type for each value... +for ( i = 0; i < 100; i++ ) { + v = randu() * pow( 2.0, discreteUniform( 0, 40 ) ); + if ( randu() < 0.5 ) { + v *= -1; + } + v = roundn( v, discreteUniform( -1, 0 ) ); + dt = minDataType( v ); + console.log( 'min(%d) => %s', v, dt ); +} diff --git a/min-dtype/lib/main.js b/min-dtype/lib/main.js index 81228204..5ce5a622 100644 --- a/min-dtype/lib/main.js +++ b/min-dtype/lib/main.js @@ -25,16 +25,16 @@ var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' ); var isComplexLike = require( '@stdlib/assert/is-complex-like' ); var real = require( '@stdlib/complex/real' ); var imag = require( '@stdlib/complex/imag' ); -var PINF = require( '@stdlib/constants/math/float64-pinf' ); -var NINF = require( '@stdlib/constants/math/float64-ninf' ); -var FLOAT32_SMALLEST_SUBNORMAL = require( '@stdlib/constants/math/float32-smallest-subnormal' ); // eslint-disable-line id-length -var FLOAT32_MAX = require( '@stdlib/constants/math/float32-max' ); -var INT8_MIN = require( '@stdlib/constants/math/int8-min' ); -var INT16_MIN = require( '@stdlib/constants/math/int16-min' ); -var INT32_MIN = require( '@stdlib/constants/math/int32-min' ); -var UINT8_MAX = require( '@stdlib/constants/math/uint8-max' ); -var UINT16_MAX = require( '@stdlib/constants/math/uint16-max' ); -var UINT32_MAX = require( '@stdlib/constants/math/uint32-max' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); +var FLOAT32_SMALLEST_SUBNORMAL = require( '@stdlib/constants/float32/smallest-subnormal' ); // eslint-disable-line id-length +var FLOAT32_MAX = require( '@stdlib/constants/float32/max' ); +var INT8_MIN = require( '@stdlib/constants/int8/min' ); +var INT16_MIN = require( '@stdlib/constants/int16/min' ); +var INT32_MIN = require( '@stdlib/constants/int32/min' ); +var UINT8_MAX = require( '@stdlib/constants/uint8/max' ); +var UINT16_MAX = require( '@stdlib/constants/uint16/max' ); +var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); // MAIN // diff --git a/min-dtype/test/test.js b/min-dtype/test/test.js new file mode 100644 index 00000000..40dbc680 --- /dev/null +++ b/min-dtype/test/test.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); +var Complex64 = require( '@stdlib/complex/float32' ); +var Complex128 = require( '@stdlib/complex/float64' ); +var minDataType = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof minDataType, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the minimum ndarray data type of the closest "kind" necessary for storing a provided scalar value', function test( t ) { + var expected; + var actual; + var values; + var i; + + values = [ + NaN, + 0, + 0.0, + -0.0, + 1, + -1, + 300, // >2**8 + -300, + 65537, // >2**16 + -65537, + 4294967297, // >2**32 + -4294967297, + 3.14, + -3.14, + 1.0e40, // >10**38 + -1.0e40, + -1.0e-46, // <10**-45 + 1.0e-46, + PINF, + NINF, + 'beep', + {}, + true, + false, + [], + new Complex64( 1.0, 1.0 ), + new Complex64( NaN, NaN ), + new Complex64( PINF, PINF ), + new Complex64( PINF, NINF ), + new Complex64( PINF, NaN ), + new Complex64( NINF, PINF ), + new Complex64( NINF, NINF ), + new Complex64( NINF, NaN ), + new Complex128( 1.0, 1.0 ), + new Complex128( NaN, NaN ), + new Complex128( PINF, PINF ), + new Complex128( PINF, NINF ), + new Complex128( PINF, NaN ), + new Complex128( NINF, PINF ), + new Complex128( NINF, NINF ), + new Complex128( NINF, NaN ), + new Complex128( -1.0e-46, 1.0 ), + new Complex128( 1.0e-46, 1.0 ), + new Complex128( 1.0, -1.0e-46 ), + new Complex128( 1.0, 1.0e-46 ), + new Complex128( -1.0e40, 1.0 ), + new Complex128( 1.0e40, 1.0 ), + new Complex128( 1.0, -1.0e40 ), + new Complex128( 1.0, 1.0e40 ) + ]; + expected = [ + 'float32', + 'uint8', + 'uint8', + 'float32', + 'uint8', + 'int8', + 'uint16', + 'int16', + 'uint32', + 'int32', + 'float64', + 'float64', + 'float32', + 'float32', + 'float64', + 'float64', + 'float64', + 'float64', + 'float32', + 'float32', + 'generic', + 'generic', + 'generic', + 'generic', + 'generic', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex64', + 'complex128', + 'complex128', + 'complex128', + 'complex128', + 'complex128', + 'complex128', + 'complex128', + 'complex128' + ]; + for ( i = 0; i < values.length; i++ ) { + actual = minDataType( values[i] ); + t.strictEqual( actual, expected[ i ], 'returns expected value when provided '+values[i] ); + } + t.end(); +}); diff --git a/next-dtype/benchmark/benchmark.js b/next-dtype/benchmark/benchmark.js new file mode 100644 index 00000000..aa31450f --- /dev/null +++ b/next-dtype/benchmark/benchmark.js @@ -0,0 +1,71 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var nextDataType = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = nextDataType(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::dtype', function benchmark( b ) { + var out; + var dt; + var i; + + dt = dtypes(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = nextDataType( dt[ i%dt.length ] ); + if ( typeof out !== 'string' && out !== -1 ) { + b.fail( 'should return a string or -1' ); + } + } + b.toc(); + if ( !isString( out ) && out !== -1 ) { + b.fail( 'should return a string or -1' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/next-dtype/examples/index.js b/next-dtype/examples/index.js new file mode 100644 index 00000000..c116f24e --- /dev/null +++ b/next-dtype/examples/index.js @@ -0,0 +1,35 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var nextDataType = require( './../lib' ); + +var DTYPES; +var dt; +var i; + +// Get the list of supported ndarray data types: +DTYPES = dtypes(); + +// Print the next larger data type for each supported data type... +for ( i = 0; i < DTYPES.length; i++ ) { + dt = nextDataType( DTYPES[ i ] ); + console.log( '%s => %s', DTYPES[ i ], dt ); +} diff --git a/next-dtype/test/test.js b/next-dtype/test/test.js new file mode 100644 index 00000000..63b31345 --- /dev/null +++ b/next-dtype/test/test.js @@ -0,0 +1,80 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var nextDataType = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof nextDataType, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if not provided a data type, the function returns a table', function test( t ) { + var out = nextDataType(); + t.strictEqual( typeof out, 'object', 'returns an object' ); + t.strictEqual( out[ 'float32' ], 'float64', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the next larger ndarray data type of the same kind', function test( t ) { + var table; + var out; + var dt; + var i; + + table = nextDataType(); + + for ( i = 0; i < DTYPES.length; i++ ) { + dt = DTYPES[ i ]; + out = nextDataType( dt ); + t.strictEqual( out, table[ dt ], 'returns expected value when provided '+dt ); + } + t.end(); +}); + +tape( 'if provided an unrecognized or unsupported data type, the function returns `null`', function test( t ) { + var values; + var i; + + values = [ + 'beep', + 'boop', + 'foo', + 'bar', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( nextDataType( values[ i ] ), null, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/orders/benchmark/benchmark.js b/orders/benchmark/benchmark.js new file mode 100644 index 00000000..28e4b63d --- /dev/null +++ b/orders/benchmark/benchmark.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var pkg = require( './../package.json' ).name; +var orders = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = orders(); + if ( out.length !== 2 ) { + b.fail( 'should return an array of length 2' ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/orders/examples/index.js b/orders/examples/index.js new file mode 100644 index 00000000..26e7506f --- /dev/null +++ b/orders/examples/index.js @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var indexOf = require( '@stdlib/utils/index-of' ); +var orders = require( './../lib' ); + +var ORDERS = orders(); +var bool; + +function isOrder( str ) { + if ( indexOf( ORDERS, str ) === -1 ) { + return false; + } + return true; +} + +bool = isOrder( 'row-major' ); +console.log( bool ); +// => true + +bool = isOrder( 'column-major' ); +console.log( bool ); +// => true + +bool = isOrder( 'beep' ); +console.log( bool ); +// => false diff --git a/orders/test/test.js b/orders/test/test.js new file mode 100644 index 00000000..b37a42f5 --- /dev/null +++ b/orders/test/test.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var orders = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof orders, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a list of ndarray orders', function test( t ) { + var expected; + var actual; + + expected = [ + 'row-major', + 'column-major' + ]; + actual = orders(); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'attached to the main function is an `enum` method to return an object mapping orders to integer values for C inter-operation', function test( t ) { + var obj; + var o; + var i; + + t.strictEqual( hasOwnProp( orders, 'enum' ), true, 'has property' ); + t.strictEqual( typeof orders.enum, 'function', 'has method' ); + + obj = orders.enum(); + t.strictEqual( typeof obj, 'object', 'returns expected value type' ); + + // List of orders which should be supported... + o = [ + 'row-major', + 'column-major' + ]; + for ( i = 0; i < o.length; i++ ) { + t.strictEqual( hasOwnProp( obj, o[ i ] ), true, 'has property `' + o[ i ] + '`' ); + t.strictEqual( isNonNegativeInteger( obj[ o[i] ] ), true, 'returns expected value' ); + } + + t.end(); +}); diff --git a/package.json b/package.json index 5766464d..405f2ad7 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,15 @@ ], "main": "./lib", "directories": { - "lib": "./lib" + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": { + "test": "tape $(find . -type d -name test -exec grep -irl --include=\\*.js tape {} +) | tap-spec", + "test-cov": "istanbul cover --dir ./reports/coverage --report lcov tape -- $(find . -type d -name test -exec grep -irl --include=\\*.js tape {} +)", + "examples": "find examples/** -name \"*.js\" ! -path \"examples/fixtures/**\" | while read -r file; do echo \"\"; echo \"Running example: $file\"; node $file || exit 1; done" }, - "scripts": {}, "homepage": "https://github.com/stdlib-js/stdlib", "repository": { "type": "git", @@ -27,19 +33,27 @@ "url": "https://github.com/stdlib-js/stdlib/issues" }, "dependencies": { - "@stdlib/types": "0.0.0", - "@stdlib/array": "0.0.0", - "@stdlib/assert": "0.0.0", - "@stdlib/buffer": "0.0.0", - "@stdlib/constants": "0.0.0", - "@stdlib/math": "0.0.0", - "@stdlib/utils": "0.0.0", - "@stdlib/bigint": "0.0.0", - "@stdlib/complex": "0.0.0", - "@stdlib/number": "0.0.0", - "@stdlib/string": "0.0.0" + "@stdlib/array": "^0.0.x", + "@stdlib/assert": "^0.0.x", + "@stdlib/bigint": "^0.0.x", + "@stdlib/buffer": "^0.0.x", + "@stdlib/complex": "^0.0.x", + "@stdlib/constants": "^0.0.x", + "@stdlib/math": "^0.0.x", + "@stdlib/number": "^0.0.x", + "@stdlib/string": "^0.0.x", + "@stdlib/types": "^0.0.x", + "@stdlib/utils": "^0.0.x" + }, + "devDependencies": { + "@stdlib/bench": "^0.0.x", + "@stdlib/blas": "^0.0.x", + "@stdlib/random": "^0.0.x", + "proxyquire": "^2.0.0", + "tape": "git+https://github.com/kgryte/tape.git#fix/globby", + "istanbul": "^0.4.1", + "tap-spec": "5.x.x" }, - "devDependencies": {}, "engines": { "node": ">=0.10.0", "npm": ">2.7.0" @@ -74,5 +88,9 @@ "namespace", "ns" ], - "__stdlib__": {} -} \ No newline at end of file + "__stdlib__": {}, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/athan" + } +} diff --git a/promotion-rules/benchmark/benchmark.js b/promotion-rules/benchmark/benchmark.js new file mode 100644 index 00000000..9a4cd17a --- /dev/null +++ b/promotion-rules/benchmark/benchmark.js @@ -0,0 +1,77 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var promotionRules = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = promotionRules(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::dtypes', function benchmark( b ) { + var out; + var dt; + var N; + var i; + var j; + var k; + + dt = dtypes(); + N = dt.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + j = i % N; + k = (i+1) % N; + out = promotionRules( dt[ j ], dt[ k ] ); + if ( typeof out !== 'string' && out !== -1 ) { + b.fail( 'should return a string or -1' ); + } + } + b.toc(); + if ( !isString( out ) && out !== -1 ) { + b.fail( 'should return a string or -1' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/promotion-rules/examples/index.js b/promotion-rules/examples/index.js new file mode 100644 index 00000000..c7da81ae --- /dev/null +++ b/promotion-rules/examples/index.js @@ -0,0 +1,42 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var promotionRules = require( './../lib' ); + +var DTYPES; +var dt1; +var dt2; +var dt; +var i; +var j; + +// Get the list of supported ndarray data types: +DTYPES = dtypes(); + +// Print the promotion rule for each pair of ndarray data types... +for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + dt = promotionRules( dt1, dt2 ); + console.log( '(%s, %s) => %s', dt1, dt2, dt ); + } +} diff --git a/promotion-rules/test/test.js b/promotion-rules/test/test.js new file mode 100644 index 00000000..7982e535 --- /dev/null +++ b/promotion-rules/test/test.js @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isObject = require( '@stdlib/assert/is-plain-object' ); +var promotionRules = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof promotionRules, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if not provided data types, the function returns a table', function test( t ) { + var out = promotionRules(); + t.strictEqual( isObject( out ), true, 'returns an object' ); + t.strictEqual( out[ 'float32' ][ 'uint32' ], 'float64', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the ndarray data type with the smallest size and closest "kind" to which ndarray data types can be safely cast', function test( t ) { + var table; + var dt1; + var dt2; + var dt; + var j; + var i; + + table = promotionRules(); + + for ( i = 0; i < DTYPES.length; i++ ) { + dt1 = DTYPES[ i ]; + for ( j = 0; j < DTYPES.length; j++ ) { + dt2 = DTYPES[ j ]; + dt = promotionRules( dt1, dt2 ); + t.strictEqual( dt, table[ dt1 ][ dt2 ], 'returns expected value when provided ('+dt1+','+dt2+')' ); + } + } + t.end(); +}); + +tape( 'if provided an unrecognized or unsupported data type, the function returns `null`', function test( t ) { + var values; + var i; + var j; + + values = [ + 'beep', + 'boop', + 'foo', + 'bar', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( promotionRules( values[ i ], 'generic' ), null, 'returns expected value when provided '+values[ i ] ); + t.strictEqual( promotionRules( 'generic', values[ i ] ), null, 'returns expected value when provided '+values[ i ] ); + + j = (i+1) % values.length; + t.strictEqual( promotionRules( values[ i ], values[ j ] ), null, 'returns expected value when provided ('+values[ i ]+','+values[ j ]+')' ); + } + t.end(); +}); diff --git a/safe-casts/benchmark/benchmark.js b/safe-casts/benchmark/benchmark.js new file mode 100644 index 00000000..fb6aa6b5 --- /dev/null +++ b/safe-casts/benchmark/benchmark.js @@ -0,0 +1,71 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var safeCasts = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = safeCasts(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::dtype', function benchmark( b ) { + var out; + var dt; + var i; + + dt = dtypes(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = safeCasts( dt[ i%dt.length ] ); + if ( out.length === 0 ) { + b.fail( 'should not be empty' ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/safe-casts/examples/index.js b/safe-casts/examples/index.js new file mode 100644 index 00000000..d8974628 --- /dev/null +++ b/safe-casts/examples/index.js @@ -0,0 +1,35 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var safeCasts = require( './../lib' ); + +var DTYPES; +var list; +var i; + +// Get the list of supported ndarray data types: +DTYPES = dtypes(); + +// Print the list of ndarray data types to which a data type can be safely cast... +for ( i = 0; i < DTYPES.length; i++ ) { + list = safeCasts( DTYPES[ i ] ); + console.log( '%s: %s', DTYPES[ i ], list.join( ', ' ) ); +} diff --git a/safe-casts/test/test.js b/safe-casts/test/test.js new file mode 100644 index 00000000..4d223686 --- /dev/null +++ b/safe-casts/test/test.js @@ -0,0 +1,75 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var safeCasts = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof safeCasts, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if not provided a data type, the function returns a table', function test( t ) { + var out = safeCasts(); + t.strictEqual( typeof out, 'object', 'returns an object' ); + t.strictEqual( out[ 'float32' ][ 'float64' ], 1, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns a list of ndarray data types to which a provided ndarray data type can be safely cast', function test( t ) { + var list; + var i; + for ( i = 0; i < DTYPES.length; i++ ) { + list = safeCasts( DTYPES[ i ] ); + t.strictEqual( isStringArray( list ), true, 'returns an array of strings when provided '+DTYPES[ i ] ); + } + t.end(); +}); + +tape( 'if provided an unrecognized or unsupported data type, the function returns `null`', function test( t ) { + var values; + var i; + + values = [ + 'beep', + 'boop', + 'foo', + 'bar', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( safeCasts( values[ i ] ), null, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/same-kind-casts/benchmark/benchmark.js b/same-kind-casts/benchmark/benchmark.js new file mode 100644 index 00000000..27daa008 --- /dev/null +++ b/same-kind-casts/benchmark/benchmark.js @@ -0,0 +1,71 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var pkg = require( './../package.json' ).name; +var sameKindCasts = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = sameKindCasts(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::dtype', function benchmark( b ) { + var out; + var dt; + var i; + + dt = dtypes(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = sameKindCasts( dt[ i%dt.length ] ); + if ( out.length === 0 ) { + b.fail( 'should not be empty' ); + } + } + b.toc(); + if ( !isStringArray( out ) ) { + b.fail( 'should return an array of strings' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/same-kind-casts/examples/index.js b/same-kind-casts/examples/index.js new file mode 100644 index 00000000..537095b9 --- /dev/null +++ b/same-kind-casts/examples/index.js @@ -0,0 +1,35 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var sameKindCasts = require( './../lib' ); + +var DTYPES; +var list; +var i; + +// Get the list of supported ndarray data types: +DTYPES = dtypes(); + +// Print the list of ndarray data types to which a data type can be cast... +for ( i = 0; i < DTYPES.length; i++ ) { + list = sameKindCasts( DTYPES[ i ] ); + console.log( '%s: %s', DTYPES[ i ], list.join( ', ' ) ); +} diff --git a/same-kind-casts/test/test.js b/same-kind-casts/test/test.js new file mode 100644 index 00000000..0cb36bd4 --- /dev/null +++ b/same-kind-casts/test/test.js @@ -0,0 +1,76 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var sameKindCasts = require( './../lib' ); + + +// VARIABLES // + +var DTYPES = dtypes(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof sameKindCasts, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if not provided a data type, the function returns a table', function test( t ) { + var out = sameKindCasts(); + t.strictEqual( typeof out, 'object', 'returns an object' ); + t.strictEqual( out[ 'float32' ][ 'float64' ], 1, 'returns expected value' ); + t.strictEqual( out[ 'float32' ][ 'int8' ], 0, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns a list of ndarray data types to which a provided ndarray data type can be safely cast or cast within the same "kind"', function test( t ) { + var list; + var i; + for ( i = 0; i < DTYPES.length; i++ ) { + list = sameKindCasts( DTYPES[ i ] ); + t.strictEqual( isStringArray( list ), true, 'returns an array of strings when provided '+DTYPES[ i ] ); + } + t.end(); +}); + +tape( 'if provided an unrecognized or unsupported data type, the function returns `null`', function test( t ) { + var values; + var i; + + values = [ + 'beep', + 'boop', + 'foo', + 'bar', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( sameKindCasts( values[ i ] ), null, 'returns expected value when provided '+values[ i ] ); + } + t.end(); +}); diff --git a/sub2ind/benchmark/benchmark.js b/sub2ind/benchmark/benchmark.js new file mode 100644 index 00000000..8df6b20d --- /dev/null +++ b/sub2ind/benchmark/benchmark.js @@ -0,0 +1,482 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var sub2ind = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var shape; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, s0, s1, s2 ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=throw', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': 'throw' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[throw]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'throw' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=wrap', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': 'wrap' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*100.0 ) - 50.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'wrap' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*100.0 ) - 50.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=clamp', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': 'clamp' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[clamp]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'clamp' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':order=row-major', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'order': 'row-major' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':order=column-major', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'order': 'column-major' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*10.0 ); + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap,clamp]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'wrap', 'clamp' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[clamp,wrap]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'clamp', 'wrap' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap,clamp,clamp]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'wrap', 'clamp', 'clamp' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=[wrap,wrap,clamp]', function benchmark( b ) { + var shape; + var opts; + var out; + var s0; + var s1; + var s2; + var i; + + shape = [ 10, 10, 10 ]; + + s0 = discreteUniform( 0, shape[ 0 ]-1 ); + s1 = discreteUniform( 0, shape[ 1 ]-1 ); + s2 = discreteUniform( 0, shape[ 2 ]-1 ); + + opts = { + 'mode': [ 'wrap', 'wrap', 'clamp' ] + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s2 = floor( randu()*20.0 ) - 5.0; + out = sub2ind( shape, s0, s1, s2, opts ); + if ( out !== out ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isInteger( out ) ) { + b.fail( 'should return an integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/sub2ind/benchmark/julia/REQUIRE b/sub2ind/benchmark/julia/REQUIRE new file mode 100644 index 00000000..98645e19 --- /dev/null +++ b/sub2ind/benchmark/julia/REQUIRE @@ -0,0 +1,2 @@ +julia 1.5 +BenchmarkTools 0.5.0 diff --git a/sub2ind/benchmark/julia/benchmark.jl b/sub2ind/benchmark/julia/benchmark.jl new file mode 100644 index 00000000..a385ef11 --- /dev/null +++ b/sub2ind/benchmark/julia/benchmark.jl @@ -0,0 +1,144 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +import BenchmarkTools +using Printf + +# Benchmark variables: +name = "sub2ind"; +repeats = 3; + +""" + print_version() + +Prints the TAP version. + +# Examples + +``` julia +julia> print_version() +``` +""" +function print_version() + @printf( "TAP version 13\n" ); +end + +""" + print_summary( total, passing ) + +Print the benchmark summary. + +# Arguments + +* `total`: total number of tests +* `passing`: number of passing tests + +# Examples + +``` julia +julia> print_summary( 3, 3 ) +``` +""" +function print_summary( total, passing ) + @printf( "#\n" ); + @printf( "1..%d\n", total ); # TAP plan + @printf( "# total %d\n", total ); + @printf( "# pass %d\n", passing ); + @printf( "#\n" ); + @printf( "# ok\n" ); +end + +""" + print_results( iterations, elapsed ) + +Print benchmark results. + +# Arguments + +* `iterations`: number of iterations +* `elapsed`: elapsed time (in seconds) + +# Examples + +``` julia +julia> print_results( 1000000, 0.131009101868 ) +``` +""" +function print_results( iterations, elapsed ) + rate = iterations / elapsed + + @printf( " ---\n" ); + @printf( " iterations: %d\n", iterations ); + @printf( " elapsed: %0.9f\n", elapsed ); + @printf( " rate: %0.9f\n", rate ); + @printf( " ...\n" ); +end + +""" + benchmark() + +Run a benchmark. + +# Notes + +* Benchmark results are returned as a two-element array: [ iterations, elapsed ]. +* The number of iterations is not the true number of iterations. Instead, an 'iteration' is defined as a 'sample', which is a computed estimate for a single evaluation. +* The elapsed time is in seconds. + +# Examples + +``` julia +julia> out = benchmark(); +``` +""" +function benchmark() + t = BenchmarkTools.@benchmark Base._sub2ind( (10,10,10), 9, 8, Int32( floor( rand()*10.0 ) ) ) samples=1e6 + + # Compute the total "elapsed" time and convert from nanoseconds to seconds: + s = sum( t.times ) / 1.0e9; + + # Determine the number of "iterations": + iter = length( t.times ); + + # Return the results: + [ iter, s ]; +end + +""" + main() + +Run benchmarks. + +# Examples + +``` julia +julia> main(); +``` +""" +function main() + print_version(); + for i in 1:repeats + @printf( "# julia::%s\n", name ); + results = benchmark(); + print_results( results[ 1 ], results[ 2 ] ); + @printf( "ok %d benchmark finished\n", i ); + end + print_summary( repeats, repeats ); +end + +main(); diff --git a/sub2ind/benchmark/python/numpy/benchmark.py b/sub2ind/benchmark/python/numpy/benchmark.py new file mode 100644 index 00000000..f08b8fae --- /dev/null +++ b/sub2ind/benchmark/python/numpy/benchmark.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# +# @license Apache-2.0 +# +# Copyright (c) 2018 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. + +"""Benchmark numpy.ravel_multi_index.""" + +from __future__ import print_function +import timeit + +NAME = "sub2ind" +REPEATS = 3 +ITERATIONS = 1000000 + + +def print_version(): + """Print the TAP version.""" + print("TAP version 13") + + +def print_summary(total, passing): + """Print the benchmark summary. + + # Arguments + + * `total`: total number of tests + * `passing`: number of passing tests + + """ + print("#") + print("1.." + str(total)) # TAP plan + print("# total " + str(total)) + print("# pass " + str(passing)) + print("#") + print("# ok") + + +def print_results(elapsed): + """Print benchmark results. + + # Arguments + + * `elapsed`: elapsed time (in seconds) + + # Examples + + ``` python + python> print_results(0.131009101868) + ``` + """ + rate = ITERATIONS / elapsed + + print(" ---") + print(" iterations: " + str(ITERATIONS)) + print(" elapsed: " + str(elapsed)) + print(" rate: " + str(rate)) + print(" ...") + + +def benchmark(): + """Run the benchmark and print benchmark results.""" + setup = "import numpy as np; from random import random;" + stmt = "y = np.ravel_multi_index((9, 8, int(random()*10.0)), (10, 10, 10))" + + t = timeit.Timer(stmt, setup=setup) + + print_version() + + for i in range(REPEATS): + print("# python::numpy::" + NAME) + elapsed = t.timeit(number=ITERATIONS) + print_results(elapsed) + print("ok " + str(i+1) + " benchmark finished") + + print_summary(REPEATS, REPEATS) + + +def main(): + """Run the benchmark.""" + benchmark() + + +if __name__ == "__main__": + main() diff --git a/sub2ind/examples/index.js b/sub2ind/examples/index.js new file mode 100644 index 00000000..3f0bddd2 --- /dev/null +++ b/sub2ind/examples/index.js @@ -0,0 +1,62 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var numel = require( '@stdlib/ndarray/base/numel' ); +var sub2ind = require( './../lib' ); + +var shape = [ 3, 3, 3 ]; +var len = numel( shape ); + +var arr = []; +var i; +for ( i = 0; i < len; i++ ) { + arr.push( i ); +} + +var opts = { + 'order': 'column-major' +}; + +console.log( '' ); +console.log( 'Dimensions: %s.', shape.join( 'x' ) ); +console.log( 'View:' ); +console.log( '' ); + +var slice; +var idx; +var row; +var j; +var k; +for ( k = 0; k < shape[ 2 ]; k++ ) { + slice = 'A[:,:,'+k+'] = '; + console.log( slice ); + for ( i = 0; i < shape[ 0 ]; i++ ) { + row = ' '; + for ( j = 0; j < shape[ 1 ]; j++ ) { + idx = sub2ind( shape, i, j, k, opts ); + row += arr[ idx ]; + if ( j < shape[ 1 ]-1 ) { + row += ', '; + } + } + console.log( row ); + } + console.log( '' ); +} diff --git a/sub2ind/test/test.js b/sub2ind/test/test.js new file mode 100644 index 00000000..3b0c7e8d --- /dev/null +++ b/sub2ind/test/test.js @@ -0,0 +1,536 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var sub2ind = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof sub2ind, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided an array-like object containing nonnegative integers as the first argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + [ 1, 2, null ], + [ 1, 2, 3.14 ], + [ 1, 2, NaN ], + [ 1, 2, '3' ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( value, 0, 0, 0 ); + }; + } +}); + +tape( 'the function throws an error if provided a subscript argument which is not an integer value', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], value, 0, 0 ); + }; + } +}); + +tape( 'the function throws an error if provided a subscript argument which is not an integer value', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], 0, value, 0 ); + }; + } +}); + +tape( 'the function throws an error if provided a subscript argument which is not an integer value', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], 0, 0, value ); + }; + } +}); + +tape( 'the function throws an error if provided a subscript argument which is not an integer value (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], value, 0, 0, {} ); + }; + } +}); + +tape( 'the function throws an error if provided a subscript argument which is not an integer value (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], 0, value, 0, {} ); + }; + } +}); + +tape( 'the function throws an error if provided a subscript argument which is not an integer value (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + -0.14, + 0.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], 0, 0, value, {} ); + }; + } +}); + +tape( 'the function throws an error if not provided an object for the options argument', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + sub2ind( [ 3, 3, 3 ], 0, 0, 0, value ); + }; + } +}); + +tape( 'the function throws an error if provided an invalid option', function test( t ) { + var values; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 'clips', + 'throws', + 'wraps', + 'clamps', + 'clip', + 5, + NaN, + true, + false, + null, + void 0, + [], + [ 'wrap', 'clamp', 'throw', 'foo' ], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var opts = { + 'mode': value + }; + sub2ind( [ 3, 3, 3 ], 0, 0, 0, opts ); + }; + } +}); + +tape( 'the function throws an error if provided fewer subscripts than array dimensions', function test( t ) { + t.throws( foo, RangeError, 'throws an error' ); + t.end(); + + function foo() { + sub2ind( [ 3, 3, 3 ], 0, 0 ); + } +}); + +tape( 'the function throws an error if provided more subscripts than array dimensions', function test( t ) { + t.throws( foo, RangeError, 'throws an error' ); + t.throws( bar, TypeError, 'throws an error' ); + t.end(); + + function foo() { + sub2ind( [ 3, 3, 3 ], 0, 0, 0, 0, {} ); + } + + function bar() { + sub2ind( [ 3, 3, 3 ], 0, 0, 0, 0 ); + } +}); + +tape( 'the function converts subscripts to a linear index (2d)', function test( t ) { + var shape; + var idx; + + shape = [ 2, 2 ]; + + idx = sub2ind( shape, 0, 0 ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, 0, 1 ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, 1, 0 ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 1, 1 ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (3d)', function test( t ) { + var shape; + var idx; + + shape = [ 3, 3, 3 ]; + + idx = sub2ind( shape, 1, 2, 2 ); + t.strictEqual( idx, 17, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (row-major)', function test( t ) { + var shape; + var opts; + var idx; + + shape = [ 2, 2 ]; + opts = { + 'order': 'row-major' + }; + + idx = sub2ind( shape, 0, 0, opts ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, 0, 1, opts ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, 1, 0, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 1, 1, opts ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function converts subscripts to a linear index (column-major)', function test( t ) { + var shape; + var opts; + var idx; + + shape = [ 2, 2 ]; + opts = { + 'order': 'column-major' + }; + + idx = sub2ind( shape, 0, 0, opts ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, 0, 1, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 1, 0, opts ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, 1, 1, opts ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a subscript which exceeds array dimensions (default)', function test( t ) { + var shape = [ 2, 2 ]; + + t.throws( foo, RangeError, 'throws a range error' ); + t.throws( bar, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + sub2ind( shape, 999999, 1 ); + } + + function bar() { + sub2ind( shape, 1, 999999 ); + } +}); + +tape( 'if the `mode` is `throw`, the function throws if provided a subscript which exceeds array dimensions (option)', function test( t ) { + var shape; + var opts; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'throw' + }; + + t.throws( foo, RangeError, 'throws a range error' ); + t.throws( bar, RangeError, 'throws a range error' ); + + t.end(); + + function foo() { + sub2ind( shape, 999999, 1, opts ); + } + + function bar() { + sub2ind( shape, 1, 999999, opts ); + } +}); + +tape( 'if the `mode` is `wrap`, the function wraps subscripts which exceed array dimensions', function test( t ) { + var shape; + var opts; + var idx; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'wrap' + }; + + idx = sub2ind( shape, 1, 0, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 2, 0, opts ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, 0, 3, opts ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, -1, 0, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, -3, 0, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 1, 5, opts ); + t.strictEqual( idx, 3, 'returns expected value' ); + + idx = sub2ind( shape, 1, 4, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 1, -4, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'if the `mode` is `clamp`, the function clamps subscripts which exceed array dimensions', function test( t ) { + var shape; + var opts; + var idx; + + shape = [ 2, 2 ]; + opts = { + 'mode': 'clamp' + }; + + idx = sub2ind( shape, 1, 0, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 2, 0, opts ); + t.strictEqual( idx, 2, 'returns expected value' ); + + idx = sub2ind( shape, 0, 3, opts ); + t.strictEqual( idx, 1, 'returns expected value' ); + + idx = sub2ind( shape, -3, 0, opts ); + t.strictEqual( idx, 0, 'returns expected value' ); + + idx = sub2ind( shape, 1, 5, opts ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function supports providing mixed modes', function test( t ) { + var shape; + var opts; + var idx; + + shape = [ 2, 2, 2 ]; + opts = { + 'mode': [ 'wrap', 'clamp' ] + }; + + idx = sub2ind( shape, -2, 10, -1, opts ); + t.strictEqual( idx, 3, 'returns expected value' ); + + t.end(); +}); diff --git a/sub2ind/test/test.validate.js b/sub2ind/test/test.validate.js new file mode 100644 index 00000000..c03e1cc5 --- /dev/null +++ b/sub2ind/test/test.validate.js @@ -0,0 +1,186 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var validate = require( './../lib/validate.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof validate, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an error if provided an `options` argument which is not an object', function test( t ) { + var values; + var err; + var i; + + values = [ + '5', + 5, + true, + false, + void 0, + null, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + err = validate( {}, values[ i ] ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an unsupported/unrecognized `order` option', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 5, + true, + false, + void 0, + null, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'order': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an unsupported/unrecognized `mode` option', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 'beep', + 'boop', + 'foo', + 'bar', + 'throws', + 'clips', + 'clip', + 5, + true, + false, + void 0, + null, + NaN, + [], + [ 'wrap', 'clamp', 'throw', 'foo' ], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'mode': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns `null` if all options are valid (mode string)', function test( t ) { + var expected; + var options; + var opts; + var err; + + opts = {}; + options = { + 'mode': 'wrap', + 'order': 'column-major' + }; + expected = { + 'mode': [ 'wrap' ], + 'order': 'column-major' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, expected, 'sets options' ); + + t.end(); +}); + +tape( 'the function returns `null` if all options are valid (mode array)', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'mode': [ 'wrap', 'clamp', 'throw' ], + 'order': 'column-major' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, options, 'sets options' ); + + t.end(); +}); + +tape( 'the function will ignore unrecognized options', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'beep': true, + 'boop': 'bop' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, {}, 'ignores unrecognized options' ); + + t.end(); +}); diff --git a/test/test.js b/test/test.js new file mode 100644 index 00000000..14dda1f7 --- /dev/null +++ b/test/test.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var objectKeys = require( '@stdlib/utils/keys' ); +var ns = require( './../lib' ); + + +// TESTS // + +tape( 'main export is an object', function test( t ) { + t.ok( true, __filename ); + t.equal( typeof ns, 'object', 'main export is an object' ); + t.end(); +}); + +tape( 'the exported object contains key-value pairs', function test( t ) { + var keys = objectKeys( ns ); + t.equal( keys.length > 0, true, 'has keys' ); + t.end(); +});