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
-
-
-
-
-
-
-
----
+* * *
-> 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].
+[npm-image]: http://img.shields.io/npm/v/@stdlib/ndarray.svg
+[npm-url]: https://npmjs.org/package/@stdlib/ndarray
+
+[test-image]: https://github.com/stdlib-js/ndarray/actions/workflows/test.yml/badge.svg
+[test-url]: https://github.com/stdlib-js/ndarray/actions/workflows/test.yml
+
+[coverage-image]: https://img.shields.io/codecov/c/github/stdlib-js/ndarray/main.svg
+[coverage-url]: https://codecov.io/github/stdlib-js/ndarray?branch=main
+
+[dependencies-image]: https://img.shields.io/david/stdlib-js/ndarray
+[dependencies-url]: https://david-dm.org/stdlib-js/ndarray/main
+
[stdlib]: https://github.com/stdlib-js/stdlib
[stdlib-authors]: https://github.com/stdlib-js/stdlib/graphs/contributors
diff --git a/array/README.md b/array/README.md
index d15cd8f8..ed752a8c 100644
--- a/array/README.md
+++ b/array/README.md
@@ -251,11 +251,11 @@ str = JSON.stringify( arr.toJSON() );
[@stdlib/ndarray/ctor]: https://github.com/stdlib-js/ndarray/tree/main/ctor
-[@stdlib/array/generic]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/generic
+[@stdlib/array/generic]: https://github.com/stdlib-js/array-generic
-[@stdlib/array/typed]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/typed
+[@stdlib/array/typed]: https://github.com/stdlib-js/array-typed
-[@stdlib/buffer/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/buffer/ctor
+[@stdlib/buffer/ctor]: https://github.com/stdlib-js/buffer-ctor
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