diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..c66ad55
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,154 @@
+#/
+# @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.
+#/
+
+# EditorConfig configuration file (see ).
+
+# Indicate that this file is a root-level configuration file:
+root = true
+
+# Set properties for all files:
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+# Set properties for JavaScript files:
+[*.js]
+indent_style = tab
+
+# Set properties for TypeScript files:
+[*.ts]
+indent_style = tab
+
+# Set properties for Python files:
+[*.py]
+indent_style = space
+indent_size = 4
+
+# Set properties for Julia files:
+[*.jl]
+indent_style = tab
+
+# Set properties for R files:
+[*.R]
+indent_style = tab
+
+# Set properties for C files:
+[*.c]
+indent_style = tab
+
+# Set properties for C header files:
+[*.h]
+indent_style = tab
+
+# Set properties for C++ files:
+[*.cpp]
+indent_style = tab
+
+# Set properties for C++ header files:
+[*.hpp]
+indent_style = tab
+
+# Set properties for Fortran files:
+[*.f]
+indent_style = space
+indent_size = 2
+insert_final_newline = false
+
+# Set properties for shell files:
+[*.sh]
+indent_style = tab
+
+# Set properties for AWK files:
+[*.awk]
+indent_style = tab
+
+# Set properties for HTML files:
+[*.html]
+indent_style = tab
+tab_width = 2
+
+# Set properties for CSS files:
+[*.css]
+indent_style = tab
+
+# Set properties for Makefiles:
+[Makefile]
+indent_style = tab
+
+[*.mk]
+indent_style = tab
+
+# Set properties for Markdown files:
+[*.md]
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = false
+
+# Set properties for `usage.txt` files:
+[usage.txt]
+indent_style = space
+indent_size = 2
+
+# Set properties for `repl.txt` files:
+[repl.txt]
+indent_style = space
+indent_size = 4
+
+# Set properties for `package.json` files:
+[package.json]
+indent_style = space
+indent_size = 2
+
+# Set properties for `datapackage.json` files:
+[datapackage.json]
+indent_style = space
+indent_size = 2
+
+# Set properties for `tslint.json` files:
+[tslint.json]
+indent_style = space
+indent_size = 2
+
+# Set properties for `tsconfig.json` files:
+[tsconfig.json]
+indent_style = space
+indent_size = 2
+
+# Set properties for LaTeX files:
+[*.tex]
+indent_style = tab
+
+# Set properties for LaTeX Bibliography files:
+[*.bib]
+indent_style = tab
+
+# Set properties for YAML files:
+[*.yml]
+indent_style = space
+indent_size = 2
+
+# Set properties for GYP files:
+[binding.gyp]
+indent_style = space
+indent_size = 2
+
+[*.gypi]
+indent_style = space
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..7212d81
--- /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 0000000..e7327d4
--- /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/stats/base/smaxabs) 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/benchmark.yml b/.github/workflows/benchmark.yml
new file mode 100644
index 0000000..e51e34e
--- /dev/null
+++ b/.github/workflows/benchmark.yml
@@ -0,0 +1,19 @@
+name: benchmark
+
+on:
+ workflow_dispatch:
+
+jobs:
+ benchmark:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v1
+ with:
+ node-version: 15
+ - name: Install production and development dependencies
+ run: |
+ npm install
+ - name: Run benchmarks
+ run: |
+ npm run benchmark
diff --git a/.github/workflows/close_pull_requests.yml b/.github/workflows/close_pull_requests.yml
new file mode 100644
index 0000000..3cd2ea0
--- /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/stats/base/smaxabs) 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 0000000..0c19f10
--- /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: 15
+ - name: Install production and development dependencies
+ run: |
+ npm install
+ - name: Run examples
+ run: |
+ npm run examples
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..ae05f51
--- /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: 15
+ - name: Increment version
+ run: |
+ git config --local user.email "noreply@stdlib.io"
+ git config --local user.name "stdlib-bot"
+ npm version patch
+ - 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()
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..3c99108
--- /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: 15
+ - 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()
diff --git a/.github/workflows/test_coverage.yml b/.github/workflows/test_coverage.yml
new file mode 100644
index 0000000..0e8045d
--- /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: 15
+ - 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
diff --git a/.github/workflows/test_install.yml b/.github/workflows/test_install.yml
new file mode 100644
index 0000000..ee70831
--- /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: 15
+ - 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()
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1475963
--- /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
new file mode 100644
index 0000000..401aa76
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,225 @@
+#/
+# @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 #
+#########
+CODE_OF_CONDUCT.md
+CONTRIBUTING.md
+CONTRIBUTORS
+TODO.md
+ROADMAP.md
+.postinstall.json
+
+# Directories #
+###############
+.circleci/
+.github/
+**/benchmark/
+**/build/
+**/examples/
+reports/
+support/
+**/tmp/
+workshops/
+
+# Ignore test directories, except for testing dependency installation:
+**/test/
+!/deps/test/
+
+# Only top-level directories:
+/etc/
+/docs/
+
+# 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 #
+############
+*.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 #
+###########
+.npmignore
+
+# Only top-level node_modules:
+/node_modules/
+
+# TypeScript #
+##############
+tsconfig.json
+tslint.json
+*.tsbuildinfo
+
+# Matlab #
+##########
+*.asv
+*.mex*
+
+# Fortran #
+###########
+*.mod
+
+# R #
+#####
+.Rhistory
+.Rapp.history
+.Rproj.user/
+
+# Python #
+##########
+__pycache__/
+*.py[cod]
+*$py.class
+*.egg-info/
+.ipynb_checkpoints
+setup.cfg
+setup.py
+
+# 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
+
+# Git #
+#######
+.git*
+.mailmap
+
+# Visual Studio #
+#################
+.vscode/
+jsconfig.json
+
+# Utilities #
+#############
+.jshintrc
+.jshintignore
+.eslintrc*
+.eslintignore
+
+.pylintrc
+.pycodestyle
+.pydocstyle
+
+.travis.yml
+circle.yml
+appveyor.yml
+azure-pipelines.yml
+
+.editorconfig
+.codeclimate.yml
+.codecov.yml
+
+.rtlintrc
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..36f5bef
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,28 @@
+#/
+# @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 for [npm][1].
+#
+# [1]: https://docs.npmjs.com/files/npmrc
+
+# Disable the creation of a lock file:
+package-lock = false
+shrinkwrap = false
+
+# Disable automatically "saving" dependencies on install:
+save = false
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..35b70c9
--- /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.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..5f59443
--- /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.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 0000000..da469e5
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,24 @@
+# This file is generated by tools/scripts/update_contributors.
+#
+# Contributors listed in alphabetical order.
+
+Athan Reines
+Brendan Graetz
+Bruno Fenzl
+Christopher Dambamuromo
+Dominik Moritz
+Frank Kovacs
+James
+Jithin KS
+Joey Reed
+Joris Labie
+Justin Dennison
+Marcus
+Matt Cochrane
+Milan Raj
+Ognjen Jevremović
+Philipp Burckhardt
+Ricky Reusser
+Ryan Seal
+Shraddheya Shendre
+rei2hu
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..fcc9934
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,481 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by this
+license (the "Software") to use, reproduce, display, distribute, execute, and
+transmit the Software, and to prepare derivative works of the Software, and to
+permit third-parties to whom the Software is furnished to do so, all subject to
+the following:
+
+The copyright notices in the Software and this entire statement, including the
+above license grant, this restriction and the following disclaimer, must be
+included in all copies of the Software, in whole or in part, and all derivative
+works of the Software, unless such copies or derivative works are solely in the
+form of machine-executable object code generated by a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES
+OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+
+DEPENDENCIES
+
+The library links against the following external libraries, which have their own
+licenses:
+
+* OpenBLAS
+
+Copyright (c) 2011-2014, The OpenBLAS Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. Neither the name of the OpenBLAS project nor the names of
+ its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+* Electron
+
+Copyright (c) 2013-2017 GitHub Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+* Boost
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+
+* Cephes
+
+Copyright (c) 1984-2000 Stephen L. Moshier
+
+Some software in this archive may be from the book _Methods and Programs for
+Mathematical Functions_ (Prentice-Hall or Simon & Schuster International, 1989)
+or from the Cephes Mathematical Library, a commercial product. In either event,
+it is copyrighted by the author. What you see here may be used freely but it
+comes with no support or guarantee.
+
+Stephen L. Moshier
+moshier@na-net.ornl.gov
+
+
+
+ATTRIBUTION
+
+The library contains implementations from the following external libraries,
+which have their own licenses:
+
+* FreeBSD
+
+Copyright (C) 1993-2004 by Sun Microsystems, Inc. All rights reserved.
+
+Developed at SunPro, a Sun Microsystems, Inc. business.
+Permission to use, copy, modify, and distribute this
+software is freely granted, provided that this notice
+is preserved.
+
+
+* FDLIBM
+
+Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+
+Developed at SunPro, a Sun Microsystems, Inc. business.
+Permission to use, copy, modify, and distribute this
+software is freely granted, provided that this notice
+is preserved.
+
+
+* Go
+
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+* SLATEC Common Mathematical Library
+
+Public domain.
+
+
+* ESLint
+
+Copyright JS Foundation and other contributors, https://js.foundation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+* StatsFuns.jl
+
+Copyright (c) 2015: Dahua Lin.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+* SpecialFunctions.jl
+
+The MIT License (MIT)
+
+Copyright (c) 2017 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and others:
+
+https://github.com/JuliaMath/SpecialFunctions.jl/graphs/contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+* MT19937
+
+Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1c7d53e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,534 @@
+#/
+# @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.
+#/
+
+# USER VARIABLES #
+
+ifndef VERBOSE
+ QUIET := @
+else
+ QUIET :=
+endif
+
+# Indicate whether to "fast" fail when linting, running tests, etc:
+ifndef FAST_FAIL
+ FAIL_FAST := true
+else
+ifeq ($(FAST_FAIL), 0)
+ FAIL_FAST := false
+else
+ FAIL_FAST := true
+endif
+endif
+
+# Define the `NODE_PATH` environment variable:
+NODE_PATH ?=
+
+# Define the `NODE_ENV` environment variable:
+NODE_ENV ?=
+
+
+# INTERNAL VARIABLES #
+
+# Instruct make to warn us when we use an undefined variable (e.g., misspellings).
+MAKEFLAGS += --warn-undefined-variables
+
+# Define the default target:
+.DEFAULT_GOAL := all
+
+# Define the `SHELL` variable to avoid issues on systems where the variable may be inherited from the environment.
+#
+# ## Notes
+#
+# - We use `bash` so that we can use `pipefail`.
+#
+#
+# [1]: https://www.gnu.org/prep/standards/html_node/Makefile-Basics.html#Makefile-Basics
+# [2]: http://clarkgrubb.com/makefile-style-guide
+SHELL := bash
+
+# Define shell flags.
+#
+# ## Notes
+#
+# - `.SHELLFLAGS` was introduced in GNU Make 3.82 and has no effect on the version of GNU Make installed on Mac OS X, which is 3.81.
+# - The `-e` flag causes `bash` to exit immediately if a `bash` executed command fails.
+# - The `-u` flag causes `bash` to exit with an error message if a variable is accessed without being defined.
+# - The `pipefail` option specifies that, if any of the commands in a pipeline fail, the entire pipeline fails. Otherwise the return value of a pipeline is the return value of the last command.
+# - The `-c` flag is in the default value of `.SHELLFLAGS`, which must be preserved, as this is how `make` passes the script to be executed to `bash`.
+#
+.SHELLFLAGS := -eu -o pipefail -c
+
+# Remove targets if its recipe fails.
+#
+# ## Notes
+#
+# - Mentioning this target anywhere in a Makefile prevents a user from re-running make and using an incomplete or invalid target.
+# - When debugging, it may be necessary to comment this line out so the incomplete or invalid target can be inspected.
+#
+# [1]: https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
+.DELETE_ON_ERROR:
+
+# Remove all the default suffixes, preferring to define all rules explicitly.
+#
+# [1]: https://www.gnu.org/software/make/manual/html_node/Suffix-Rules.html#Suffix-Rules
+# [2]: https://www.gnu.org/software/make/manual/html_node/Suffix-Rules.html#Suffix-Rules
+.SUFFIXES:
+
+# 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
+
+# Determine the filename:
+this_file := $(lastword $(MAKEFILE_LIST))
+
+# Determine the absolute path of the Makefile (see http://blog.jgc.org/2007/01/what-makefile-am-i-in.html):
+this_dir := $(dir $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
+
+# Remove the trailing slash:
+this_dir := $(patsubst %/,%,$(this_dir))
+
+# Determine root directory:
+ROOT_DIR = $(this_dir)
+
+# Define the root build directory:
+BUILD_DIR ?= $(ROOT_DIR)/build
+
+# Define the root directory for storing distributable files:
+DIST_DIR ?= $(ROOT_DIR)/dist
+
+# Define the root directory for storing temporary files:
+TMP_DIR ?= $(ROOT_DIR)/tmp
+
+# Define the directories for writing reports, including code coverage:
+REPORTS_DIR ?= $(ROOT_DIR)/reports
+COVERAGE_DIR ?= $(REPORTS_DIR)/coverage
+
+# Define the top-level directory containing node module dependencies:
+NODE_MODULES ?= $(ROOT_DIR)/node_modules
+
+# Define the top-level directory containing node module executables:
+BIN_DIR ?= $(NODE_MODULES)/.bin
+
+# Define the path to the root `package.json`:
+ROOT_PACKAGE_JSON ?= $(ROOT_DIR)/package.json
+
+# Define the folder name convention for source files requiring compilation:
+SRC_FOLDER ?= src
+
+# Define the folder name convention for documentation files:
+DOCUMENTATION_FOLDER ?= docs
+
+# Define the folder name convention for configuration files:
+CONFIG_FOLDER ?= etc
+
+# Define the folder name convention for benchmark files:
+BENCHMARKS_FOLDER ?= benchmark
+
+# Define the folder name convention for benchmark fixtures:
+BENCHMARKS_FIXTURES_FOLDER ?= $(BENCHMARKS_FOLDER)/fixtures
+
+# Define the folder name convention for examples files:
+EXAMPLES_FOLDER ?= examples
+
+# Define the folder name convention for examples fixtures:
+EXAMPLES_FIXTURES_FOLDER ?= $(EXAMPLES_FOLDER)/fixtures
+
+# Define the folder name convention for test files:
+TESTS_FOLDER ?= test
+
+# Define the folder name convention for test fixtures:
+TESTS_FIXTURES_FOLDER ?= $(TESTS_FOLDER)/fixtures
+
+# Define a filepath pattern for benchmark files:
+BENCHMARKS_FILTER ?= .*/.*
+
+# Define a filepath pattern for example files:
+EXAMPLES_FILTER ?= .*/.*
+
+# Define a filepath pattern for test files:
+TESTS_FILTER ?= .*/.*
+
+# Define a filename pattern for benchmark files:
+BENCHMARKS_PATTERN ?= benchmark*.js
+
+# Define a filename pattern for example files:
+EXAMPLES_PATTERN ?= *.js
+
+# Define a filename pattern for test files:
+TESTS_PATTERN ?= test*.js
+
+# Define Node environments:
+ifdef NODE_ENV
+ NODE_ENV_BENCHMARK := $(NODE_ENV)
+ NODE_ENV_EXAMPLES := $(NODE_ENV)
+ NODE_ENV_TEST := $(NODE_ENV)
+else
+ NODE_ENV ?=
+ NODE_ENV_BENCHMARK ?= benchmark
+ NODE_ENV_EXAMPLES ?= examples
+ NODE_ENV_TEST ?= test
+endif
+
+# Define whether delete operations should be safe (i.e., deleted items are sent to trash, rather than permanently deleted):
+SAFE_DELETE ?= false
+
+# Define the delete command:
+ifeq ($(SAFE_DELETE), true)
+ # FIXME: -rm -rf
+ DELETE := -rm
+ DELETE_FLAGS := -rf
+else
+ DELETE ?= -rm
+ DELETE_FLAGS ?= -rf
+endif
+
+# Determine the `open` command:
+ifeq ($(OS), Darwin)
+ OPEN ?= open
+else
+ OPEN ?= xdg-open
+endif
+# TODO: add Windows command
+
+# Define the command for `node`:
+NODE ?= node
+
+# Define the command for `npm`:
+NPM ?= npm
+
+# Define the path to a JavaScript test runner.
+#
+# ## Notes
+#
+# - We reference the `bin` file directly in order to support using `istanbul` for code coverage on Windows (https://github.com/gotwarlost/istanbul#usage-on-windows)
+JAVASCRIPT_TEST ?= $(NODE_MODULES)/tape/bin/tape
+
+# Define any command-line options to use when invoking the test runner:
+JAVASCRIPT_TEST_FLAGS ?=
+
+# Define the path to the executable for parsing TAP output:
+TAP_REPORTER ?= $(BIN_DIR)/tap-spec
+
+# Define the path to the Istanbul executable:
+ISTANBUL ?= $(BIN_DIR)/istanbul
+
+# Define which files and directories to exclude from coverage instrumentation:
+ISTANBUL_EXCLUDES_FLAGS ?= \
+ --no-default-excludes \
+ -x 'node_modules/**' \
+ -x 'reports/**' \
+ -x 'tmp/**' \
+ -x 'deps/**' \
+ -x 'dist/**' \
+ -x "**/$(SRC_FOLDER)/**" \
+ -x "**/$(TESTS_FOLDER)/**" \
+ -x "**/$(EXAMPLES_FOLDER)/**" \
+ -x "**/$(BENCHMARKS_FOLDER)/**" \
+ -x "**/$(CONFIG_FOLDER)/**" \
+ -x "**/$(DOCUMENTATION_FOLDER)/**"
+
+# Define the command to generate test coverage:
+ISTANBUL_COVER ?= $(ISTANBUL) cover
+
+# Define the type of report Istanbul should produce:
+ISTANBUL_COVER_REPORT_FORMAT ?= lcov
+
+# Define the command-line options to be used when generating code coverage:
+ISTANBUL_COVER_FLAGS ?= \
+ $(ISTANBUL_EXCLUDES_FLAGS) \
+ --dir $(COVERAGE_DIR) \
+ --report $(ISTANBUL_COVER_REPORT_FORMAT)
+
+# On Mac OSX, in order to use `|` and other regular expression operators, we need to use enhanced regular expression syntax (-E); see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man7/re_format.7.html#//apple_ref/doc/man/7/re_format.
+ifeq ($(OS), Darwin)
+ find_kernel_prefix := -E
+else
+ find_kernel_prefix :=
+endif
+
+# Common exclude flags that most recipes for finding package files should use (Note: order does matter to some degree):
+FIND_COMMON_EXCLUDE_FLAGS ?= \
+ -not -path "$(ROOT_DIR)/.*" \
+ -not -path "$(NODE_MODULES)/*" \
+ -not -path "$(BUILD_DIR)/*" \
+ -not -path "$(REPORTS_DIR)/*" \
+
+# Define exclusion flags to use when searching for benchmark files:
+FIND_BENCHMARKS_EXCLUDE_FLAGS ?= \
+ $(FIND_COMMON_EXCLUDE_FLAGS) \
+ -not -path "$(ROOT_DIR)/**/$(BENCHMARKS_FIXTURES_FOLDER)/*"
+
+# Define flags for finding benchmark files:
+FIND_BENCHMARKS_FLAGS ?= \
+ -type f \
+ -name "$(BENCHMARKS_PATTERN)" \
+ -path "$(ROOT_DIR)/**/$(BENCHMARKS_FOLDER)/**" \
+ -regex "$(BENCHMARKS_FILTER)" \
+ $(FIND_BENCHMARKS_EXCLUDE_FLAGS)
+
+ifneq ($(OS), Darwin)
+ FIND_BENCHMARKS_FLAGS := -regextype posix-extended $(FIND_BENCHMARKS_FLAGS)
+endif
+
+# Define a command to list benchmark files:
+FIND_BENCHMARKS_CMD ?= find $(find_kernel_prefix) $(ROOT_DIR) $(FIND_BENCHMARKS_FLAGS)
+
+# Define exclusion flags to use when searching for examples files:
+FIND_EXAMPLES_EXCLUDE_FLAGS ?= \
+ $(FIND_COMMON_EXCLUDE_FLAGS) \
+ -not -path "$(ROOT_DIR)/**/$(EXAMPLES_FIXTURES_FOLDER)/*"
+
+# Define flags for finding examples files:
+FIND_EXAMPLES_FLAGS ?= \
+ -type f \
+ -name "$(EXAMPLES_PATTERN)" \
+ -path "$(ROOT_DIR)/**/$(EXAMPLES_FOLDER)/**" \
+ -regex "$(EXAMPLES_FILTER)" \
+ $(FIND_EXAMPLES_EXCLUDE_FLAGS)
+
+ifneq ($(OS), Darwin)
+ FIND_EXAMPLES_FLAGS := -regextype posix-extended $(FIND_EXAMPLES_FLAGS)
+endif
+
+# Define a command to list example files:
+FIND_EXAMPLES_CMD ?= find $(find_kernel_prefix) $(ROOT_DIR) $(FIND_EXAMPLES_FLAGS)
+
+# Define exclusion flags to use when searching for test files:
+FIND_TESTS_EXCLUDE_FLAGS ?= \
+ $(FIND_COMMON_EXCLUDE_FLAGS) \
+ -not -path "$(ROOT_DIR)/**/$(TESTS_FIXTURES_FOLDER)/*"
+
+# Define flags for finding test files:
+FIND_TESTS_FLAGS ?= \
+ -type f \
+ -name "$(TESTS_PATTERN)" \
+ -regex "$(TESTS_FILTER)" \
+ $(FIND_TESTS_EXCLUDE_FLAGS)
+
+ifneq ($(OS), Darwin)
+ FIND_TESTS_FLAGS := -regextype posix-extended $(FIND_TESTS_FLAGS)
+endif
+
+# Define a command to list test files:
+FIND_TESTS_CMD ?= find $(find_kernel_prefix) $(ROOT_DIR) $(FIND_TESTS_FLAGS)
+
+
+# RULES #
+
+#/
+# Default target.
+#
+# @example
+# make
+#
+# @example
+# make all
+#/
+all: help
+
+.PHONY: all
+
+#/
+# Prints a `Makefile` help message.
+#
+# @example
+# make help
+#/
+help:
+ $(QUIET) echo 'Read the Makefile to see the list of available commands.'
+ $(QUIET) echo ''
+
+.PHONY: help
+
+#/
+# Prints the runtime value of a `Makefile` variable.
+#
+# ## Notes
+#
+# - The rule uses the following format:
+#
+# ```bash
+# $ make inspect.
+# ```
+#
+# @example
+# make inspect.ROOT_DIR
+#
+# @example
+# make inspect.CC
+#/
+inspect.%:
+ $(QUIET) echo '$*=$($*)'
+
+#/
+# Runs the project's install sequence.
+#
+# @example
+# make install
+#/
+install:
+ $(NPM) install
+
+.PHONY: install
+
+#/
+# Removes node module dependencies.
+#
+# @example
+# make clean-node
+#/
+clean-node:
+ $(QUIET) $(DELETE) $(DELETE_FLAGS) $(NODE_MODULES)
+
+#/
+# Runs the project's cleanup sequence.
+#
+# @example
+# make clean
+#/
+clean: clean-node clean-cov
+ $(QUIET) $(DELETE) $(DELETE_FLAGS) $(BUILD_DIR)
+ $(QUIET) $(DELETE) $(DELETE_FLAGS) $(REPORTS_DIR)
+
+.PHONY: clean
+
+#/
+# Runs JavaScript benchmarks consecutively.
+#
+# ## Notes
+#
+# - The recipe assumes that benchmark files can be run via Node.js.
+# - This rule is useful when wanting to glob for JavaScript benchmark files (e.g., run all JavaScript benchmarks for a particular package).
+#
+#
+# @param {string} [BENCHMARKS_FILTER] - file path pattern (e.g., `.*/utils/group-by/.*`)
+#
+# @example
+# make benchmark
+#
+# @example
+# make benchmark BENCHMARKS_FILTER=".*/utils/group-by/.*"
+#/
+benchmark: $(NODE_MODULES)
+ $(QUIET) $(FIND_BENCHMARKS_CMD) | grep '^[\/]\|^[a-zA-Z]:[/\]' | while read -r file; do \
+ echo ""; \
+ echo "Running benchmark: $$file"; \
+ NODE_ENV="$(NODE_ENV_BENCHMARK)" \
+ NODE_PATH="$(NODE_PATH)" \
+ $(NODE) $$file || exit 1; \
+ done
+
+.PHONY: benchmark
+
+#/
+# Runs JavaScript examples consecutively.
+#
+# ## Notes
+#
+# - This rule is useful when wanting to glob for JavaScript examples files (e.g., run all JavaScript examples for a particular package).
+# - This rule **assumes** that examples files can be run using Node.js.
+#
+#
+# @param {string} [EXAMPLES_FILTER] - file path pattern (e.g., `.*/math/base/special/abs/.*`)
+#
+# @example
+# make examples
+#
+# @example
+# make examples EXAMPLES_FILTER=".*/strided/common/.*"
+#/
+examples: $(NODE_MODULES)
+ $(QUIET) $(FIND_EXAMPLES_CMD) | grep '^[\/]\|^[a-zA-Z]:[/\]' | while read -r file; do \
+ echo ""; \
+ echo "Running example: $$file"; \
+ NODE_ENV="$(NODE_ENV_EXAMPLES)" \
+ NODE_PATH="$(NODE_PATH)" \
+ $(NODE) $$file || exit 1; \
+ done
+
+.PHONY: examples
+
+#/
+# Runs JavaScript tests consecutively.
+#
+# ## Notes
+#
+# - This rule is useful when wanting to glob for JavaScript test files (e.g., run all JavaScript tests for a particular package).
+# - This rule **assumes** that test files can be run using Node.js.
+#
+#
+# @param {string} [TEST_FILTER] - file path pattern (e.g., `.*/math/base/special/abs/.*`)
+#
+# @example
+# make test
+#
+# @example
+# make test TESTS_FILTER=".*/strided/common/.*"
+#/
+test: $(NODE_MODULES)
+ $(QUIET) $(FIND_TESTS_CMD) | grep '^[\/]\|^[a-zA-Z]:[/\]' | while read -r test; do \
+ echo ''; \
+ echo "Running test: $$test"; \
+ NODE_ENV="$(NODE_ENV_TEST)" \
+ NODE_PATH="$(NODE_PATH)" \
+ $(JAVASCRIPT_TEST) \
+ $(JAVASCRIPT_TEST_FLAGS) \
+ $$test \
+ | $(TAP_REPORTER) || exit 1; \
+ done
+
+.PHONY: test
+
+#/
+# Runs unit tests and generate a test coverage report.
+#
+# @example
+# make test-cov
+#/
+test-cov: clean-cov
+ $(QUIET) NODE_ENV="$(NODE_ENV_TEST)" \
+ NODE_PATH="$(NODE_PATH)" \
+ $(ISTANBUL_COVER) $(ISTANBUL_COVER_FLAGS) $(JAVASCRIPT_TEST) -- $$( $(FIND_TESTS_CMD) )
+
+.PHONY: test-cov
+
+#/
+# Removes a test coverage directory.
+#
+# @example
+# make clean-cov
+#/
+clean-cov:
+ $(QUIET) $(DELETE) $(DELETE_FLAGS) $(COVERAGE_DIR)
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..f5374f6
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1 @@
+Copyright (c) 2016-2021 The Stdlib Authors.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..17eb26b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,229 @@
+
+
+# smaxabs
+
+[![NPM version][npm-image]][npm-url] [![Build Status][test-image]][test-url] [![Coverage Status][coverage-image]][coverage-url] [![dependencies][dependencies-image]][dependencies-url]
+
+> Calculate the maximum absolute value of a single-precision floating-point strided array.
+
+
+
+
+
+
+
+## Installation
+
+```bash
+npm install @stdlib/stats-base-smaxabs
+```
+
+
+
+
+
+## Usage
+
+```javascript
+var smaxabs = require( '@stdlib/stats-base-smaxabs' );
+```
+
+#### smaxabs( N, x, stride )
+
+Computes the maximum absolute value of a single-precision floating-point strided array `x`.
+
+```javascript
+var Float32Array = require( '@stdlib/array-float32' );
+
+var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+var N = x.length;
+
+var v = smaxabs( N, x, 1 );
+// returns 2.0
+```
+
+The function has the following parameters:
+
+- **N**: number of indexed elements.
+- **x**: input [`Float32Array`][@stdlib/array/float32].
+- **stride**: index increment for `x`.
+
+The `N` and `stride` parameters determine which elements in `x` are accessed at runtime. For example, to compute the maximum absolute value of every other element in `x`,
+
+```javascript
+var Float32Array = require( '@stdlib/array-float32' );
+var floor = require( '@stdlib/math-base-special-floor' );
+
+var x = new Float32Array( [ 1.0, 2.0, 2.0, -7.0, -2.0, 3.0, 4.0, 2.0 ] );
+var N = floor( x.length / 2 );
+
+var v = smaxabs( N, x, 2 );
+// returns 4.0
+```
+
+Note that indexing is relative to the first index. To introduce an offset, use [`typed array`][mdn-typed-array] views.
+
+
+
+```javascript
+var Float32Array = require( '@stdlib/array-float32' );
+var floor = require( '@stdlib/math-base-special-floor' );
+
+var x0 = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
+var x1 = new Float32Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
+
+var N = floor( x0.length / 2 );
+
+var v = smaxabs( N, x1, 2 );
+// returns 4.0
+```
+
+#### smaxabs.ndarray( N, x, stride, offset )
+
+Computes the maximum absolute value of a single-precision floating-point strided array using alternative indexing semantics.
+
+```javascript
+var Float32Array = require( '@stdlib/array-float32' );
+
+var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+var N = x.length;
+
+var v = smaxabs.ndarray( N, x, 1, 0 );
+// returns 2.0
+```
+
+The function has the following additional parameters:
+
+- **offset**: starting index for `x`.
+
+While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to calculate the maximum absolute value for every other value in `x` starting from the second value
+
+```javascript
+var Float32Array = require( '@stdlib/array-float32' );
+var floor = require( '@stdlib/math-base-special-floor' );
+
+var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
+var N = floor( x.length / 2 );
+
+var v = smaxabs.ndarray( N, x, 2, 1 );
+// returns 4.0
+```
+
+
+
+
+
+
+
+## Notes
+
+- If `N <= 0`, both functions return `NaN`.
+
+
+
+
+
+
+
+## Examples
+
+
+
+```javascript
+var randu = require( '@stdlib/random-base-randu' );
+var round = require( '@stdlib/math-base-special-round' );
+var Float32Array = require( '@stdlib/array-float32' );
+var smaxabs = require( '@stdlib/stats-base-smaxabs' );
+
+var x;
+var i;
+
+x = new Float32Array( 10 );
+for ( i = 0; i < x.length; i++ ) {
+ x[ i ] = round( (randu()*100.0) - 50.0 );
+}
+console.log( x );
+
+var v = smaxabs( x.length, x, 1 );
+console.log( v );
+```
+
+
+
+
+
+
+
+
+* * *
+
+## Notice
+
+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 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].
+
+---
+
+## License
+
+See [LICENSE][stdlib-license].
+
+
+## Copyright
+
+Copyright © 2016-2021. The Stdlib [Authors][stdlib-authors].
+
+
+
+
+
+
+
+
+
+[npm-image]: http://img.shields.io/npm/v/@stdlib/stats-base-smaxabs.svg
+[npm-url]: https://npmjs.org/package/@stdlib/stats-base-smaxabs
+
+[test-image]: https://github.com/stdlib-js/stats-base-smaxabs/actions/workflows/test.yml/badge.svg
+[test-url]: https://github.com/stdlib-js/stats-base-smaxabs/actions/workflows/test.yml
+
+[coverage-image]: https://img.shields.io/codecov/c/github/stdlib-js/stats-base-smaxabs/main.svg
+[coverage-url]: https://codecov.io/github/stdlib-js/stats-base-smaxabs?branch=main
+
+[dependencies-image]: https://img.shields.io/david/stdlib-js/stats-base-smaxabs
+[dependencies-url]: https://david-dm.org/stdlib-js/stats-base-smaxabs/main
+
+[stdlib]: https://github.com/stdlib-js/stdlib
+
+[stdlib-authors]: https://github.com/stdlib-js/stdlib/graphs/contributors
+
+[stdlib-license]: https://raw.githubusercontent.com/stdlib-js/stats-base-smaxabs/main/LICENSE
+
+[@stdlib/array/float32]: https://github.com/stdlib-js/stdlib
+
+[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
+
+
+
+
diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js
new file mode 100644
index 0000000..22b27df
--- /dev/null
+++ b/benchmark/benchmark.js
@@ -0,0 +1,96 @@
+/**
+* @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 randu = require( '@stdlib/random-base-randu' );
+var isnan = require( '@stdlib/math-base-assert-is-nan' );
+var pow = require( '@stdlib/math-base-special-pow' );
+var Float32Array = require( '@stdlib/array-float32' );
+var pkg = require( './../package.json' ).name;
+var smaxabs = require( './../lib/smaxabs.js' );
+
+
+// FUNCTIONS //
+
+/**
+* Creates a benchmark function.
+*
+* @private
+* @param {PositiveInteger} len - array length
+* @returns {Function} benchmark function
+*/
+function createBenchmark( len ) {
+ var x;
+ var i;
+
+ x = new Float32Array( len );
+ for ( i = 0; i < x.length; i++ ) {
+ x[ i ] = ( randu()*20.0 ) - 10.0;
+ }
+ return benchmark;
+
+ function benchmark( b ) {
+ var v;
+ var i;
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ v = smaxabs( x.length, x, 1 );
+ if ( isnan( v ) ) {
+ b.fail( 'should not return NaN' );
+ }
+ }
+ b.toc();
+ if ( isnan( v ) ) {
+ 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 f;
+ var i;
+
+ min = 1; // 10^min
+ max = 6; // 10^max
+
+ for ( i = min; i <= max; i++ ) {
+ len = pow( 10, i );
+ f = createBenchmark( len );
+ bench( pkg+':len='+len, f );
+ }
+}
+
+main();
diff --git a/benchmark/benchmark.native.js b/benchmark/benchmark.native.js
new file mode 100644
index 0000000..25e8796
--- /dev/null
+++ b/benchmark/benchmark.native.js
@@ -0,0 +1,105 @@
+/**
+* @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 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 Float32Array = require( '@stdlib/array-float32' );
+var tryRequire = require( '@stdlib/utils-try-require' );
+var pkg = require( './../package.json' ).name;
+
+
+// VARIABLES //
+
+var smaxabs = tryRequire( resolve( __dirname, './../lib/smaxabs.native.js' ) );
+var opts = {
+ 'skip': ( smaxabs instanceof Error )
+};
+
+
+// FUNCTIONS //
+
+/**
+* Creates a benchmark function.
+*
+* @private
+* @param {PositiveInteger} len - array length
+* @returns {Function} benchmark function
+*/
+function createBenchmark( len ) {
+ var x;
+ var i;
+
+ x = new Float32Array( len );
+ for ( i = 0; i < x.length; i++ ) {
+ x[ i ] = ( randu()*20.0 ) - 10.0;
+ }
+ return benchmark;
+
+ function benchmark( b ) {
+ var v;
+ var i;
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ v = smaxabs( x.length, x, 1 );
+ if ( isnan( v ) ) {
+ b.fail( 'should not return NaN' );
+ }
+ }
+ b.toc();
+ if ( isnan( v ) ) {
+ 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 f;
+ var i;
+
+ min = 1; // 10^min
+ max = 6; // 10^max
+
+ for ( i = min; i <= max; i++ ) {
+ len = pow( 10, i );
+ f = createBenchmark( len );
+ bench( pkg+'::native:len='+len, opts, f );
+ }
+}
+
+main();
diff --git a/benchmark/benchmark.ndarray.js b/benchmark/benchmark.ndarray.js
new file mode 100644
index 0000000..23e6519
--- /dev/null
+++ b/benchmark/benchmark.ndarray.js
@@ -0,0 +1,96 @@
+/**
+* @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 randu = require( '@stdlib/random-base-randu' );
+var isnan = require( '@stdlib/math-base-assert-is-nan' );
+var pow = require( '@stdlib/math-base-special-pow' );
+var Float32Array = require( '@stdlib/array-float32' );
+var pkg = require( './../package.json' ).name;
+var smaxabs = require( './../lib/ndarray.js' );
+
+
+// FUNCTIONS //
+
+/**
+* Creates a benchmark function.
+*
+* @private
+* @param {PositiveInteger} len - array length
+* @returns {Function} benchmark function
+*/
+function createBenchmark( len ) {
+ var x;
+ var i;
+
+ x = new Float32Array( len );
+ for ( i = 0; i < x.length; i++ ) {
+ x[ i ] = ( randu()*20.0 ) - 10.0;
+ }
+ return benchmark;
+
+ function benchmark( b ) {
+ var v;
+ var i;
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ v = smaxabs( x.length, x, 1, 0 );
+ if ( isnan( v ) ) {
+ b.fail( 'should not return NaN' );
+ }
+ }
+ b.toc();
+ if ( isnan( v ) ) {
+ 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 f;
+ var i;
+
+ min = 1; // 10^min
+ max = 6; // 10^max
+
+ for ( i = min; i <= max; i++ ) {
+ len = pow( 10, i );
+ f = createBenchmark( len );
+ bench( pkg+':ndarray:len='+len, f );
+ }
+}
+
+main();
diff --git a/benchmark/benchmark.ndarray.native.js b/benchmark/benchmark.ndarray.native.js
new file mode 100644
index 0000000..2c34e73
--- /dev/null
+++ b/benchmark/benchmark.ndarray.native.js
@@ -0,0 +1,105 @@
+/**
+* @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 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 Float32Array = require( '@stdlib/array-float32' );
+var tryRequire = require( '@stdlib/utils-try-require' );
+var pkg = require( './../package.json' ).name;
+
+
+// VARIABLES //
+
+var smaxabs = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) );
+var opts = {
+ 'skip': ( smaxabs instanceof Error )
+};
+
+
+// FUNCTIONS //
+
+/**
+* Creates a benchmark function.
+*
+* @private
+* @param {PositiveInteger} len - array length
+* @returns {Function} benchmark function
+*/
+function createBenchmark( len ) {
+ var x;
+ var i;
+
+ x = new Float32Array( len );
+ for ( i = 0; i < x.length; i++ ) {
+ x[ i ] = ( randu()*20.0 ) - 10.0;
+ }
+ return benchmark;
+
+ function benchmark( b ) {
+ var v;
+ var i;
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ v = smaxabs( x.length, x, 1, 0 );
+ if ( isnan( v ) ) {
+ b.fail( 'should not return NaN' );
+ }
+ }
+ b.toc();
+ if ( isnan( v ) ) {
+ 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 f;
+ var i;
+
+ min = 1; // 10^min
+ max = 6; // 10^max
+
+ for ( i = min; i <= max; i++ ) {
+ len = pow( 10, i );
+ f = createBenchmark( len );
+ bench( pkg+'::native:ndarray:len='+len, opts, f );
+ }
+}
+
+main();
diff --git a/benchmark/c/Makefile b/benchmark/c/Makefile
new file mode 100644
index 0000000..7280962
--- /dev/null
+++ b/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.length.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 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/benchmark/c/benchmark.length.c b/benchmark/c/benchmark.length.c
new file mode 100644
index 0000000..6af79e9
--- /dev/null
+++ b/benchmark/c/benchmark.length.c
@@ -0,0 +1,153 @@
+/**
+* @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 `smaxabs`.
+*/
+#include "stdlib/stats/base/smaxabs.h"
+#include
+#include
+#include
+#include
+#include
+
+#define NAME "smaxabs"
+#define ITERATIONS 1000000
+#define REPEATS 3
+#define MIN 1
+#define MAX 6
+
+/**
+* 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 iterations number of iterations
+* @param elapsed elapsed time in seconds
+*/
+void print_results( int iterations, 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 number on the interval [0,1].
+*
+* @return random number
+*/
+float rand_float() {
+ int r = rand();
+ return (float)r / ( (float)RAND_MAX + 1.0f );
+}
+
+/*
+* Runs a benchmark.
+*
+* @param iterations number of iterations
+* @param len array length
+* @return elapsed time in seconds
+*/
+double benchmark( int iterations, int len ) {
+ double elapsed;
+ float x[ len ];
+ float v;
+ double t;
+ int i;
+
+ for ( i = 0; i < len; i++ ) {
+ x[ i ] = ( rand_float()*20000.0f ) - 10000.0f;
+ }
+ t = tic();
+ for ( i = 0; i < iterations; i++ ) {
+ v = stdlib_strided_smaxabs( len, x, 1 );
+ if ( v != v ) {
+ printf( "should not return NaN\n" );
+ break;
+ }
+ }
+ elapsed = tic() - t;
+ if ( v != v ) {
+ printf( "should not return NaN\n" );
+ }
+ return elapsed;
+}
+
+/**
+* Main execution sequence.
+*/
+int main( void ) {
+ double elapsed;
+ int count;
+ int iter;
+ int len;
+ int i;
+ int j;
+
+ // Use the current time to seed the random number generator:
+ srand( time( NULL ) );
+
+ print_version();
+ count = 0;
+ for ( i = MIN; i <= MAX; i++ ) {
+ len = pow( 10, i );
+ iter = ITERATIONS / pow( 10, i-1 );
+ for ( j = 0; j < REPEATS; j++ ) {
+ count += 1;
+ printf( "# c::%s:len=%d\n", NAME, len );
+ elapsed = benchmark( iter, len );
+ print_results( iter, elapsed );
+ printf( "ok %d benchmark finished\n", count );
+ }
+ }
+ print_summary( count, count );
+}
diff --git a/binding.gyp b/binding.gyp
new file mode 100644
index 0000000..7d0005b
--- /dev/null
+++ b/binding.gyp
@@ -0,0 +1,170 @@
+# @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.
+
+# A `.gyp` file for building a Node.js native add-on.
+#
+# [1]: https://gyp.gsrc.io/docs/InputFormatReference.md
+# [2]: https://gyp.gsrc.io/docs/UserDocumentation.md
+{
+ # List of files to include in this file:
+ 'includes': [
+ './include.gypi',
+ ],
+
+ # Define variables to be used throughout the configuration for all targets:
+ 'variables': {
+ # Target name should match the add-on export name:
+ 'addon_target_name%': 'addon',
+
+ # Set variables based on the host OS:
+ 'conditions': [
+ [
+ 'OS=="win"',
+ {
+ # Define the object file suffix:
+ 'obj': 'obj',
+ },
+ {
+ # Define the object file suffix:
+ 'obj': 'o',
+ }
+ ], # end condition (OS=="win")
+ ], # end conditions
+ }, # end variables
+
+ # Define compile targets:
+ 'targets': [
+
+ # Target to generate an add-on:
+ {
+ # The target name should match the add-on export name:
+ 'target_name': '<(addon_target_name)',
+
+ # Define dependencies:
+ 'dependencies': [],
+
+ # Define directories which contain relevant include headers:
+ 'include_dirs': [
+ # Local include directory:
+ '<@(include_dirs)',
+ ],
+
+ # List of source files:
+ 'sources': [
+ '<@(src_files)',
+ ],
+
+ # Settings which should be applied when a target's object files are used as linker input:
+ 'link_settings': {
+ # Define libraries:
+ 'libraries': [
+ '<@(libraries)',
+ ],
+
+ # Define library directories:
+ 'library_dirs': [
+ '<@(library_dirs)',
+ ],
+ },
+
+ # C/C++ compiler flags:
+ 'cflags': [
+ # Enable commonly used warning options:
+ '-Wall',
+
+ # Aggressive optimization:
+ '-O3',
+ ],
+
+ # C specific compiler flags:
+ 'cflags_c': [
+ # Specify the C standard to which a program is expected to conform:
+ '-std=c99',
+ ],
+
+ # C++ specific compiler flags:
+ 'cflags_cpp': [
+ # Specify the C++ standard to which a program is expected to conform:
+ '-std=c++11',
+ ],
+
+ # Linker flags:
+ 'ldflags': [],
+
+ # Apply conditions based on the host OS:
+ 'conditions': [
+ [
+ 'OS=="mac"',
+ {
+ # Linker flags:
+ 'ldflags': [
+ '-undefined dynamic_lookup',
+ '-Wl,-no-pie',
+ '-Wl,-search_paths_first',
+ ],
+ },
+ ], # end condition (OS=="mac")
+ [
+ 'OS!="win"',
+ {
+ # C/C++ flags:
+ 'cflags': [
+ # Generate platform-independent code:
+ '-fPIC',
+ ],
+ },
+ ], # end condition (OS!="win")
+ ], # end conditions
+ }, # end target <(addon_target_name)
+
+ # Target to copy a generated add-on to a standard location:
+ {
+ 'target_name': 'copy_addon',
+
+ # Declare that the output of this target is not linked:
+ 'type': 'none',
+
+ # Define dependencies:
+ 'dependencies': [
+ # Require that the add-on be generated before building this target:
+ '<(addon_target_name)',
+ ],
+
+ # Define a list of actions:
+ 'actions': [
+ {
+ 'action_name': 'copy_addon',
+ 'message': 'Copying addon...',
+
+ # Explicitly list the inputs in the command-line invocation below:
+ 'inputs': [],
+
+ # Declare the expected outputs:
+ 'outputs': [
+ '<(addon_output_dir)/<(addon_target_name).node',
+ ],
+
+ # Define the command-line invocation:
+ 'action': [
+ 'cp',
+ '<(PRODUCT_DIR)/<(addon_target_name).node',
+ '<(addon_output_dir)/<(addon_target_name).node',
+ ],
+ },
+ ], # end actions
+ }, # end target copy_addon
+ ], # end targets
+}
diff --git a/docs/repl.txt b/docs/repl.txt
new file mode 100644
index 0000000..4b4f537
--- /dev/null
+++ b/docs/repl.txt
@@ -0,0 +1,94 @@
+
+{{alias}}( N, x, stride )
+ Computes the maximum absolute value of a single-precision floating-point
+ strided array.
+
+ The `N` and `stride` parameters determine which elements in `x` are accessed
+ at runtime.
+
+ Indexing is relative to the first index. To introduce an offset, use a typed
+ array view.
+
+ If `N <= 0`, the function returns `NaN`.
+
+ Parameters
+ ----------
+ N: integer
+ Number of indexed elements.
+
+ x: Float32Array
+ Input array.
+
+ stride: integer
+ Index increment.
+
+ Returns
+ -------
+ out: number
+ Maximum absolute value.
+
+ Examples
+ --------
+ // Standard Usage:
+ > var x = new {{alias:@stdlib/array/float32}}( [ 1.0, -2.0, 2.0 ] );
+ > {{alias}}( x.length, x, 1 )
+ 2.0
+
+ // Using `N` and `stride` parameters:
+ > x = new {{alias:@stdlib/array/float32}}( [ -2.0, 1.0, 1.0, -5.0, 2.0, -1.0 ] );
+ > var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
+ > var stride = 2;
+ > {{alias}}( N, x, stride )
+ 2.0
+
+ // Using view offsets:
+ > var x0 = new {{alias:@stdlib/array/float32}}( [ 1.0, -2.0, 3.0, 2.0, 5.0, -1.0 ] );
+ > var x1 = new {{alias:@stdlib/array/float32}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 );
+ > N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 );
+ > stride = 2;
+ > {{alias}}( N, x1, stride )
+ 2.0
+
+{{alias}}.ndarray( N, x, stride, offset )
+ Computes the maximum absolute value of a single-precision floating-point
+ strided array using alternative indexing semantics.
+
+ While typed array views mandate a view offset based on the underlying
+ buffer, the `offset` parameter supports indexing semantics based on a
+ starting index.
+
+ Parameters
+ ----------
+ N: integer
+ Number of indexed elements.
+
+ x: Float32Array
+ Input array.
+
+ stride: integer
+ Index increment.
+
+ offset: integer
+ Starting index.
+
+ Returns
+ -------
+ out: number
+ Maximum absolute value.
+
+ Examples
+ --------
+ // Standard Usage:
+ > var x = new {{alias:@stdlib/array/float32}}( [ 1.0, -2.0, 2.0 ] );
+ > {{alias}}.ndarray( x.length, x, 1, 0 )
+ 2.0
+
+ // Using offset parameter:
+ > var x = new {{alias:@stdlib/array/float32}}( [ 1.0, -2.0, 3.0, 2.0, 5.0, -1.0 ] );
+ > var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
+ > {{alias}}.ndarray( N, x, 2, 1 )
+ 2.0
+
+ See Also
+ --------
+
diff --git a/docs/types/index.d.ts b/docs/types/index.d.ts
new file mode 100644
index 0000000..e509bce
--- /dev/null
+++ b/docs/types/index.d.ts
@@ -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.
+*/
+
+// TypeScript Version: 2.0
+
+/**
+* Interface describing `smaxabs`.
+*/
+interface Routine {
+ /**
+ * Computes the maximum absolute value of a single-precision floating-point strided array.
+ *
+ * @param N - number of indexed elements
+ * @param x - input array
+ * @param stride - stride length
+ * @returns maximum absolute value
+ *
+ * @example
+ * var Float32Array = require( `@stdlib/array/float32` );
+ *
+ * var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+ *
+ * var v = smaxabs( x.length, x, 1 );
+ * // returns 2.0
+ */
+ ( N: number, x: Float32Array, stride: number ): number;
+
+ /**
+ * Computes the maximum absolute value of a single-precision floating-point strided array using alternative indexing semantics.
+ *
+ * @param N - number of indexed elements
+ * @param x - input array
+ * @param stride - stride length
+ * @param offset - starting index
+ * @returns maximum absolute value
+ *
+ * @example
+ * var Float32Array = require( `@stdlib/array/float32` );
+ *
+ * var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+ *
+ * var v = smaxabs.ndarray( x.length, x, 1, 0 );
+ * // returns 2.0
+ */
+ ndarray( N: number, x: Float32Array, stride: number, offset: number ): number; // tslint:disable-line:max-line-length
+}
+
+/**
+* Computes the maximum absolute value of a single-precision floating-point strided array.
+*
+* @param N - number of indexed elements
+* @param x - input array
+* @param stride - stride length
+* @returns maximum absolute value
+*
+* @example
+* var Float32Array = require( `@stdlib/array/float32` );
+*
+* var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+*
+* var v = smaxabs( x.length, x, 1 );
+* // returns 2.0
+*
+* @example
+* var Float32Array = require( `@stdlib/array/float32` );
+*
+* var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+*
+* var v = smaxabs.ndarray( x.length, x, 1, 0 );
+* // returns 2.0
+*/
+declare var smaxabs: Routine;
+
+
+// EXPORTS //
+
+export = smaxabs;
diff --git a/docs/types/test.ts b/docs/types/test.ts
new file mode 100644
index 0000000..30a231b
--- /dev/null
+++ b/docs/types/test.ts
@@ -0,0 +1,157 @@
+/*
+* @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.
+*/
+
+import smaxabs = require( './index' );
+
+
+// TESTS //
+
+// The function returns a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs( x.length, x, 1 ); // $ExpectType number
+}
+
+// The compiler throws an error if the function is provided a first argument which is not a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs( '10', x, 1 ); // $ExpectError
+ smaxabs( true, x, 1 ); // $ExpectError
+ smaxabs( false, x, 1 ); // $ExpectError
+ smaxabs( null, x, 1 ); // $ExpectError
+ smaxabs( undefined, x, 1 ); // $ExpectError
+ smaxabs( [], x, 1 ); // $ExpectError
+ smaxabs( {}, x, 1 ); // $ExpectError
+ smaxabs( ( x: number ): number => x, x, 1 ); // $ExpectError
+}
+
+// The compiler throws an error if the function is provided a second argument which is not a Float32Array...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs( x.length, 10, 1 ); // $ExpectError
+ smaxabs( x.length, '10', 1 ); // $ExpectError
+ smaxabs( x.length, true, 1 ); // $ExpectError
+ smaxabs( x.length, false, 1 ); // $ExpectError
+ smaxabs( x.length, null, 1 ); // $ExpectError
+ smaxabs( x.length, undefined, 1 ); // $ExpectError
+ smaxabs( x.length, [], 1 ); // $ExpectError
+ smaxabs( x.length, {}, 1 ); // $ExpectError
+ smaxabs( x.length, ( x: number ): number => x, 1 ); // $ExpectError
+}
+
+// The compiler throws an error if the function is provided a third argument which is not a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs( x.length, x, '10' ); // $ExpectError
+ smaxabs( x.length, x, true ); // $ExpectError
+ smaxabs( x.length, x, false ); // $ExpectError
+ smaxabs( x.length, x, null ); // $ExpectError
+ smaxabs( x.length, x, undefined ); // $ExpectError
+ smaxabs( x.length, x, [] ); // $ExpectError
+ smaxabs( x.length, x, {} ); // $ExpectError
+ smaxabs( x.length, x, ( x: number ): number => x ); // $ExpectError
+}
+
+// The compiler throws an error if the function is provided an unsupported number of arguments...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs(); // $ExpectError
+ smaxabs( x.length ); // $ExpectError
+ smaxabs( x.length, x ); // $ExpectError
+ smaxabs( x.length, x, 1, 10 ); // $ExpectError
+}
+
+// Attached to main export is an `ndarray` method which returns a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs.ndarray( x.length, x, 1, 0 ); // $ExpectType number
+}
+
+// The compiler throws an error if the `ndarray` method is provided a first argument which is not a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs.ndarray( '10', x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( true, x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( false, x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( null, x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( undefined, x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( [], x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( {}, x, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( ( x: number ): number => x, x, 1, 0 ); // $ExpectError
+}
+
+// The compiler throws an error if the `ndarray` method is provided a second argument which is not a Float32Array...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs.ndarray( x.length, 10, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, '10', 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, true, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, false, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, null, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, undefined, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, [], 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, {}, 1, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, ( x: number ): number => x, 1, 0 ); // $ExpectError
+}
+
+// The compiler throws an error if the `ndarray` method is provided a third argument which is not a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs.ndarray( x.length, x, '10', 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, true, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, false, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, null, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, undefined, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, [], 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, {}, 0 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, ( x: number ): number => x, 0 ); // $ExpectError
+}
+
+// The compiler throws an error if the `ndarray` method is provided a fourth argument which is not a number...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs.ndarray( x.length, x, 1, '10' ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, true ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, false ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, null ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, undefined ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, [] ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, {} ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, ( x: number ): number => x ); // $ExpectError
+}
+
+// The compiler throws an error if the `ndarray` method is provided an unsupported number of arguments...
+{
+ const x = new Float32Array( 10 );
+
+ smaxabs.ndarray(); // $ExpectError
+ smaxabs.ndarray( x.length ); // $ExpectError
+ smaxabs.ndarray( x.length, x ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1 ); // $ExpectError
+ smaxabs.ndarray( x.length, x, 1, 0, 10 ); // $ExpectError
+}
diff --git a/examples/c/Makefile b/examples/c/Makefile
new file mode 100644
index 0000000..ff5293d
--- /dev/null
+++ b/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/examples/c/example.c b/examples/c/example.c
new file mode 100644
index 0000000..d7e830e
--- /dev/null
+++ b/examples/c/example.c
@@ -0,0 +1,39 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2020 The Stdlib Authors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stdlib/stats/base/smaxabs.h"
+#include
+#include
+
+int main() {
+ // Create a strided array:
+ float x[] = { 1.0, -2.0, -3.0, 4.0, -5.0, -6.0, 7.0, 8.0 };
+
+ // Specify the number of elements:
+ int64_t N = 4;
+
+ // Specify the stride length:
+ int64_t stride = 2;
+
+ // Compute the maximum absolute value:
+ float v = stdlib_strided_smaxabs( N, x, stride );
+
+ // Print the result:
+ printf( "maxabs: %f", v );
+ printf( "\n" );
+}
diff --git a/examples/index.js b/examples/index.js
new file mode 100644
index 0000000..9e027b5
--- /dev/null
+++ b/examples/index.js
@@ -0,0 +1,36 @@
+/**
+* @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 randu = require( '@stdlib/random-base-randu' );
+var round = require( '@stdlib/math-base-special-round' );
+var Float32Array = require( '@stdlib/array-float32' );
+var smaxabs = require( './../lib' );
+
+var x;
+var i;
+
+x = new Float32Array( 10 );
+for ( i = 0; i < x.length; i++ ) {
+ x[ i ] = round( (randu()*100.0) - 50.0 );
+}
+console.log( x );
+
+var v = smaxabs( x.length, x, 1 );
+console.log( v );
diff --git a/include.gypi b/include.gypi
new file mode 100644
index 0000000..2fa318f
--- /dev/null
+++ b/include.gypi
@@ -0,0 +1,53 @@
+# @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.
+
+# A GYP include file for building a Node.js native add-on.
+#
+# Main documentation:
+#
+# [1]: https://gyp.gsrc.io/docs/InputFormatReference.md
+# [2]: https://gyp.gsrc.io/docs/UserDocumentation.md
+{
+ # Define variables to be used throughout the configuration for all targets:
+ 'variables': {
+ # Source directory:
+ 'src_dir': './src',
+
+ # Include directories:
+ 'include_dirs': [
+ '
+
+/*
+* 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
+
+/**
+* Computes the maximum absolute value of a single-precision floating-point strided array.
+*/
+float stdlib_strided_smaxabs( const int64_t N, const float *X, const int64_t stride );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !STDLIB_STATS_BASE_SMAXABS_H
diff --git a/lib/index.js b/lib/index.js
new file mode 100644
index 0000000..f475b01
--- /dev/null
+++ b/lib/index.js
@@ -0,0 +1,65 @@
+/**
+* @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';
+
+/**
+* Compute the maximum absolute value of a single-precision floating-point strided array.
+*
+* @module @stdlib/stats/base/smaxabs
+*
+* @example
+* var Float32Array = require( '@stdlib/array-float32' );
+* var smaxabs = require( '@stdlib/stats-base-smaxabs' );
+*
+* var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+* var N = x.length;
+*
+* var v = smaxabs( N, x, 1 );
+* // returns 2.0
+*
+* @example
+* var Float32Array = require( '@stdlib/array-float32' );
+* var floor = require( '@stdlib/math-base-special-floor' );
+* var smaxabs = require( '@stdlib/stats-base-smaxabs' );
+*
+* var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
+* var N = floor( x.length / 2 );
+*
+* var v = smaxabs.ndarray( N, x, 2, 1 );
+* // returns 4.0
+*/
+
+// MODULES //
+
+var join = require( 'path' ).join;
+var tryRequire = require( '@stdlib/utils-try-require' );
+var smaxabs = require( './main.js' );
+
+
+// MAIN //
+
+var tmp = tryRequire( join( __dirname, './native.js' ) );
+if ( !(tmp instanceof Error) ) {
+ smaxabs = tmp;
+}
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/lib/main.js b/lib/main.js
new file mode 100644
index 0000000..f5ef17d
--- /dev/null
+++ b/lib/main.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';
+
+// MODULES //
+
+var setReadOnly = require( '@stdlib/utils-define-nonenumerable-read-only-property' );
+var smaxabs = require( './smaxabs.js' );
+var ndarray = require( './ndarray.js' );
+
+
+// MAIN //
+
+setReadOnly( smaxabs, 'ndarray', ndarray );
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/lib/native.js b/lib/native.js
new file mode 100644
index 0000000..93b0213
--- /dev/null
+++ b/lib/native.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';
+
+// MODULES //
+
+var setReadOnly = require( '@stdlib/utils-define-nonenumerable-read-only-property' );
+var smaxabs = require( './smaxabs.native.js' );
+var ndarray = require( './ndarray.native.js' );
+
+
+// MAIN //
+
+setReadOnly( smaxabs, 'ndarray', ndarray );
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/lib/ndarray.js b/lib/ndarray.js
new file mode 100644
index 0000000..ab48c40
--- /dev/null
+++ b/lib/ndarray.js
@@ -0,0 +1,78 @@
+/**
+* @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 isnanf = require( '@stdlib/math-base-assert-is-nanf' );
+var abs = require( '@stdlib/math-base-special-abs' );
+
+
+// MAIN //
+
+/**
+* Computes the maximum absolute value of a single-precision floating-point strided array.
+*
+* @param {PositiveInteger} N - number of indexed elements
+* @param {Float32Array} x - input array
+* @param {integer} stride - stride length
+* @param {NonNegativeInteger} offset - starting index
+* @returns {number} maximum absolute value
+*
+* @example
+* var Float32Array = require( '@stdlib/array-float32' );
+* var floor = require( '@stdlib/math-base-special-floor' );
+*
+* var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
+* var N = floor( x.length / 2 );
+*
+* var v = smaxabs( N, x, 2, 1 );
+* // returns 4.0
+*/
+function smaxabs( N, x, stride, offset ) {
+ var max;
+ var ix;
+ var v;
+ var i;
+
+ if ( N <= 0 ) {
+ return NaN;
+ }
+ if ( N === 1 || stride === 0 ) {
+ return abs( x[ offset ] );
+ }
+ ix = offset;
+ max = abs( x[ ix ] );
+ for ( i = 1; i < N; i++ ) {
+ ix += stride;
+ v = abs( x[ ix ] );
+ if ( isnanf( v ) ) {
+ return v;
+ }
+ if ( v > max ) {
+ max = v;
+ }
+ }
+ return max;
+}
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/lib/ndarray.native.js b/lib/ndarray.native.js
new file mode 100644
index 0000000..f61ad0e
--- /dev/null
+++ b/lib/ndarray.native.js
@@ -0,0 +1,60 @@
+/**
+* @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 Float32Array = require( '@stdlib/array-float32' );
+var addon = require( './smaxabs.native.js' );
+
+
+// MAIN //
+
+/**
+* Computes the maximum absolute value of a double-precision floating-point strided array.
+*
+* @param {PositiveInteger} N - number of indexed elements
+* @param {Float32Array} x - input array
+* @param {integer} stride - stride length
+* @param {NonNegativeInteger} offset - starting index
+* @returns {number} maximum absolute value
+*
+* @example
+* var Float32Array = require( '@stdlib/array-float32' );
+* var floor = require( '@stdlib/math-base-special-floor' );
+*
+* var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
+* var N = floor( x.length / 2 );
+*
+* var v = smaxabs( N, x, 2, 1 );
+* // returns 4.0
+*/
+function smaxabs( N, x, stride, offset ) {
+ var view;
+ if ( stride < 0 ) {
+ offset += (N-1) * stride;
+ }
+ view = new Float32Array( x.buffer, x.byteOffset+(x.BYTES_PER_ELEMENT*offset), x.length-offset ); // eslint-disable-line max-len
+ return addon( N, view, stride );
+}
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/lib/smaxabs.js b/lib/smaxabs.js
new file mode 100644
index 0000000..e4fd9fb
--- /dev/null
+++ b/lib/smaxabs.js
@@ -0,0 +1,80 @@
+/**
+* @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 isnanf = require( '@stdlib/math-base-assert-is-nanf' );
+var abs = require( '@stdlib/math-base-special-abs' );
+
+
+// MAIN //
+
+/**
+* Computes the maximum absolute value of a single-precision floating-point strided array.
+*
+* @param {PositiveInteger} N - number of indexed elements
+* @param {Float32Array} x - input array
+* @param {integer} stride - stride length
+* @returns {number} maximum absolute value
+*
+* @example
+* var Float32Array = require( '@stdlib/array-float32' );
+*
+* var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+* var N = x.length;
+*
+* var v = smaxabs( N, x, 1 );
+* // returns 2.0
+*/
+function smaxabs( N, x, stride ) {
+ var max;
+ var ix;
+ var v;
+ var i;
+
+ if ( N <= 0 ) {
+ return NaN;
+ }
+ if ( N === 1 || stride === 0 ) {
+ return abs( x[ 0 ] );
+ }
+ if ( stride < 0 ) {
+ ix = (1-N) * stride;
+ } else {
+ ix = 0;
+ }
+ max = abs( x[ ix ] );
+ for ( i = 1; i < N; i++ ) {
+ ix += stride;
+ v = abs( x[ ix ] );
+ if ( isnanf( v ) ) {
+ return v;
+ }
+ if ( v > max ) {
+ max = v;
+ }
+ }
+ return max;
+}
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/lib/smaxabs.native.js b/lib/smaxabs.native.js
new file mode 100644
index 0000000..29dff95
--- /dev/null
+++ b/lib/smaxabs.native.js
@@ -0,0 +1,52 @@
+/**
+* @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 addon = require( './../src/addon.node' );
+
+
+// MAIN //
+
+/**
+* Computes the maximum absolute value of a single-precision floating-point strided array.
+*
+* @param {PositiveInteger} N - number of indexed elements
+* @param {Float32Array} x - input array
+* @param {integer} stride - stride length
+* @returns {number} maximum absolute value
+*
+* @example
+* var Float32Array = require( '@stdlib/array-float32' );
+*
+* var x = new Float32Array( [ 1.0, -2.0, 2.0 ] );
+* var N = x.length;
+*
+* var v = smaxabs( N, x, 1 );
+* // returns 2.0
+*/
+function smaxabs( N, x, stride ) {
+ return addon( N, x, stride );
+}
+
+
+// EXPORTS //
+
+module.exports = smaxabs;
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..6763481
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,42 @@
+{
+ "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/smaxabs.c"
+ ],
+ "include": [
+ "./include"
+ ],
+ "libraries": [
+ "-lm"
+ ],
+ "libpath": [],
+ "dependencies": [
+ "@stdlib/math-base-assert-is-nanf"
+ ]
+ }
+ ]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..4e678f8
--- /dev/null
+++ b/package.json
@@ -0,0 +1,109 @@
+{
+ "name": "@stdlib/stats-base-smaxabs",
+ "version": "0.0.0",
+ "description": "Calculate the maximum absolute value of a single-precision floating-point strided array.",
+ "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",
+ "browser": "./lib/main.js",
+ "gypfile": true,
+ "directories": {
+ "benchmark": "./benchmark",
+ "doc": "./docs",
+ "example": "./examples",
+ "include": "./include",
+ "lib": "./lib",
+ "test": "./test",
+ "src": "./src"
+ },
+ "types": "./docs/types",
+ "scripts": {
+ "test": "make test",
+ "test-cov": "make test-cov",
+ "examples": "make examples",
+ "benchmark": "make benchmark"
+ },
+ "homepage": "https://github.com/stdlib-js/stdlib",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/stdlib-js/stats-base-smaxabs.git"
+ },
+ "bugs": {
+ "url": "https://github.com/stdlib-js/stdlib/issues"
+ },
+ "dependencies": {
+ "@stdlib/math-base-assert-is-nanf": "^0.0.x",
+ "@stdlib/math-base-special-abs": "^0.0.x",
+ "@stdlib/utils-define-nonenumerable-read-only-property": "^0.0.x",
+ "@stdlib/utils-library-manifest": "^0.0.x",
+ "@stdlib/utils-try-require": "^0.0.x"
+ },
+ "devDependencies": {
+ "@stdlib/array-float32": "^0.0.x",
+ "@stdlib/assert-is-browser": "^0.0.x",
+ "@stdlib/bench": "^0.0.x",
+ "@stdlib/math-base-assert-is-nan": "^0.0.x",
+ "@stdlib/math-base-assert-is-positive-zero": "^0.0.x",
+ "@stdlib/math-base-special-floor": "^0.0.x",
+ "@stdlib/math-base-special-pow": "^0.0.x",
+ "@stdlib/math-base-special-round": "^0.0.x",
+ "@stdlib/random-base-randu": "^0.0.x",
+ "proxyquire": "^2.0.0",
+ "tape": "git+https://github.com/kgryte/tape.git#fix/globby",
+ "istanbul": "^0.4.1",
+ "tap-spec": "5.x.x"
+ },
+ "engines": {
+ "node": ">=0.10.0",
+ "npm": ">2.7.0"
+ },
+ "os": [
+ "aix",
+ "darwin",
+ "freebsd",
+ "linux",
+ "macos",
+ "openbsd",
+ "sunos",
+ "win32",
+ "windows"
+ ],
+ "keywords": [
+ "stdlib",
+ "stdmath",
+ "statistics",
+ "stats",
+ "mathematics",
+ "math",
+ "maximum",
+ "max",
+ "absolute",
+ "abs",
+ "range",
+ "extremes",
+ "domain",
+ "extent",
+ "strided",
+ "strided array",
+ "typed",
+ "array",
+ "float32",
+ "single",
+ "float",
+ "float32array"
+ ],
+ "__stdlib__": {},
+ "funding": {
+ "type": "patreon",
+ "url": "https://www.patreon.com/athan"
+ }
+}
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..dd720a3
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,70 @@
+#/
+# @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
+
+
+# RULES #
+
+#/
+# Removes generated files for building an add-on.
+#
+# @example
+# make clean-addon
+#/
+clean-addon:
+ $(QUIET) -rm -f *.o *.node
+
+.PHONY: clean-addon
+
+#/
+# Removes generated files.
+#
+# @example
+# make clean
+#/
+clean: clean-addon
+
+.PHONY: clean
diff --git a/src/addon.cpp b/src/addon.cpp
new file mode 100644
index 0000000..3002410
--- /dev/null
+++ b/src/addon.cpp
@@ -0,0 +1,117 @@
+/**
+* @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/stats/base/smaxabs.h"
+#include
+#include
+#include
+#include
+#include
+
+/**
+* Add-on namespace.
+*/
+namespace stdlib_stats_base_smaxabs {
+
+ /**
+ * Computes the maximum absolute value of a single-precision floating-point strided array.
+ *
+ * ## Notes
+ *
+ * - When called from JavaScript, the function expects three arguments:
+ *
+ * - `N`: number of indexed elements
+ * - `X`: input array
+ * - `stride`: stride length
+ */
+ napi_value node_smaxabs( napi_env env, napi_callback_info info ) {
+ napi_status status;
+
+ size_t argc = 3;
+ napi_value argv[ 3 ];
+ status = napi_get_cb_info( env, info, &argc, argv, nullptr, nullptr );
+ assert( status == napi_ok );
+
+ if ( argc < 3 ) {
+ napi_throw_error( env, nullptr, "invalid invocation. Must provide 3 arguments." );
+ return nullptr;
+ }
+
+ napi_valuetype vtype0;
+ status = napi_typeof( env, argv[ 0 ], &vtype0 );
+ assert( status == napi_ok );
+ if ( vtype0 != napi_number ) {
+ napi_throw_type_error( env, nullptr, "invalid argument. First argument must be a number." );
+ return nullptr;
+ }
+
+ bool res;
+ status = napi_is_typedarray( env, argv[ 1 ], &res );
+ assert( status == napi_ok );
+ if ( res == false ) {
+ napi_throw_type_error( env, nullptr, "invalid argument. Second argument must be a Float32Array." );
+ return nullptr;
+ }
+
+ napi_valuetype vtype2;
+ status = napi_typeof( env, argv[ 2 ], &vtype2 );
+ assert( status == napi_ok );
+ if ( vtype2 != napi_number ) {
+ napi_throw_type_error( env, nullptr, "invalid argument. Third argument must be a number." );
+ return nullptr;
+ }
+
+ int64_t N;
+ status = napi_get_value_int64( env, argv[ 0 ], &N );
+ assert( status == napi_ok );
+
+ int64_t stride;
+ status = napi_get_value_int64( env, argv[ 2 ], &stride );
+ assert( status == napi_ok );
+
+ napi_typedarray_type vtype1;
+ size_t xlen;
+ void *X;
+ status = napi_get_typedarray_info( env, argv[ 1 ], &vtype1, &xlen, &X, nullptr, nullptr );
+ assert( status == napi_ok );
+ if ( vtype1 != napi_float32_array ) {
+ napi_throw_type_error( env, nullptr, "invalid argument. Second argument must be a Float32Array." );
+ return nullptr;
+ }
+ if ( (N-1)*llabs(stride) >= (int64_t)xlen ) {
+ napi_throw_range_error( env, nullptr, "invalid argument. Second argument has insufficient elements based on the associated stride and the number of indexed elements." );
+ return nullptr;
+ }
+
+ napi_value v;
+ status = napi_create_double( env, (double)stdlib_strided_smaxabs( N, (float *)X, stride ), &v );
+ assert( status == napi_ok );
+
+ return v;
+ }
+
+ napi_value Init( napi_env env, napi_value exports ) {
+ napi_status status;
+ napi_value fcn;
+ status = napi_create_function( env, "exports", NAPI_AUTO_LENGTH, node_smaxabs, NULL, &fcn );
+ assert( status == napi_ok );
+ return fcn;
+ }
+
+ NAPI_MODULE( NODE_GYP_MODULE_NAME, Init )
+} // end namespace stdlib_stats_base_smaxabs
diff --git a/src/smaxabs.c b/src/smaxabs.c
new file mode 100644
index 0000000..d800178
--- /dev/null
+++ b/src/smaxabs.c
@@ -0,0 +1,61 @@
+/**
+* @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/stats/base/smaxabs.h"
+#include "stdlib/math/base/assert/is_nanf.h"
+#include
+#include
+
+/**
+* Computes the maximum absolute value of a single-precision floating-point strided array.
+*
+* @param N number of indexed elements
+* @param X input array
+* @param stride stride length
+* @return output value
+*/
+float stdlib_strided_smaxabs( const int64_t N, const float *X, const int64_t stride ) {
+ int64_t ix;
+ int64_t i;
+ float max;
+ float v;
+
+ if ( N <= 0 ) {
+ return 0.0 / 0.0; // NaN
+ }
+ if ( N == 1 || stride == 0 ) {
+ return fabsf( X[ 0 ] );
+ }
+ if ( stride < 0 ) {
+ ix = (1-N) * stride;
+ } else {
+ ix = 0;
+ }
+ max = fabsf( X[ ix ] );
+ for ( i = 1; i < N; i++ ) {
+ ix += stride;
+ v = fabsf( X[ ix ] );
+ if ( stdlib_base_is_nanf( v ) ) {
+ return v;
+ }
+ if ( v > max ) {
+ max = v;
+ }
+ }
+ return max;
+}
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..e33e95b
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,82 @@
+/**
+* @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 proxyquire = require( 'proxyquire' );
+var IS_BROWSER = require( '@stdlib/assert-is-browser' );
+var smaxabs = require( './../lib' );
+
+
+// VARIABLES //
+
+var opts = {
+ 'skip': IS_BROWSER
+};
+
+
+// TESTS //
+
+tape( 'main export is a function', function test( t ) {
+ t.ok( true, __filename );
+ t.strictEqual( typeof smaxabs, 'function', 'main export is a function' );
+ t.end();
+});
+
+tape( 'attached to the main export is a method providing an ndarray interface', function test( t ) {
+ t.strictEqual( typeof smaxabs.ndarray, 'function', 'method is a function' );
+ t.end();
+});
+
+tape( 'if a native implementation is available, the main export is the native implementation', opts, function test( t ) {
+ var smaxabs = proxyquire( './../lib', {
+ '@stdlib/utils/try-require': tryRequire
+ });
+
+ t.strictEqual( smaxabs, mock, 'returns expected value' );
+ t.end();
+
+ function tryRequire() {
+ return mock;
+ }
+
+ function mock() {
+ // Mock...
+ }
+});
+
+tape( 'if a native implementation is not available, the main export is a JavaScript implementation', opts, function test( t ) {
+ var smaxabs;
+ var main;
+
+ main = require( './../lib/smaxabs.js' );
+
+ smaxabs = proxyquire( './../lib', {
+ '@stdlib/utils/try-require': tryRequire
+ });
+
+ t.strictEqual( smaxabs, main, 'returns expected value' );
+ t.end();
+
+ function tryRequire() {
+ return new Error( 'Cannot find module' );
+ }
+});
diff --git a/test/test.ndarray.js b/test/test.ndarray.js
new file mode 100644
index 0000000..85aa310
--- /dev/null
+++ b/test/test.ndarray.js
@@ -0,0 +1,177 @@
+/**
+* @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 floor = require( '@stdlib/math-base-special-floor' );
+var isnan = require( '@stdlib/math-base-assert-is-nan' );
+var isPositiveZero = require( '@stdlib/math-base-assert-is-positive-zero' );
+var Float32Array = require( '@stdlib/array-float32' );
+var smaxabs = require( './../lib/ndarray.js' );
+
+
+// TESTS //
+
+tape( 'main export is a function', function test( t ) {
+ t.ok( true, __filename );
+ t.strictEqual( typeof smaxabs, 'function', 'main export is a function' );
+ t.end();
+});
+
+tape( 'the function has an arity of 4', function test( t ) {
+ t.strictEqual( smaxabs.length, 4, 'has expected arity' );
+ t.end();
+});
+
+tape( 'the function calculates the maximum absolute value of a strided array', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0 ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -4.0, -5.0 ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -0.0, 0.0, -0.0 ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN, NaN ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `NaN`', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 0, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ v = smaxabs( -1, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter equal to `1`, the function returns the first indexed element', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 1, x, 1, 0 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports a `stride` parameter', function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 0
+ 2.0,
+ 2.0, // 1
+ -7.0,
+ -2.0, // 2
+ 3.0,
+ 4.0, // 3
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, 2, 0 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'the function supports a negative `stride` parameter', function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 3
+ 2.0,
+ 2.0, // 2
+ -7.0,
+ -2.0, // 1
+ 3.0,
+ 4.0, // 0
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, -2, 6 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'if provided a `stride` parameter equal to `0`, the function returns the first indexed element', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( x.length, x, 0, 0 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports an `offset` parameter', function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 2.0,
+ 1.0, // 0
+ 2.0,
+ -2.0, // 1
+ -2.0,
+ 2.0, // 2
+ 3.0,
+ 4.0 // 3
+ ]);
+ N = floor( x.length / 2 );
+
+ v = smaxabs( N, x, 2, 1 );
+ t.strictEqual( v, 4.0, 'returns expected value' );
+
+ t.end();
+});
diff --git a/test/test.ndarray.native.js b/test/test.ndarray.native.js
new file mode 100644
index 0000000..2cf6566
--- /dev/null
+++ b/test/test.ndarray.native.js
@@ -0,0 +1,186 @@
+/**
+* @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 floor = require( '@stdlib/math-base-special-floor' );
+var isnan = require( '@stdlib/math-base-assert-is-nan' );
+var isPositiveZero = require( '@stdlib/math-base-assert-is-positive-zero' );
+var Float32Array = require( '@stdlib/array-float32' );
+var tryRequire = require( '@stdlib/utils-try-require' );
+
+
+// VARIABLES //
+
+var smaxabs = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) );
+var opts = {
+ 'skip': ( smaxabs instanceof Error )
+};
+
+
+// TESTS //
+
+tape( 'main export is a function', opts, function test( t ) {
+ t.ok( true, __filename );
+ t.strictEqual( typeof smaxabs, 'function', 'main export is a function' );
+ t.end();
+});
+
+tape( 'the function has an arity of 4', opts, function test( t ) {
+ t.strictEqual( smaxabs.length, 4, 'has expected arity' );
+ t.end();
+});
+
+tape( 'the function calculates the maximum absolute value of a strided array', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0 ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -4.0, -5.0 ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -0.0, 0.0, -0.0 ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN, NaN ] );
+ v = smaxabs( x.length, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `NaN`', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 0, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ v = smaxabs( -1, x, 1, 0 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter equal to `1`, the function returns the first indexed element', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 1, x, 1, 0 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports a `stride` parameter', opts, function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 0
+ 2.0,
+ 2.0, // 1
+ -7.0,
+ -2.0, // 2
+ 3.0,
+ 4.0, // 3
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, 2, 0 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'the function supports a negative `stride` parameter', opts, function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 3
+ 2.0,
+ 2.0, // 2
+ -7.0,
+ -2.0, // 1
+ 3.0,
+ 4.0, // 0
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, -2, 6 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'if provided a `stride` parameter equal to `0`, the function returns the first indexed element', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( x.length, x, 0, 0 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports an `offset` parameter', opts, function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 2.0,
+ 1.0, // 0
+ 2.0,
+ -2.0, // 1
+ -2.0,
+ 2.0, // 2
+ 3.0,
+ 4.0 // 3
+ ]);
+ N = floor( x.length / 2 );
+
+ v = smaxabs( N, x, 2, 1 );
+ t.strictEqual( v, 4.0, 'returns expected value' );
+
+ t.end();
+});
diff --git a/test/test.smaxabs.js b/test/test.smaxabs.js
new file mode 100644
index 0000000..7a3c169
--- /dev/null
+++ b/test/test.smaxabs.js
@@ -0,0 +1,181 @@
+/**
+* @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 floor = require( '@stdlib/math-base-special-floor' );
+var isnan = require( '@stdlib/math-base-assert-is-nan' );
+var isPositiveZero = require( '@stdlib/math-base-assert-is-positive-zero' );
+var Float32Array = require( '@stdlib/array-float32' );
+var smaxabs = require( './../lib/smaxabs.js' );
+
+
+// TESTS //
+
+tape( 'main export is a function', function test( t ) {
+ t.ok( true, __filename );
+ t.strictEqual( typeof smaxabs, 'function', 'main export is a function' );
+ t.end();
+});
+
+tape( 'the function has an arity of 3', function test( t ) {
+ t.strictEqual( smaxabs.length, 3, 'has expected arity' );
+ t.end();
+});
+
+tape( 'the function calculates the maximum absolute value of a strided array', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0 ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -4.0, -5.0 ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -0.0, 0.0, -0.0 ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN, NaN ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `NaN`', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 0, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ v = smaxabs( -1, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter equal to `1`, the function returns the first element', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 1, x, 1 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports a `stride` parameter', function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 0
+ 2.0,
+ 2.0, // 1
+ -7.0,
+ -2.0, // 2
+ 3.0,
+ 4.0, // 3
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, 2 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'the function supports a negative `stride` parameter', function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 3
+ 2.0,
+ 2.0, // 2
+ -7.0,
+ -2.0, // 1
+ 3.0,
+ 4.0, // 0
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, -2 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'if provided a `stride` parameter equal to `0`, the function returns the first element', function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( x.length, x, 0 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports view offsets', function test( t ) {
+ var x0;
+ var x1;
+ var N;
+ var v;
+
+ x0 = new Float32Array([
+ 2.0,
+ 1.0, // 0
+ 2.0,
+ -2.0, // 1
+ -2.0,
+ 2.0, // 2
+ 3.0,
+ 4.0, // 3
+ 6.0
+ ]);
+
+ x1 = new Float32Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
+ N = floor(x1.length / 2);
+
+ v = smaxabs( N, x1, 2 );
+ t.strictEqual( v, 4.0, 'returns expected value' );
+
+ t.end();
+});
diff --git a/test/test.smaxabs.native.js b/test/test.smaxabs.native.js
new file mode 100644
index 0000000..321f3a3
--- /dev/null
+++ b/test/test.smaxabs.native.js
@@ -0,0 +1,272 @@
+/**
+* @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 floor = require( '@stdlib/math-base-special-floor' );
+var isnan = require( '@stdlib/math-base-assert-is-nan' );
+var isPositiveZero = require( '@stdlib/math-base-assert-is-positive-zero' );
+var Float32Array = require( '@stdlib/array-float32' );
+var tryRequire = require( '@stdlib/utils-try-require' );
+
+
+// VARIABLES //
+
+var smaxabs = tryRequire( resolve( __dirname, './../lib/smaxabs.native.js' ) );
+var opts = {
+ 'skip': ( smaxabs instanceof Error )
+};
+
+
+// TESTS //
+
+tape( 'main export is a function', opts, function test( t ) {
+ t.ok( true, __filename );
+ t.strictEqual( typeof smaxabs, 'function', 'main export is a function' );
+ t.end();
+});
+
+tape( 'the function has an arity of 3', opts, function test( t ) {
+ t.strictEqual( smaxabs.length, 3, 'has expected arity' );
+ t.end();
+});
+
+tape( 'the functions throws an error if provided a first argument which is not a number', opts, function test( t ) {
+ var values;
+ var i;
+
+ values = [
+ '5',
+ 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() {
+ smaxabs( value, new Float32Array( 10 ), 1 );
+ };
+ }
+});
+
+tape( 'the functions throws an error if provided a second argument which is not a Float32Array', opts, function test( t ) {
+ var values;
+ var i;
+
+ values = [
+ '5',
+ 5,
+ 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() {
+ smaxabs( 10, value, 1 );
+ };
+ }
+});
+
+tape( 'the functions throws an error if provided a third argument which is not a number', opts, function test( t ) {
+ var values;
+ var i;
+
+ values = [
+ '5',
+ 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() {
+ smaxabs( 10, new Float32Array( 10 ), value );
+ };
+ }
+});
+
+tape( 'the function calculates the maximum absolute value of a strided array', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0 ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -4.0, -5.0 ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( v, 5.0, 'returns expected value' );
+
+ x = new Float32Array( [ -0.0, 0.0, -0.0 ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ x = new Float32Array( [ NaN, NaN ] );
+ v = smaxabs( x.length, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `NaN`', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 0, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ v = smaxabs( -1, x, 1 );
+ t.strictEqual( isnan( v ), true, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'if provided an `N` parameter equal to `1`, the function returns the first element', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( 1, x, 1 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports a `stride` parameter', opts, function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 0
+ 2.0,
+ 2.0, // 1
+ -7.0,
+ -2.0, // 2
+ 3.0,
+ 4.0, // 3
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, 2 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'the function supports a negative `stride` parameter', opts, function test( t ) {
+ var N;
+ var x;
+ var v;
+
+ x = new Float32Array([
+ 1.0, // 3
+ 2.0,
+ 2.0, // 2
+ -7.0,
+ -2.0, // 1
+ 3.0,
+ 4.0, // 0
+ 2.0
+ ]);
+
+ N = floor( x.length / 2 );
+ v = smaxabs( N, x, -2 );
+
+ t.strictEqual( v, 4.0, 'returns expected value' );
+ t.end();
+});
+
+tape( 'if provided a `stride` parameter equal to `0`, the function returns the first element', opts, function test( t ) {
+ var x;
+ var v;
+
+ x = new Float32Array( [ -1.0, -2.0, -4.0, 5.0, 3.0 ] );
+
+ v = smaxabs( x.length, x, 0 );
+ t.strictEqual( v, 1.0, 'returns expected value' );
+
+ t.end();
+});
+
+tape( 'the function supports view offsets', opts, function test( t ) {
+ var x0;
+ var x1;
+ var N;
+ var v;
+
+ x0 = new Float32Array([
+ 2.0,
+ 1.0, // 0
+ 2.0,
+ -2.0, // 1
+ -2.0,
+ 2.0, // 2
+ 3.0,
+ 4.0, // 3
+ 6.0
+ ]);
+
+ x1 = new Float32Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
+ N = floor(x1.length / 2);
+
+ v = smaxabs( N, x1, 2 );
+ t.strictEqual( v, 4.0, 'returns expected value' );
+
+ t.end();
+});