diff --git a/lib/node_modules/@stdlib/math/base/special/powf/LICENSE b/lib/node_modules/@stdlib/math/base/special/powf/LICENSE new file mode 100644 index 000000000000..a7566ad6f2c3 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/LICENSE @@ -0,0 +1,192 @@ + + 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 + +DEPENDENCIES & ATTRIBUTION + +The library links against the following external libraries or 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. diff --git a/lib/node_modules/@stdlib/math/base/special/powf/README.md b/lib/node_modules/@stdlib/math/base/special/powf/README.md new file mode 100644 index 000000000000..4a67542d9810 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/README.md @@ -0,0 +1,240 @@ + + +# Exponential Function + +> [Exponential function][exponential-function]. + +
+ +The [exponential function][exponential-function] is defined as + + + +```math +y = b^x +``` + + + + + +where `b` is the **base** and `x` is the **exponent**. + +
+ + + +
+ +## Usage + +```javascript +var powf = require( '@stdlib/math/base/special/powf' ); +``` + +#### powf( base, exponent ) + +Evaluates the [exponential function][exponential-function] for single-precision floating-point values. + +```javascript +var v = powf( 2.0, 3.0 ); +// returns 8.0 + +v = powf( 4.0, 0.5 ); +// returns 2.0 + +v = powf( 100.0, 0.0 ); +// returns 1.0 + +v = powf( 3.1415927410125732, 5.0 ); +// returns ~306.0197 + +v = powf( 3.1415927410125732, -0.2 ); +// returns ~0.7954 + +v = powf( NaN, 3.0 ); +// returns NaN + +v = powf( 5.0, NaN ); +// returns NaN + +v = powf( NaN, NaN ); +// returns NaN +``` + +
+ + + +
+ +## Examples + + + +```javascript +var randu = require( '@stdlib/random/base/randu' ); +var roundf = require( '@stdlib/math/base/special/roundf' ); +var powf = require( '@stdlib/math/base/special/powf' ); + +var b; +var x; +var i; + +for ( i = 0; i < 100; i++ ) { + b = roundf( randu()*10.0 ); + x = roundf( randu()*10.0 ) - 5.0; + console.log( '%d^%d = %d', b, x, powf( b, x ) ); +} +``` + +
+ + + + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/math/base/special/powf.h" +``` + +#### stdlib_base_powf( base, exponent ) + +Evaluates the exponential function for single-precision floating-point values. + +```c +float out = stdlib_base_powf( 3.1415927410125732f, 5.0f ); +// returns ~306.0197f + +out = stdlib_base_powf( 4.0f, 0.5f ); +// returns 2.0f +``` + +The function accepts the following arguments: + +- **base**: `[in] float` base. +- **exponent**: `[in] float` exponent. + +```c +float stdlib_base_powf( const float base, const float exponent ); +``` + +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/math/base/special/powf.h" +#include +#include + +int main( void ) { + float out; + float b; + float x; + int i; + + for ( i = 0; i < 100; i++ ) { + b = ( ( (float)rand() / (float)RAND_MAX ) * 10.0f ); + x = ( ( (float)rand() / (float)RAND_MAX ) * 10.0f ) - 5.0f; + out = stdlib_base_powf( b, x ); + printf( "powf(%f, %f) = %f\n", b, x, out ); + } +} +``` + +
+ + + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/math/base/special/powf/benchmark/benchmark.js b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/benchmark.js new file mode 100644 index 000000000000..1ea8ca5cdd32 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/benchmark.js @@ -0,0 +1,76 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF 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 isnanf = require( '@stdlib/math/base/assert/is-nan' ); +var pkg = require( './../package.json' ).name; +var powf = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var x; + var y; + var z; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + x = ( randu()*100.0 ) - 0.0; + y = ( randu()*100.0 ) - 50.0; + z = powf( x, y ); + if ( isnanf( z ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnanf( z ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::built-in', function benchmark( b ) { + var x; + var y; + var z; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + x = ( randu()*100.0 ) - 0.0; + y = ( randu()*100.0 ) - 50.0; + z = Math.powf( x, y ); // eslint-disable-line stdlib/no-builtin-math + if ( isnanf( z ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnanf( z ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/powf/benchmark/benchmark.native.js b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/benchmark.native.js new file mode 100644 index 000000000000..a6061673bc92 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/benchmark.native.js @@ -0,0 +1,62 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF 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 isnanf = require( '@stdlib/math/base/assert/is-nan' ); +var tryRequire = require( '@stdlib/utils/try-require' ); +var pkg = require( './../package.json' ).name; + + +// VARIABLES // + +var powf = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( powf instanceof Error ) +}; + + +// MAIN // + +bench( pkg+'::native', opts, function benchmark( b ) { + var v; + var x; + var y; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = ( randu()*100.0 ) - 0.0; + x = ( randu()*100.0 ) - 50.0; + y = powf( v, x ); + if ( isnanf( y ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnanf( y ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/Makefile b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/Makefile new file mode 100644 index 000000000000..d564e8b2d6f9 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/Makefile @@ -0,0 +1,127 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles C source files. +# +# @param {string} [C_COMPILER] - C compiler +# @param {string} [CFLAGS] - C compiler flags +# @param {(string|void)} [fPIC] - compiler flag indicating whether to generate position independent code +# +# @example +# make +# +# @example +# make all +#/ +all: $(c_targets) + +.PHONY: all + +#/ +# Compiles C source files. +# +# @private +# @param {string} CC - C compiler +# @param {string} CFLAGS - C compiler flags +# @param {(string|void)} fPIC - compiler flag indicating whether to generate position independent code +#/ +$(c_targets): %.out: %.c + $(QUIET) $(CC) $(CFLAGS) $(fPIC) -o $@ $< -lm + +#/ +# 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/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/benchmark.c b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/benchmark.c new file mode 100644 index 000000000000..c25def4fd0c3 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/benchmark.c @@ -0,0 +1,134 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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 +#include +#include +#include +#include + +#define NAME "powf" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +static void print_version( void ) { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +static void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +static void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +static double tic( void ) { + 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 +*/ +static float rand_float( void ) { + int r = rand(); + return (float)r / ( (float)RAND_MAX + 1.0f ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +static double benchmark( void ) { + double elapsed; + float x; + float y; + float z; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + x = ( 100.0f*rand_float() ) - 0.0f; + y = ( 100.0f*rand_float() ) - 50.0f; + z = powf( x, y ); + if ( z != z ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( z != z ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/native/Makefile b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/native/Makefile new file mode 100644 index 000000000000..a4bd7b38fd74 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/native/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# VARIABLES # + +ifndef VERBOSE + QUIET := @ +else + QUIET := +endif + +# Determine the OS ([1][1], [2][2]). +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define the program used for compiling C source files: +ifdef C_COMPILER + CC := $(C_COMPILER) +else + CC := gcc +endif + +# Define the command-line options when compiling C files: +CFLAGS ?= \ + -std=c99 \ + -O3 \ + -Wall \ + -pedantic + +# Determine whether to generate position independent code ([1][1], [2][2]). +# +# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options +# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option +ifeq ($(OS), WINNT) + fPIC ?= +else + fPIC ?= -fPIC +endif + +# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`): +INCLUDE ?= + +# List of source files: +SOURCE_FILES ?= + +# List of libraries (e.g., `-lopenblas -lpthread`): +LIBRARIES ?= + +# List of library paths (e.g., `-L /foo/bar -L /beep/boop`): +LIBPATH ?= + +# List of C targets: +c_targets := benchmark.out + + +# RULES # + +#/ +# Compiles 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/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/native/benchmark.c b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/native/benchmark.c new file mode 100644 index 000000000000..f9f2870f73aa --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/benchmark/c/native/benchmark.c @@ -0,0 +1,135 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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/math/base/special/powf.h" +#include +#include +#include +#include +#include + +#define NAME "powf" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +static void print_version( void ) { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +static void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +static void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +static double tic( void ) { + 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 +*/ +static float rand_float( void ) { + int r = rand(); + return (float)r / ( (float)RAND_MAX + 1.0f ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +static double benchmark( void ) { + double elapsed; + float b; + float x; + float y; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + b = rand_float() * 10.0f; + x = rand_float() * 5.0f; + y = stdlib_base_powf( b, x ); + if ( y != y ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( y != y ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} diff --git a/lib/node_modules/@stdlib/math/base/special/powf/binding.gyp b/lib/node_modules/@stdlib/math/base/special/powf/binding.gyp new file mode 100644 index 000000000000..68a1ca11d160 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/binding.gyp @@ -0,0 +1,170 @@ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/lib/node_modules/@stdlib/math/base/special/powf/docs/repl.txt b/lib/node_modules/@stdlib/math/base/special/powf/docs/repl.txt new file mode 100644 index 000000000000..1deebef3a4c1 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/docs/repl.txt @@ -0,0 +1,39 @@ + +{{alias}}( b, x ) + Evaluates the exponential function `bˣ` for single-precision floating-point values. + + Parameters + ---------- + b: number + Base. + + x: number + Exponent. + + Returns + ------- + y: number + Function value. + + Examples + -------- + > var y = {{alias}}( 2.0, 3.0 ) + 8.0 + > y = {{alias}}( 4.0, 0.5 ) + 2.0 + > y = {{alias}}( 100.0, 0.0 ) + 1.0 + > y = {{alias}}( {{alias:@stdlib/constants/float32/pi}}, 5.0 ) + ~306.0197 + > y = {{alias}}( {{alias:@stdlib/constants/float32/pi}}, -0.2 ) + ~0.7954 + > y = {{alias}}( NaN, 3.0 ) + NaN + > y = {{alias}}( 5.0, NaN ) + NaN + > y = {{alias}}( NaN, NaN ) + NaN + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/math/base/special/powf/docs/types/index.d.ts b/lib/node_modules/@stdlib/math/base/special/powf/docs/types/index.d.ts new file mode 100644 index 000000000000..780029179f9e --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/docs/types/index.d.ts @@ -0,0 +1,65 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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: 4.1 + +/** +* Evaluates the exponential function for single-precision floating-point values. +* +* @param b - base +* @param x - exponent +* @returns function value +* +* @example +* var v = powf( 2.0, 3.0 ); +* // returns 8.0 +* +* @example +* var v = powf( 4.0, 0.5 ); +* // returns 2.0 +* +* @example +* var v = powf( 100.0, 0.0 ); +* // returns 1.0 +* +* @example +* var v = powf( 3.1415927410125732, 5.0 ); +* // returns ~306.0197 +* +* @example +* var v = powf( 3.1415927410125732, -0.2 ); +* // returns ~0.7954 +* +* @example +* var v = powf( NaN, 3.0 ); +* // returns NaN +* +* @example +* var v = powf( 5.0, NaN ); +* // returns NaN +* +* @example +* var v = powf( NaN, NaN ); +* // returns NaN +*/ +declare function powf( b: number, x: number ): number; + + +// EXPORTS // + +export = powf; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/docs/types/test.ts b/lib/node_modules/@stdlib/math/base/special/powf/docs/types/test.ts new file mode 100644 index 000000000000..65810932a669 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/docs/types/test.ts @@ -0,0 +1,56 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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 powf = require( './index' ); + + +// TESTS // + +// The function returns a number... +{ + powf( 8, 2 ); // $ExpectType number +} + +// The compiler throws an error if the function is provided values other than two numbers... +{ + powf( true, 3 ); // $ExpectError + powf( false, 2 ); // $ExpectError + powf( '5', 1 ); // $ExpectError + powf( [], 1 ); // $ExpectError + powf( {}, 2 ); // $ExpectError + powf( ( x: number ): number => x, 2 ); // $ExpectError + + powf( 9, true ); // $ExpectError + powf( 9, false ); // $ExpectError + powf( 5, '5' ); // $ExpectError + powf( 8, [] ); // $ExpectError + powf( 9, {} ); // $ExpectError + powf( 8, ( x: number ): number => x ); // $ExpectError + + powf( [], true ); // $ExpectError + powf( {}, false ); // $ExpectError + powf( false, '5' ); // $ExpectError + powf( {}, [] ); // $ExpectError + powf( '5', ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided insufficient arguments... +{ + powf(); // $ExpectError + powf( 3 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/math/base/special/powf/examples/c/Makefile b/lib/node_modules/@stdlib/math/base/special/powf/examples/c/Makefile new file mode 100644 index 000000000000..25ced822f96a --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/lib/node_modules/@stdlib/math/base/special/powf/examples/c/example.c b/lib/node_modules/@stdlib/math/base/special/powf/examples/c/example.c new file mode 100644 index 000000000000..83d68964bb42 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/examples/c/example.c @@ -0,0 +1,35 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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/math/base/special/powf.h" +#include +#include + +int main( void ) { + float out; + float b; + float x; + int i; + + for ( i = 0; i < 100; i++ ) { + b = ( ( (float)rand() / (float)RAND_MAX ) * 10.0f ); + x = ( ( (float)rand() / (float)RAND_MAX ) * 10.0f ) - 5.0f; + out = stdlib_base_powf( b, x ); + printf( "powf(%f, %f) = %f\n", b, x, out ); + } +} diff --git a/lib/node_modules/@stdlib/math/base/special/powf/examples/index.js b/lib/node_modules/@stdlib/math/base/special/powf/examples/index.js new file mode 100644 index 000000000000..e389258c36a6 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/examples/index.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR 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 roundf = require( '@stdlib/math/base/special/roundf' ); +var powf = require('./../lib'); + +var b; +var x; +var i; + +for ( i = 0; i < 100; i++ ) { + b = roundf( randu()*10.0 ); + x = roundf( randu()*10.0 ) - 5.0; + console.log( '%d^%d = %d', b, x, powf( b, x ) ); +} diff --git a/lib/node_modules/@stdlib/math/base/special/powf/include.gypi b/lib/node_modules/@stdlib/math/base/special/powf/include.gypi new file mode 100644 index 000000000000..ecfaf82a3279 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/include.gypi @@ -0,0 +1,53 @@ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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': [ + ' 0 00000000000 10000000000000000000 +var HIGH_MIN_NORMAL_EXP = 0x00800000; // asm type annotation + +// 0x3f800000 = 1065353216 => 0 01111111000 00000000000000000000 +var HIGH_BIASED_EXP_0 = 0x3f800000; // asm type annotation + +// 0xfffff000 = 4294963200 => 1 11111111111 11111111111100000000 +var HIGH_BIASED_EXP_NEG_64 = 0xfffff000; // asm type annotation + +// 0x20000000 = 536870912 => 0 10000000000 00000000000000000000 +var HIGH_SIGNIFICAND_HALF = 0x20000000; // asm type annotation + +// 0x00400000 = 4194304 => 0 00000000000 10000000000000000000 +var HIGH_MIN_NORMAL_EXP_HALF = 0x00400000; // asm type annotation + +var TWO24 = 16777216.0; // 0x4b800000 + +// 2/(3*LN2) +var CP = 9.6179670095e-01; // 0x3f76384f =2/(3ln2) + +// (float)CP +var CP_HI = 9.6191406250e-01; // 0x3f764000 =12b cp + +// Low: CP_HI +var CP_LO = -1.1736857402e-04; // 0xb8f623c6 =tail of CP_HI + +var BP = [ + 1.0, + 1.5 +]; +var DP_HI = [ + 0.0, + 5.84960938e-01 // 0x3f15c000 +]; +var DP_LO = [ + 0.0, + 1.56322085e-06 // 0x35d1cfdc +]; + + +// MAIN // + +/** +* Computes \\(\operatorname{log2}(ax)\\). +* +* @private +* @param {Array} out - output array +* @param {number} ax - absolute value of `x` +* @param {number} ahx - high word of `ax` +* @returns {Array} output array containing a tuple comprised of high and low parts +* +* @example +* var t = log2ax( [ 0.0, 0.0 ], 9.0, 1075970048 ); // => [ t1, t2 ] +* // returns [ 3.169923782348633, 0.0000012190936795504075 ] +*/ +function log2ax( out, ax, ahx ) { + var ahs; + var ss; // `hs + ls` + var s2; // `ss` squared + var hs; + var ls; + var ht; + var lt; + var bp; // `BP` constant + var dp; // `DP` constant + var hp; + var lp; + var hz; + var lz; + var t1; + var t2; + var t; + var r; + var u; + var v; + var n; + var j; + var k; + + n = 0; // asm type annotation + + // Check if `x` is subnormal... + if ( ahx < HIGH_MIN_NORMAL_EXP ) { + ax *= TWO24; + n -= 24; // asm type annotation + ahx = fromWordf( ax ); + } + // Extract the unbiased exponent of `x`: + n += ((ahx >> (FLOAT32_PRECISION -1) ) - FLOAT32_EXPONENT_BIAS); // asm type annotation + + // Isolate the significand bits of `x`: + j = (ahx & FLOAT32_SIGNIFICAND_MASK); // asm type annotation + + // Normalize `ahx` by setting the (biased) exponent to `127`: + ahx = (j | HIGH_BIASED_EXP_0); // asm type annotation + + // Determine the interval of `|x|` by comparing significand bits... + + // |x| < sqrt(3/2) + if ( j <= 0x1cc471 ) { // 0 00000000001 11001100100010001110 + k = 0; + } + // |x| < sqrt(3) + else if ( j < 0x5db3d7 ) { // 0 00000000010 11101101100111110111 + k = 1; + } + // |x| >= sqrt(3) + else { + k = 0; + n += 1; // asm type annotation + ahx -= HIGH_MIN_NORMAL_EXP; + } + // Load the normalized float word into `|x|`: + ahx = float64ToFloat32( ahx ); + ax = toWordf( ahx ); + + // Compute `ss = hs + ls = (x-1)/(x+1)` or `(x-1.5)/(x+1.5)`: + bp = float64ToFloat32( BP[ k ] ); // BP[0] = 1.0, BP[1] = 1.5 + u = float64ToFloat32( ax - bp ); // (x-1) || (x-1.5) + v = float64ToFloat32( 1.0 / float64ToFloat32(ax + bp) ); // 1/(x+1) || 1/(x+1.5) + ss = float64ToFloat32( u * v ); + hs = float64ToFloat32( ss ); + ahs = fromWordf( hs ); + ahs = float64ToFloat32( ahs & HIGH_BIASED_EXP_NEG_64 ) + hs = toWordf( ahs ); + + // Compute `ht = ax + bp` High + ahs = ((ahx>>1) & HIGH_BIASED_EXP_NEG_64) | HIGH_SIGNIFICAND_HALF; + ahs += HIGH_MIN_NORMAL_EXP_HALF+(k << 21); // `(k<<21)` can be considered the word equivalent of `1.0` or `1.5` + ahs = float64ToFloat32( ahs ); + ht = toWordf( ahs ); + lt = float64ToFloat32( ax - float64ToFloat32(ht - bp) ); + ls = float64ToFloat32( v * ( float64ToFloat32( u - float64ToFloat32(hs*ht) ) - float64ToFloat32( hs*lt ) ) ); // eslint-disable-line max-len + + // Compute `log(ax)`... + + s2 = float64ToFloat32( ss * ss); + r = float64ToFloat32( s2 * s2 * float64ToFloat32( polyvalL( s2 ))); + r += float64ToFloat32( ls * float64ToFloat32(hs + ss)); + s2 = float64ToFloat32( hs * hs ); + ht = float64ToFloat32( 3.0 + s2 + r ); + ahs = fromWordf( ht ); + ahs = float64ToFloat32( ahs & HIGH_BIASED_EXP_NEG_64 ); + ht = toWordf( ahs ); + lt = float64ToFloat32( r - float64ToFloat32((ht-3.0) - s2)); + + // u+v = ss*(1+...): + u = float64ToFloat32( hs * ht ); + v = float64ToFloat32( float64ToFloat32( ls*ht ) + float64ToFloat32( lt*ss )); // eslint-disable-line max-len + + // 2/(3LN2) * (ss+...): + hp = u + v; + ahs = fromWordf( hp ); + ahs = float64ToFloat32( ahs & HIGH_BIASED_EXP_NEG_64 ); + hp = toWordf( ahs ); + lp = float64ToFloat32( v - float64ToFloat32(hp - u)); + hz = float64ToFloat32( CP_HI * hp ); // CP_HI+CP_LO = 2/(3*LN2) + lz = float64ToFloat32( float64ToFloat32( CP_LO*hp ) + float64ToFloat32( lp*CP ) + DP_LO[ k ]); // eslint-disable-line max-len + + // log2(ax) = (ss+...)*2/(3*LN2) = n + dp + hz + lz + dp = float64ToFloat32( DP_HI[ k ] ); + t = float64ToFloat32( n ); + // log2(ax) + t1 = float64ToFloat32(( float64ToFloat32(hz+lz) + float64ToFloat32( dp )) + float64ToFloat32( t )); // eslint-disable-line max-len + ahs = fromWordf( t1 ); + ahs = float64ToFloat32( ahs & HIGH_BIASED_EXP_NEG_64 ); + t1 = toWordf( ahs ); + t2 = float64ToFloat32( lz - float64ToFloat32(((t1-t) - dp) - float64ToFloat32( hz ))); // eslint-disable-line max-len + + return out; +} + + +// EXPORTS // + +module.exports = log2ax; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/logx.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/logx.js new file mode 100644 index 000000000000..6198c6b4ae5d --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/logx.js @@ -0,0 +1,97 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* +* ## Notice +* +* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/12.2.0/lib/msun/src/e_powf.c}. The implementation follows the original, but has been modified for JavaScript. +* +* ```text +* 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. +* ``` +*/ + +'use strict'; + +// MODULES // + +var fromWordf = require( '@stdlib/number/float32/base/from-word' ); +var toWordf = require( '@stdlib/number/float32/base/to-word' ); +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); +var polyvalW = require( './polyval_w.js' ); + + +// VARIABLES // + +// 0xfffff000 = 4294963200 => 1 11111111111 11111111111100000000 +var HIGH_BIASED_EXP_NEG_64 = 0xfffff000; // asm type annotation + +// 1/LN2 +var INV_LN2 = 1.4426950216e+00; // 0x3fb8aa3b =1/ln2 + +// High (16 bits): 1/LN2 +var INV_LN2_HI = 1.4426879883e+00; // 0x3fb8aa00 =16b 1/ln2 + +// Low: 1/LN2 +var INV_LN2_LO = 7.0526075433e-06; // 0x36eca570 =1/ln2 tail + + +// MAIN // + +/** +* Computes \\(\operatorname{log}(x)\\) assuming \\(|1-x|\\) is small and using the approximation \\(x - x^2/2 + x^3/3 - x^4/4\\). +* +* @private +* @param {Array} out - output array +* @param {number} ax - absolute value of `x` +* @returns {Array} output array containing a tuple comprised of high and low parts +* +* @example +* var t = logx( [ 0.0, 0.0 ], 9.0 ); +* // Expected output: [ -1265.7236328125, -0.0008163940840404393 ] +*/ +function logx( out, ax ) { + var ahs; + var t2; + var t1; + var t; + var w; + var u; + var v; + + t = float64ToFloat32( ax - 1.0 ); // `t` has `20` trailing zeros + w = float64ToFloat32( t * t * float64ToFloat32( polyvalW( t ) ) ); + u = float64ToFloat32( INV_LN2_HI * t ); // `INV_LN2_HI` has `16` significant bits + v = float64ToFloat32( float64ToFloat32( t*INV_LN2_LO ) - float64ToFloat32( w*INV_LN2 ) ); // eslint-disable-line max-len + t1 = float64ToFloat32( u + v ); + ahs = fromWordf( t1 ); + ahs = float64ToFloat32( ahs & HIGH_BIASED_EXP_NEG_64 ); + t1 = toWordf( ahs ); + t2 = float64ToFloat32( float64ToFloat32( v ) - float64ToFloat32( t1 - u) ); + + return out; +} + + +// EXPORTS // + +module.exports = logx; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/main.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/main.js new file mode 100644 index 000000000000..54b8cbf14100 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/main.js @@ -0,0 +1,297 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* +* ## Notice +* +* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/12.2.0/lib/msun/src/e_powf.c}. The implementation follows the original, but has been modified for JavaScript. +* +* ```text +* 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. +* ``` +*/ + +'use strict'; + +// MODULES // + +var isOddf = require( '@stdlib/math/base/assert/is-oddf' ); +var isInfinitef = require( '@stdlib/math/base/assert/is-infinitef' ); +var isInteger = require( '@stdlib/math/base/assert/is-integer' ); +var sqrtf = require( '@stdlib/math/base/special/sqrtf' ); +var absf = require( '@stdlib/math/base/special/absf' ); +var fromWordf = require( '@stdlib/number/float32/base/from-word' ); +var toWordf = require( '@stdlib/number/float32/base/to-word' ); +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); +var NINF = require( '@stdlib/constants/float32/ninf' ); +var PINF = require( '@stdlib/constants/float32/pinf' ); +var FLOAT32_ABS_MASK = require( '@stdlib/constants/float32/abs-mask' ); +var xIsZero = require( './x_is_zero.js' ); +var yIsInfinite = require( './y_is_infinite.js' ); +var log2ax = require( './log2ax.js' ); +var logx = require( './logx.js' ); +var pow2 = require( './pow2.js' ); + + +// VARIABLES // + +// 0x3f7ffff8 = 1065353216 => 0 01111111011 11111111111111111000 => biased exponent: 126 = -1+127 => 2^-1 * (1.999999) +var HIGH_MAX_NEAR_UNITY = 0x3f7ffff8; // asm type annotation + +// 0x4d000000 = 1291845632 => 0 10011010000 00000000000000000000 => biased exponent: 208 = 81+127 => 2^81 +var HIGH_BIASED_EXP_27 = 0x4d000000; // asm type annotation + +// 0x43000000 = 1124073472 => 0 10000110000 00000000000000000000 => biased exponent: 96 = -31+127 => 2^16 +var SMALL_BIASED_EXP_10 = 0x43000000; // asm type annotation + +// 0x3f800007 = 1065353223 => 0 01111111100 00000000000000000111 => biased exponent: 127 = 0+127 => 2^0 * (1.0000000007) +var BIASED_EXP_0 = 0x3f800007; // asm type annotation + +// 0xfffff000 = 4294963200 => 1 11111111111 11111111111100000000 +var HIGH_BIASED_EXP_NEG_64 = 0xfffff000; // asm type annotation + +// 0x43160000 = 1128275968 => 0 10000110011 00000000000000000000 => biased exponent: 99 = -28+127 => 2^22 +var SMALL_60 = 0x43160000; // asm type annotation + +// 0xc3160000 = 3273056256 => 1 10000110011 00000000000000000000 => biased exponent: 99 = -28+127 => -2^22 +var SMALL_NEG_60 = 0xc3160000>>>0; // asm type annotation + +var HUGE = 1.0e30; +var TINY = 1.0e-30; + +// -(128-log2(ovfl+.5ulp)) +var OVT = 4.2995665694e-08; + +// Log workspace: +var LOG_WORKSPACE = 0.0; + + +// MAIN // + +/** +* Evaluates the exponential function for single-precision floating-point values. +* +* @param {number} x - base +* @param {number} y - exponent +* @returns {number} function value +* +* @example +* var v = powf( 2.0, 3.0 ); +* // returns 8.0 +* +* @example +* var v = powf( 4.0, 0.5 ); +* // returns 2.0 +* +* @example +* var v = powf( 100.0, 0.0 ); +* // returns 1.0 +* +* @example +* var v = powf( 3.1415927410125732, 5.0 ); +* // returns ~306.0197 +* +* @example +* var v = powf( 3.1415927410125732, -0.2 ); +* // returns ~0.7954 +* +* @example +* var v = powf( NaN, 3.0 ); +* // returns NaN +* +* @example +* var v = powf( 5.0, NaN ); +* // returns NaN +* +* @example +* var v = powf( NaN, NaN ); +* // returns NaN +*/ +function powf( x, y ) { + var ahs; + var ahx; + var ahy; + var ax; + var hx; + var hy; + var hp; + var lp; + var sn; + var y1; + var t1; + var t2; + var hp; + var lp; + var z; // y prime + var t; + var j; + + x = float64ToFloat32( x ); + hx = toWordf( x ); + y = float64ToFloat32( y ); + hy = toWordf( y ); + + // Special cases `y`... + if ( y === 0.0 ) { + return 1.0; + } + if ( y === 1.0 ) { + return x; + } + if ( y === -1.0 ) { + return 1.0 / x; + } + if ( y === 0.5 ) { + return sqrtf( x ); + } + if ( y === -0.5 ) { + return 1.0 / sqrtf( x ); + } + if ( y === 2.0 ) { + return x * x; + } + if ( y === 3.0 ) { + return x * x * x; + } + if ( y === 4.0 ) { + x *= x; + return x * x; + } + if ( isInfinitef( y ) ) { // y is +-inf + return yIsInfinite( x, y ); + } + + // Special cases `x`... + if ( hx === 0 ) { + return xIsZero( x, y ); + } + if ( x === 1.0 ) { + return 1.0; + } + if ( + x === -1.0 && + isOddf( y ) + ) { + return -1.0; + } + if ( isInfinitef( x ) ) { + if ( x === NINF ) { + // `pow( 1/x, -y )` + return powf( -0.0, -y ); + } + if ( y < 0.0 ) { + return 0.0; + } + return PINF; + } + if ( + x < 0.0 && + isInteger( y ) === false + ) { + // Signal NaN... + return (x-x)/(x-x); // (-1)**non-int is NaN + } + ax = absf( x ); + + // Remove the sign bits (i.e., get absolute values): + ahx = (hx & FLOAT32_ABS_MASK); // asm type annotation + ahy = (hy & FLOAT32_ABS_MASK); // asm type annotation + + if ( sn && isOddf( y ) ) { + sn = -1.0; + } else { + sn = 1.0; + } + // Case 1: `|y|` is huge + + // if |y| > 2^27 + if( ahy > HIGH_BIASED_EXP_27 ) { + // Over- or underflow if `x` is not close to unity... + if ( ahx < HIGH_MAX_NEAR_UNITY ) { + // y < 0 + if ( sn === 1 ) { + // Signal overflow... + return sn * HUGE * HUGE; + } + // Signal underflow... + return sn * TINY * TINY; + } + if ( ahx > BIASED_EXP_0 ) { + // y > 0 + if ( sn === 0 ) { + // Signal overflow... + return sn * HUGE * HUGE; + } + // Signal underflow... + return sn * TINY * TINY; + } + // At this point, `|1-x|` is tiny (`<= 2^-20`). Suffice to compute `log(x)` by `x - x^2/2 + x^3/3 - x^4/4`. + t = logx( LOG_WORKSPACE, ax ); + } + // Case 2: `|y|` is not huge... + else { + t = log2ax( LOG_WORKSPACE, ax, ahx ); + } + // Split `y` into `y1 + y2` and compute `(y1+y2) * (t1+t2)`... + ahs = fromWordf( y ); + ahs = float64ToFloat32( ahs & HIGH_BIASED_EXP_NEG_64 ); + y1 = toWordf( ahs ); + lp = float64ToFloat32(float64ToFloat32( float64ToFloat32(y-y1)*t1 ) + float64ToFloat32( y*t2 )); // eslint-disable-line max-len + hp = float64ToFloat32( y1 * t1 ); + z = float64ToFloat32( lp + hp ); + j = fromWordf( z ); + + + // z > 128 + if ( j > SMALL_BIASED_EXP_10 ) { + // Signal overflow + return sn * HUGE * HUGE; + } + // z == 128 + else if ( j === SMALL_BIASED_EXP_10 ) { + if ( (lp+OVT) > (z-hp) ) { + // Signal overflow... + return sn * HUGE * HUGE; + } + } + // z <= -150 + else if ( (j&FLOAT32_ABS_MASK) > SMALL_60 ) { + // Signal underflow... + return sn * TINY * TINY; + } + // z == -150 + else if ( j === SMALL_NEG_60 ) { + if( lp <= (z-hp) ) { + // Signal underflow... + return sn * TINY * TINY; + } + } + // Compute `2^(hp+lp)`... + z = pow2( j, hp, lp ); + + return sn * z; +} + + +// EXPORTS // + +module.exports = powf; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/native.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/native.js new file mode 100644 index 000000000000..2a9d6257e5fe --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/native.js @@ -0,0 +1,74 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF 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 // + +/** +* Evaluates the exponential function for single-precision floating-point values. +* +* @private +* @param {number} x - base +* @param {number} y - exponent +* @returns {number} function value +* +* @example +* var v = powf( 2.0, 3.0 ); +* // returns 8.0 +* +* @example +* var v = powf( 4.0, 0.5 ); +* // returns 2.0 +* +* @example +* var v = powf( 100.0, 0.0 ); +* // returns 1.0 +* +* @example +* var v = powf( 3.1415927410125732, 5.0 ); +* // returns ~306.0197 +* +* @example +* var v = powf( 3.1415927410125732, -0.2 ); +* // returns ~0.7954 +* +* @example +* var v = powf( NaN, 3.0 ); +* // returns NaN +* +* @example +* var v = powf( 5.0, NaN ); +* // returns NaN +* +* @example +* var v = powf( NaN, NaN ); +*/ +function powf( x, y ) { + return addon( x, y ); +} + + +// EXPORTS // + +module.exports = powf; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_l.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_l.js new file mode 100644 index 000000000000..5d4f749e8559 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_l.js @@ -0,0 +1,47 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* This is a generated file. Do not edit directly. */ +'use strict'; + +// MAIN // + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the polynomial +* @returns {number} evaluated polynomial +*/ +function evalpoly( x ) { + if ( x === 0.0 ) { + return 0.60000002384; + } + return 0.60000002384 + (x * (0.42857143283 + (x * (0.33333334327 + (x * (0.27272811532 + (x * (0.23066075146 + (x * 0.20697501302))))))))); // eslint-disable-line max-len +} + + +// EXPORTS // + +module.exports = evalpoly; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_p.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_p.js new file mode 100644 index 000000000000..6449065ea79b --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_p.js @@ -0,0 +1,47 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* This is a generated file. Do not edit directly. */ +'use strict'; + +// MAIN // + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the polynomial +* @returns {number} evaluated polynomial +*/ +function evalpoly( x ) { + if ( x === 0.0 ) { + return 0.16666667163; + } + return 0.16666667163 + (x * (0.002777777845 + (x * (0.00006613755977 + (x * (-0.0000016533901999 + (x * 4.1381369442e-8))))))); // eslint-disable-line max-len +} + + +// EXPORTS // + +module.exports = evalpoly; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_w.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_w.js new file mode 100644 index 000000000000..19aa6342c5bc --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/polyval_w.js @@ -0,0 +1,47 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* This is a generated file. Do not edit directly. */ +'use strict'; + +// MAIN // + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @private +* @param {number} x - value at which to evaluate the polynomial +* @returns {number} evaluated polynomial +*/ +function evalpoly( x ) { + if ( x === 0.0 ) { + return 0.5; + } + return 0.5 + (x * (0.333333343 + (x * 0.25))); +} + + +// EXPORTS // + +module.exports = evalpoly; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/pow2.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/pow2.js new file mode 100644 index 000000000000..3bdbe02c615b --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/pow2.js @@ -0,0 +1,143 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* +* ## Notice +* +* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/12.2.0/lib/msun/src/e_powf.c}. The implementation follows the original, but has been modified for JavaScript. +* +* ```text +* 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. +* ``` +*/ + +'use strict'; + +// MODULES // + +var fromWordf = require( '@stdlib/number/float32/base/from-word' ); +var toWordf = require( '@stdlib/number/float32/base/to-word' ); +var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); +var uint32ToInt32 = require( '@stdlib/number/uint32/base/to-int32' ); +var ldexpf = require( '@stdlib/math/base/special/ldexpf' ); +var LN2 = require( '@stdlib/constants/float32/ln-two' ); +var FLOAT32_EXPONENT_BIAS = require( '@stdlib/constants/float32/exponent-bias' ); +var FLOAT32_ABS_MASK = require( '@stdlib/constants/float32/abs-mask' ); +var FLOAT32_SIGNIFICAND_MASK = require( '@stdlib/constants/float32/significand-mask' ); +var FLOAT32_PRECISION = require( '@stdlib/constants/float32/precision' ); +var polyvalP = require( './polyval_p.js' ); + + +// VARIABLES // + +// 0x00800000 = 8388608 => 0 00000001 00000000000000000000000 => biased exponent: 1 = -126+127 => 2^-126 (smallest normal float32) +var HIGH_MIN_NORMAL_EXP = 0x00800000; // asm type annotation + +// 0x3f000000 = 1056964608 => 0 01111110 00000000000000000000000 => biased exponent: 126 = -1+127 => 2^-1 (i.e., 0.5) +var HIGH_BIASED_EXP_NEG_1 = 0x3f000000; // asm type annotation + +// 0xffff8000 = 4294934528 => 1 11111111111 11111000000000000000 +var HIGH_NEG_NAN = 0xffff8000; // asm type annotation + +// High: LN2 +var LN2_HI = 6.93145752e-01; // 0x3f317200 + +// Low: LN2 +var LN2_LO = 1.42860654e-06; // 0x35bfbe8c + + +// MAIN // + +/** +* Computes \\(2^{\mathrm{hp} + \mathrm{lp}\\). +* +* @private +* @param {number} j - high word of `hp + lp` +* @param {number} hp - first power summand +* @param {number} lp - second power summand +* @returns {number} function value +* +* @example +* var z = pow2( 1065961648, -0.3398475646972656, -0.000002438187359100815 ); +* // returns ~0.79 +*/ +function pow2( j, hp, lp ) { + var ahs; + var tmp; + var t1; + var t; + var r; + var u; + var v; + var w; + var z; + var n; + var i; + var k; + + i = (j & FLOAT32_ABS_MASK); // asm type annotation + k = ((i>>FLOAT32_PRECISION -1) - FLOAT32_EXPONENT_BIAS); // asm type annotation + n = 0; + + // `|z| > 0.5`, set `n = [z+0.5]` + if ( i > HIGH_BIASED_EXP_NEG_1 ) { + n = (j + (HIGH_MIN_NORMAL_EXP>>(k+1)))>>>0; // asm type annotation + k = (((n & FLOAT32_ABS_MASK)>>FLOAT32_PRECISION-1) - FLOAT32_EXPONENT_BIAS); // new k for n + tmp = ((n & ~(FLOAT32_SIGNIFICAND_MASK >> k)))>>>0; // asm type annotation + tmp = float64ToFloat32( tmp ); + t = toWordf( tmp ); + n = (((n & FLOAT32_SIGNIFICAND_MASK)|HIGH_MIN_NORMAL_EXP) >> ((FLOAT32_PRECISION-1)-k))>>>0; // eslint-disable-line max-len + if ( j < 0 ) { + n = -n; + } + hp -= t; + } + t = lp + hp; + ahs = fromWordf( t ); + ahs = float64ToFloat32( ahs & HIGH_NEG_NAN ); + t = toWordf( ahs ); + u = float64ToFloat32( t * LN2_HI ); + v = float64ToFloat32(( float64ToFloat32(lp - float64ToFloat32(t-hp))*LN2 ) + float64ToFloat32( t*LN2_LO )); + z = float64ToFloat32( u + v ); + w = float64ToFloat32( v - float64ToFloat32(z - u)); + t = float64ToFloat32( z * z ); + t1 = float64ToFloat32( z - float64ToFloat32( t*float64ToFloat32( polyvalP( t ) ) ) ); // eslint-disable-line max-len + r = float64ToFloat32( float64ToFloat32( (z*t1) / (t1-2.0) ) - float64ToFloat32( w + float64ToFloat32(z*w) )); // eslint-disable-line max-len + z = float64ToFloat32( 1.0 - float64ToFloat32(r - z) ); + j = fromWordf( z ); + j = uint32ToInt32( j ); + j += (n << (FLOAT32_PRECISION-1))>>>0; // asm type annotation + + // Check for subnormal output... + if ( (j>>(FLOAT32_PRECISION-1)) <= 0 ) { + z = ldexpf( z, n ); + } else { + j = float64ToFloat32( j ); + z = toWordf( j ); + } + return z; +} + + +// EXPORTS // + +module.exports = pow2; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/x_is_zero.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/x_is_zero.js new file mode 100644 index 000000000000..7070b507e60f --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/x_is_zero.js @@ -0,0 +1,100 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* +* ## Notice +* +* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/s_pow.c}. The implementation follows the original, but has been modified for JavaScript. +* +* ```text +* 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. +* ``` +*/ + +'use strict'; + +// MODULES // + +var isOddf = require( '@stdlib/math/base/assert/is-oddf' ); +var copysignf = require( '@stdlib/math/base/special/copysignf' ); +var NINF = require( '@stdlib/constants/float32/ninf' ); +var PINF = require( '@stdlib/constants/float32/pinf' ); + + +// MAIN // + +/** +* Evaluates the exponential function when \\(|x| = 0\\). +* +* @private +* @param {number} x - base +* @param {number} y - exponent +* @returns {number} function value +* +* @example +* var v = powf( 0.0, 2 ); +* // returns 0.0 +* +* @example +* var v = powf( -0.0, -9 ); +* // returns -Infinity +* +* @example +* var v = powf( 0.0, -9 ); +* // returns Infinity +* +* @example +* var v = powf( -0.0, 9 ); +* // returns 0.0 +* +* @example +* var v = powf( 0.0, -Infinity ); +* // returns Infinity +* +* @example +* var v = powf( 0.0, Infinity ); +* // returns 0.0 +*/ +function powf( x, y ) { + if ( y === NINF ) { + return PINF; + } + if ( y === PINF ) { + return 0.0; + } + if ( y > 0.0 ) { + if ( isOddf( y ) ) { + return x; // handles +-0 + } + return 0.0; + } + // y < 0.0 + if ( isOddf( y ) ) { + return copysignf( PINF, x ); // handles +-0 + } + return PINF; +} + + +// EXPORTS // + +module.exports = powf; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/lib/y_is_infinite.js b/lib/node_modules/@stdlib/math/base/special/powf/lib/y_is_infinite.js new file mode 100644 index 000000000000..8eea4cd5f0ad --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/lib/y_is_infinite.js @@ -0,0 +1,88 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var absf = require( '@stdlib/math/base/special/absf' ); +var PINF = require( '@stdlib/constants/float32/pinf' ); + + +// MAIN // + +/** +* Evaluates the exponential function when \\( y = \pm \infty\\). +* +* @private +* @param {number} x - base +* @param {number} y - exponent +* @returns {number} function value +* +* @example +* var v = powf( -1.0, Infinity ); +* // returns NaN +* +* @example +* var v = powf( -1.0, -Infinity ); +* // returns NaN +* +* @example +* var v = powf( 1.0, Infinity ); +* // returns 1.0 +* +* @example +* var v = powf( 1.0, -Infinity ); +* // returns 1.0 +* +* @example +* var v = powf( 0.5, Infinity ); +* // returns 0.0 +* +* @example +* var v = powf( 0.5, -Infinity ); +* // returns Infinity +* +* @example +* var v = powf( 1.5, -Infinity ); +* // returns 0.0 +* +* @example +* var v = powf( 1.5, Infinity ); +* // returns Infinity +*/ +function powf( x, y ) { + if ( x === -1.0 ) { + // Julia (0.4.2) and Python (2.7.9) return `1.0` (WTF???). JavaScript (`Math.powf`), R, and libm return `NaN`. We choose `NaN`, as the value is indeterminate; i.e., we cannot determine whether `y` is odd, even, or somewhere in between. + return (x-x)/(x-x); // signal NaN + } + if ( x === 1.0 ) { + return 1.0; + } + // (|x| > 1 && y === NINF) || (|x| < 1 && y === PINF) + if ( (absf(x) < 1.0) === (y === PINF) ) { + return 0.0; + } + // (|x| > 1 && y === PINF) || (|x| < 1 && y === NINF) + return PINF; +} + + +// EXPORTS // + +module.exports = powf; diff --git a/lib/node_modules/@stdlib/math/base/special/powf/package.json b/lib/node_modules/@stdlib/math/base/special/powf/package.json new file mode 100644 index 000000000000..1ac64db64844 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/package.json @@ -0,0 +1,188 @@ +{ + "name": "@stdlib/math/base/special/powf", + "version": "0.0.0", + "description": "Exponential function.", + "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", + "gypfile": true, + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "include": "./include", + "lib": "./lib", + "scripts": "./scripts", + "src": "./src", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdmath", + "mathematics", + "math", + "math.powf", + "powf", + "power", + "natural", + "exponential", + "function", + "number" + ], + "__stdlib__": { + "scaffold": { + "$schema": "math/base@v1.0", + "base_alias": "powf", + "alias": "powf", + "pkg_desc": "exponential function", + "desc": "exponential function", + "short_desc": "exponential function", + "parameters": [ + { + "name": "x", + "desc": "base", + "type": { + "javascript": "number", + "jsdoc": "number", + "c": "float", + "dtype": "float32" + }, + "domain": [ + { + "min": "-infinity", + "max": "infinity" + } + ], + "rand": { + "prng": "random/base/uniform", + "parameters": [ + -10, + 10 + ] + }, + "example_values": [ + -1.2, + 2, + -3.1, + 4, + 5.5, + 100, + 8.9, + 3.1415927410125732, + 11.3, + -3.1415927410125732, + 13.5, + 14.6, + -15.7, + 16.8, + -17.9, + 10, + -19.11, + 20.12, + -21.15, + 1 + ] + }, + { + "name": "y", + "desc": "exponent", + "type": { + "javascript": "number", + "jsdoc": "number", + "c": "float", + "dtype": "float32" + }, + "domain": [ + { + "min": "-infinity", + "max": "infinity" + } + ], + "rand": { + "prng": "random/base/uniform", + "parameters": [ + -10, + 10 + ] + }, + "example_values": [ + 1.2, + -2, + 3, + -0.5, + 0, + -5.6, + 8.9, + -10, + 1.5, + -12, + 13.5, + 14.6, + -15.7, + 6, + -17, + 18, + -9, + 2.12, + -1.15, + -2 + ] + } + ], + "returns": { + "desc": "function value", + "type": { + "javascript": "number", + "jsdoc": "number", + "c": "float", + "dtype": "float32" + } + }, + "keywords": [ + "natural", + "exponential", + "powf", + "power" + ], + "extra_keywords": [ + "math.powf" + ] + } + } +} diff --git a/lib/node_modules/@stdlib/math/base/special/powf/scripts/evalpoly.js b/lib/node_modules/@stdlib/math/base/special/powf/scripts/evalpoly.js new file mode 100644 index 000000000000..21b43397e389 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/scripts/evalpoly.js @@ -0,0 +1,153 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* +* This script compiles modules for evaluating polynomial functions. If any polynomial coefficients change, this script should be rerun to update the compiled files. +*/ +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var readFileSync = require( '@stdlib/fs/read-file' ).sync; +var writeFileSync = require( '@stdlib/fs/write-file' ).sync; +var currentYear = require( '@stdlib/time/current-year' ); +var substringBefore = require( '@stdlib/string/substring-before' ); +var substringAfter = require( '@stdlib/string/substring-after' ); +var format = require( '@stdlib/string/format' ); +var licenseHeader = require( '@stdlib/_tools/licenses/header' ); +var compile = require( '@stdlib/math/base/tools/evalpoly-compile' ); +var compileC = require( '@stdlib/math/base/tools/evalpoly-compile-c' ); + + +// VARIABLES // + +// Polynomial coefficients ordered in ascending degree... +var L = [ + 6.0000002384e-01, // 0x3f19999a + 4.2857143283e-01, // 0x3edb6db7 + 3.3333334327e-01, // 0x3eaaaaab + 2.7272811532e-01, // 0x3e8ba305 + 2.3066075146e-01, // 0x3e6c3255 + 2.0697501302e-01, // 0x3e53f142 +]; + +// `x - x^2/2 + x^3/3 - x^4/4`... +var W = [ + 0.5, + 3.33333343e-01, + 0.25 +]; + +var P = [ + 1.6666667163e-01, // 0x3e2aaaab + 2.7777778450e-03, // 0xbb360b61 + 6.6137559770e-05, // 0x388ab355 + -1.6533901999e-06, // 0xb5ddea0e + 4.1381369442e-08, // 0x3331bb4c +]; + +// Header to add to output files: +var header = licenseHeader( 'Apache-2.0', 'js', { + 'year': currentYear(), + 'copyright': 'The Stdlib Authors' +}); +header += '\n/* This is a generated file. Do not edit directly. */\n'; + + +// FUNCTIONS // + +/** +* Inserts a compiled function into file content. +* +* @private +* @param {string} text - source content +* @param {string} id - function identifier +* @param {string} str - function string +* @returns {string} updated content +*/ +function insert( text, id, str ) { + var before; + var after; + var begin; + var end; + + begin = '// BEGIN: '+id; + end = '// END: '+id; + + before = substringBefore( text, begin ); + after = substringAfter( text, end ); + + return format( '%s// BEGIN: %s\n\n%s\n%s%s', before, id, str, end, after ); +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var fpath; + var copts; + var opts; + var file; + var str; + + opts = { + 'encoding': 'utf8' + }; + + fpath = resolve( __dirname, '..', 'lib', 'polyval_l.js' ); + str = header + compile( L ); + writeFileSync( fpath, str, opts ); + + fpath = resolve( __dirname, '..', 'lib', 'polyval_w.js' ); + str = header + compile( W ); + writeFileSync( fpath, str, opts ); + + fpath = resolve( __dirname, '..', 'lib', 'polyval_p.js' ); + str = header + compile( P ); + writeFileSync( fpath, str, opts ); + + copts = { + 'dtype': 'float', + 'name': '' + }; + + fpath = resolve( __dirname, '..', 'src', 'main.c' ); + file = readFileSync( fpath, opts ); + + copts.name = 'polyval_l'; + str = compileC( L, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'polyval_w'; + str = compileC( W, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'polyval_p'; + str = compileC( P, copts ); + file = insert( file, copts.name, str ); + + writeFileSync( fpath, file, opts ); +} + +main(); diff --git a/lib/node_modules/@stdlib/math/base/special/powf/test/fixtures/julia/REQUIRE b/lib/node_modules/@stdlib/math/base/special/powf/test/fixtures/julia/REQUIRE new file mode 100644 index 000000000000..308c3be89c85 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/test/fixtures/julia/REQUIRE @@ -0,0 +1,2 @@ +julia 1.5 +JSON 0.21 diff --git a/lib/node_modules/@stdlib/math/base/special/powf/test/fixtures/julia/runner.jl b/lib/node_modules/@stdlib/math/base/special/powf/test/fixtures/julia/runner.jl new file mode 100644 index 000000000000..422d06b3a6d3 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/test/fixtures/julia/runner.jl @@ -0,0 +1,179 @@ +#!/usr/bin/env julia +# +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 JSON + +""" + gen( x, y, name ) + +Generate fixture data and write to file. + +# Arguments + +* `x`: base domain +* `y`: exponent domain +* `name::AbstractString`: output filename + +# Examples + +``` julia +julia> x = range( -1000, stop = 1000, length = 2001 ); +julia> y = range( 0, stop = 1000, length = 1001 ); +julia> gen( x, y, \"data.json\" ); +``` +""" +function gen( x, y, name ) + z = Array{Float64}( undef, length(x) ); + for i in eachindex(x) + z[ i ] = Float32( x[i]^y[i] ); + end + + # Store data to be written to file as a collection: + data = Dict([ + ("x", x), + ("y", y), + ("expected", z) + ]); + + # Based on the script directory, create an output filepath: + filepath = joinpath( dir, name ); + + # Write the data to the output filepath as JSON: + outfile = open( filepath, "w" ); + write( outfile, JSON.json(data) ); + write( outfile, "\n" ); + close( outfile ); +end + +# Get the filename: +file = @__FILE__; + +# Extract the directory in which this file resides: +dir = dirname( file ); + +# Squares (x small): +x = range( -1000, stop = 1000, length = 2001 ); +y = zeros( 2001 ); +y[:] .= 2.0; +gen( x, y, "squared_small.json" ); + +# Squares (x large): +x = range( 3.14e10, stop = 3.14e11, length = 2001 ); +y = zeros( 2001 ); +y[:] .= 2.0; +gen( x, y, "squared_large.json" ); + +# Cubes (x small): +x = range( -1000, stop = 1000, length = 2001 ); +y = zeros( 2001 ); +y[:] .= 3.0; +gen( x, y, "cubed_small.json" ); + +# Cubes (x large): +x = range( -9.99e29, stop = -4.64e32, length = 2001 ); +y = zeros( 2001 ); +y[:] .= 3.0; +gen( x, y, "cubed_large.json" ); + +# To the 4th power (x small): +x = range( -1000, stop = 1000, length = 2001 ); +y = zeros( 2001 ); +y[:] .= 4.0; +gen( x, y, "to_the_fourth_small.json" ); + +# To the 4th power (x large): +x = range( 1.234e30, stop = 3.14e35, length = 2001 ); +y = zeros( 2001 ); +y[:] .= 4.0; +gen( x, y, "to_the_fourth_large.json" ); + +# Base near unity (y small): +x = range( 0.999999, stop = 1.000001, length = 500 ); +y = range( -10, stop = 10, length = 500 ); +gen( x, y, "base_near_unity_small.json" ); + +# Base near unity (y large): +x = range( 0.999999, stop = 1.000001, length = 500 ); +y = range( 100, stop = 79, length = 500 ); +gen( x, y, "base_near_unity_large.json" ); + +# Base near unity (y huge): +x = range( 0.999999, stop = 1.000001, length = 500 ); +y = range( 1.0e6, stop = 1.0e8, length = 500 ); +gen( x, y, "base_near_unity_huge.json" ); + +# Subnormal results: +z = range( 3.14e-39, stop = 1.40129846e-45, length = 2001 ); +x = range( 3.14e-26, stop = 3.14e-27, length = 2001 ); +y = log.(z) ./ log.(x); +gen( x, y, "subnormal_results.json" ); + +# Negative exponents (x small, y small): +x = range( 0, stop = 10, length = 5001 ); +y = rand( 5001 ) .* -100; +gen( x, y, "negative_exp_small_small.json" ); + +# Negative exponents (x large, y small): +x = range( 3.14e10, stop = 1e15, length = 5001 ); +y = rand( 5001 ) .* -100; +gen( x, y, "negative_exp_large_small.json" ); + +# Negative exponents (x small, y large): +x = range( 0, stop = 10, length = 5001 ); +y = rand( 5001 ) .* -(2.0^27); +gen( x, y, "negative_exp_small_large.json" ); + +# Negative exponents (x large, y large): +x = range( 3.14e20, stop = 1e22, length = 5001 ); +y = rand( 5001 ) .* -(2.0^27); +gen( x, y, "negative_exp_large_large.json" ); + +# x small, y small: +x = rand( 5001 ) .* 100; +y = rand( 5001 ) .* 100; +gen( x, y, "small_small.json" ); + +# x small, y large: +x = rand( 5001 ) .* 1.9988548; +y = rand( 5001 ) .* 1024; +gen( x, y, "small_large.json" ); + +# x large, y small: +x = rand( 5001 ) .* 1e30; +y = rand( 5001 ) .* 10; +gen( x, y, "large_small.json" ); + +# Random (x decimal, y decimal): +x = rand( 5001 ) .* 500; +y = rand( 5001 ) .* 100; +gen( x, y, "decimal_decimal.json" ); + +# Random (x decimal, y integer): +x = rand( 5001 ) .* 500; +y = round.( rand(5001) .* 100 ); +gen( x, y, "decimal_integer.json" ); + +# Random (x integer, y decimal): +x = round.( rand(5001) .* 500 ); +y = rand( 5001 ) .* 100; +gen( x, y, "integer_decimal.json" ); + +# Random (x integer, y integer): +x = round.( rand(5001) .* 500 ); +y = round.( rand(5001) .* 100 ); +gen( x, y, "integer_integer.json" ); diff --git a/lib/node_modules/@stdlib/math/base/special/powf/test/test.js b/lib/node_modules/@stdlib/math/base/special/powf/test/test.js new file mode 100644 index 000000000000..b7248f187787 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/test/test.js @@ -0,0 +1,1022 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF 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 absf = require( '@stdlib/math/base/special/absf' ); +var sqrtf = require( '@stdlib/math/base/special/sqrtf' ); +var randu = require( '@stdlib/random/base/randu' ); +var round = require( '@stdlib/math/base/special/round' ); +var PINF = require( '@stdlib/constants/float32/pinf' ); +var NINF = require( '@stdlib/constants/float32/ninf' ); +var EPS = require( '@stdlib/constants/float32/eps' ); +var MAX_SAFE_INTEGER = require( '@stdlib/constants/float32/max-safe-integer' ); +var isnanf = require( '@stdlib/math/base/assert/is-nanf' ); +var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' ); +var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' ); +var powf = require('./../lib'); + + +// FIXTURES // + +var squaredSmall = require( './fixtures/julia/squared_small.json' ); +var squaredLarge = require( './fixtures/julia/squared_large.json' ); +var cubedSmall = require( './fixtures/julia/cubed_small.json' ); +var cubedLarge = require( './fixtures/julia/cubed_large.json' ); +var toTheFourthSmall = require( './fixtures/julia/to_the_fourth_small.json' ); +var toTheFourthLarge = require( './fixtures/julia/to_the_fourth_large.json' ); +var baseNearUnitySmall = require( './fixtures/julia/base_near_unity_small.json' ); +var baseNearUnityLarge = require( './fixtures/julia/base_near_unity_large.json' ); +var baseNearUnityHuge = require( './fixtures/julia/base_near_unity_huge.json' ); +var subnormalResults = require( './fixtures/julia/subnormal_results.json' ); +var negativeExpSmallSmall = require( './fixtures/julia/negative_exp_small_small.json' ); +var negativeExpSmallLarge = require( './fixtures/julia/negative_exp_small_large.json' ); +var negativeExpLargeSmall = require( './fixtures/julia/negative_exp_large_small.json' ); +var negativeExpLargeLarge = require( './fixtures/julia/negative_exp_large_large.json' ); +var smallSmall = require( './fixtures/julia/small_small.json' ); +var smallLarge = require( './fixtures/julia/small_large.json' ); +var largeSmall = require( './fixtures/julia/large_small.json' ); +var decimalDecimal = require( './fixtures/julia/decimal_decimal.json' ); +var decimalInteger = require( './fixtures/julia/decimal_integer.json' ); +var integerDecimal = require( './fixtures/julia/integer_decimal.json' ); +var integerInteger = require( './fixtures/julia/integer_integer.json' ); +const FLOAT32_MAX_SAFE_INTEGER = require('@stdlib/constants/float32/max-safe-integer'); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof powf, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function accepts two parameters: a base and an exponent', function test( t ) { + t.equal( powf.length, 2.0, 'arity is 2' ); + t.end(); +}); + +tape( 'the function evaluates the exponential function (`y = 2` and `x` small)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = squaredSmall.x; + y = squaredSmall.y; + expected = squaredSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`y = 2` and `x` large)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = squaredLarge.x; + y = squaredLarge.y; + expected = squaredLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`y = 3` and `x` small)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = cubedSmall.x; + y = cubedSmall.y; + expected = cubedSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`y = 3` and `x` large)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = cubedLarge.x; + y = cubedLarge.y; + expected = cubedLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`y = 4` and `x` small)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = toTheFourthSmall.x; + y = toTheFourthSmall.y; + expected = toTheFourthSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`y = 4` and `x` large)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = toTheFourthLarge.x; + y = toTheFourthLarge.y; + expected = toTheFourthLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`x ~ 1`, `y` small)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = baseNearUnitySmall.x; + y = baseNearUnitySmall.y; + expected = baseNearUnitySmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`x ~ 1`, `y` large)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = baseNearUnityLarge.x; + y = baseNearUnityLarge.y; + expected = baseNearUnityLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (`x ~ 1`, `y` huge)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = baseNearUnityHuge.x; + y = baseNearUnityHuge.y; + expected = baseNearUnityHuge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (subnormal results)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = subnormalResults.x; + y = subnormalResults.y; + expected = subnormalResults.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (negative exponents; `x` small, `y` small)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = negativeExpSmallSmall.x; + y = negativeExpSmallSmall.y; + expected = negativeExpSmallSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + if ( expected[i] === null ) { + t.equal( actual, PINF, 'powf('+x[i]+','+y[i]+') returns +infinity' ); + } else { + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (negative exponents; `x` small, `y` large)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = negativeExpSmallLarge.x; + y = negativeExpSmallLarge.y; + expected = negativeExpSmallLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + if ( expected[i] === null ) { + t.equal( actual, PINF, 'powf('+x[i]+','+y[i]+') returns +infinity' ); + } else { + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (negative exponents; `x` large, `y` small)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = negativeExpLargeSmall.x; + y = negativeExpLargeSmall.y; + expected = negativeExpLargeSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + if ( expected[i] === null ) { + t.equal( actual, PINF, 'powf('+x[i]+','+y[i]+') returns +infinity' ); + } + else if ( expected[i] === 5.0e-324 ) { + // Julia, Python, and R occasionally return the min subnormal value, when, in fact, the result should underflow; e.g., `pow(571413458040000, -21.92803603935001)` returns `0` for this implementation, and `5.0e-324` on other platforms. The answer checked on Wolfram Alpha is `2.564828778186e-324`, which is less than the min subnormal. This discrepancy arises, at least when compared to Julia's Openlibm, due to differences in our `ldexp` and their `scalbn`. + t.equal( actual === expected[i] || actual === 0.0, true, 'powf('+x[i]+','+y[i]+') returns '+expected[i]+' or 0' ); + } + else { + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (negative exponents; `x` large, `y` large)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = negativeExpLargeLarge.x; + y = negativeExpLargeLarge.y; + expected = negativeExpLargeLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + if ( expected[i] === null ) { + t.equal( actual, PINF, 'powf('+x[i]+','+y[i]+') returns +infinity' ); + } else { + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (near overflow)', function test( t ) { + var x; + var y; + var v; + + x = 2.0; + y = 512; + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + x = 2.0; + y = 511; + v = powf( x, y ); + t.equal( v, 8.98846567431158e37, 'powf('+x+','+y+') returns 8.98846567431158e307' ); + + x = 2.001355585648339; + y = 511; + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + x = 2.0; + y = 513; + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + x = 1.998647974895499; + y = 513; + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + x = 2.0 + ( EPS*2.0 ); + y = 512; + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + t.end(); +}); + +tape( 'the function evaluates the exponential function (near underflow)', function test( t ) { + var x; + var y; + var v; + + x = 2.0; + y = -149; + v = powf( x, y ); + t.equal( v, 0.0, 'powf('+x+','+y+') returns 0' ); + + x = 1.9987108; + y = -149; + v = powf( x, y ); + t.equal( v, 1.4e-45, 'powf('+x+','+y+') returns 5e-324' ); + + // Wolfram Alpha: 2.47032822920649828116748364864574508116622553173015e-324 + x = 1.9999999; + y = -149; + v = powf( x, y ); + t.equal( v, 0.0, 'powf('+x+','+y+') returns 0' ); + + x = 1.9999999; + y = -149; + v = powf( x, y ); + t.equal( v, 0.0, 'powf('+x+','+y+') returns 0' ); + + t.end(); +}); + +tape( 'the function evaluates the exponential function (small `x`, large `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = smallLarge.x; + y = smallLarge.y; + expected = smallLarge.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + if ( expected[i] === 1.4e-45 ) { + t.equal( actual === expected[i] || actual === 0.0, true, 'powf('+x[i]+','+y[i]+') returns 1.4e-45 or 0' ); + } else { + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (large `x`, small `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = largeSmall.x; + y = largeSmall.y; + expected = largeSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (small `x`, small `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = smallSmall.x; + y = smallSmall.y; + expected = smallSmall.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (decimal `x`, decimal `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = decimalDecimal.x; + y = decimalDecimal.y; + expected = decimalDecimal.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (decimal `x`, integer `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = decimalInteger.x; + y = decimalInteger.y; + expected = decimalInteger.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (integer `x`, decimal `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = integerDecimal.x; + y = integerDecimal.y; + expected = integerDecimal.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the exponential function (integer `x`, integer `y`)', function test( t ) { + var expected; + var actual; + var x; + var y; + var i; + + x = integerInteger.x; + y = integerInteger.y; + expected = integerInteger.expected; + for ( i = 0; i < x.length; i++ ) { + actual = powf( x[i], y[i] ); + t.equal( actual, expected[i], 'powf('+x[i]+','+y[i]+') returns '+expected[i] ); + } + t.end(); +}); + +tape( 'the function returns `NaN` if provided `NaN` for the exponent', function test( t ) { + var v; + + v = powf( -3.0, NaN ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + v = powf( 0.0, NaN ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'the function returns `NaN` if provided `NaN` for the base', function test( t ) { + var v; + + v = powf( NaN, 5.0 ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + v = powf( NaN, 1.0 ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + v = powf( NaN, 0.0 ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'any number raised to the zero power is `1`', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + x = ( randu()*1.0e6 ) - 5.0e5; + v = powf( x, 0.0 ); + t.equal( v, 1.0, 'powf('+x+',0.0) returns 1' ); + } + t.equal( powf( PINF, 0.0 ), 1.0, 'inf^0 = 1' ); + t.equal( powf( NINF, 0.0 ), 1.0, '(-inf)^0 = 1' ); + t.equal( powf( 0.0, 0.0 ), 1.0, '0^0 = 1' ); + t.end(); +}); + +tape( 'any number raised to the `-1` power is the reciprocal of that number', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + x = ( randu()*1.0e6 ) - 5.0e5; + v = powf( x, -1.0 ); + t.equal( v, 1/x, 'powf('+x+',0.0) returns '+(1/x) ); + } + t.equal( isPositiveZero( powf( PINF, -1.0 ) ), true, 'inf^-1 = 0' ); + t.equal( isNegativeZero( powf( NINF, -1.0 ) ), true, '(-inf)^0 = -0' ); + t.equal( powf( 0.0, -1.0 ), PINF, '0^-1 = +infinity' ); + t.equal( powf( -0.0, -1.0 ), NINF, '(-0)^-1 = -infinity' ); + t.end(); +}); + +tape( 'unity raised to any power is `1`', function test( t ) { + var y; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + y = ( randu()*1.0e6 ) - 5.0e5; + v = powf( 1.0, y ); + t.equal( v, 1.0, 'powf(1.0,'+y+') returns 1' ); + } + t.equal( powf( 1.0, PINF ), 1.0, '1^inf = 1' ); + t.equal( powf( 1.0, NINF ), 1.0, '1^(-inf) = 1' ); + t.equal( powf( 1.0, 0.0 ), 1.0, '1^0 = 1' ); + t.end(); +}); + +tape( '`-1` raised to any odd integer is `-1`', function test( t ) { + var v; + var i; + for ( i = -51; i < 53; i += 2 ) { + v = powf( -1.0, i ); + t.equal( v, -1.0, 'powf(1.0,'+i+') returns -1' ); + } + t.end(); +}); + +tape( '`+-0` raised to `-infinity` is `+infinity`', function test( t ) { + var v; + + v = powf( +0.0, NINF ); + t.equal( v, PINF, 'returns +infinity' ); + + v = powf( -0.0, NINF ); + t.equal( v, PINF, 'returns +infinity' ); + + t.end(); +}); + +tape( '`+-0` raised to `+infinity` is `0`', function test( t ) { + var v; + + v = powf( +0.0, PINF ); + t.equal( isPositiveZero( v ), true, 'returns +0' ); + + v = powf( -0.0, PINF ); + t.equal( isPositiveZero( v ), true, 'returns +0' ); + + t.end(); +}); + +tape( '`+-0` raised to any positive finite number which is not an odd integer is `0`', function test( t ) { + var y; + var i; + var v; + + y = [ + 2, + 3.14, + 1.0e5, + 5.1, + 9.999999 + ]; + + for ( i = 0; i < y.length; i++ ) { + v = powf( +0.0, y[ i ] ); + t.equal( isPositiveZero( v ), true, 'powf(0,'+y[i]+') returns +0' ); + + v = powf( -0.0, y[ i ] ); + t.equal( isPositiveZero( v ), true, 'powf(-0,'+y[i]+') returns +0' ); + } + t.end(); +}); + +tape( '`+-0` raised to any positive odd integer is `+-0`', function test( t ) { + var i; + var v; + + for ( i = 1; i < 101; i += 2 ) { + v = powf( +0.0, i ); + t.equal( isPositiveZero( v ), true, 'powf(0,'+i+') returns +0' ); + + v = powf( -0.0, i ); + t.equal( isNegativeZero( v ), true, 'powf(-0,'+i+') returns -0' ); + } + t.end(); +}); + +tape( '`+-0` raised to any negative finite number which is not an odd integer is `+infinity`', function test( t ) { + var y; + var i; + var v; + + y = [ + -2, + -3.14, + -1.0e5, + -5.1, + -9.999999 + ]; + + for ( i = 0; i < y.length; i++ ) { + v = powf( +0.0, y[ i ] ); + t.equal( v, PINF, 'powf(0,'+y[i]+') returns +infinity' ); + + v = powf( -0.0, y[ i ] ); + t.equal( v, PINF, 'powf(-0,'+y[i]+') returns +infinity' ); + } + t.end(); +}); + +tape( '`+-0` raised to any negative odd integer is `+-infinity`', function test( t ) { + var i; + var v; + + for ( i = -101; i < 0; i += 2 ) { + v = powf( +0.0, i ); + t.equal( v, PINF, 'powf(0,'+i+') returns +infinity' ); + + v = powf( -0.0, i ); + t.equal( v, NINF, 'powf(-0,'+i+') returns -infinity' ); + } + t.end(); +}); + +tape( '`-1` raised to `+-infinity` is indeterminate and the function returns `NaN`', function test( t ) { + var v; + + v = powf( -1.0, PINF ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + v = powf( -1.0, NINF ); + t.equal( isnanf( v ), true, 'returns NaN' ); + + t.end(); +}); + +tape( 'raising any number to the `1/2` power returns the same results as evaluating the principal square root', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 500; i++ ) { + x = randu()*1.0e5; + v = powf( x, 0.5 ); + t.equal( v, sqrtf( x ), 'returns sqrtf('+x+')' ); + } + t.end(); +}); + +tape( 'raising any number to the `-1/2` power returns the same results as evaluating the inverse of the principal square root', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 500; i++ ) { + x = randu()*1.0e5; + v = powf( x, -0.5 ); + t.equal( v, 1.0/sqrtf( x ), 'returns sqrtf('+x+')' ); + } + t.end(); +}); + +tape( 'the function returns `+infinity` if a positive number greater than `1` is raised to `+infinity`', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + x = 1.0 + ( randu()*1.0e5 ); + v = powf( x, PINF ); + t.equal( v, PINF, 'powf('+x+',+infinity) returns +infinity' ); + } + t.end(); +}); + +tape( 'the function returns `+infinity` if a negative number less than `-1` is raised to `+infinity`', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + x = ( -randu()*1.0e5 ) - 1.0; + v = powf( x, PINF ); + t.equal( v, PINF, 'powf('+x+',+infinity) returns +infinity' ); + } + t.end(); +}); + +tape( 'the function returns `+infinity` if `-infinity` is raised to `+infinity`', function test( t ) { + var v = powf( NINF, PINF ); + t.equal( v, PINF, 'returns +infinity' ); + t.end(); +}); + +tape( 'the function returns `(-0)^y` if `-infinity` is raised to a numeric `y` power', function test( t ) { + var y; + var v; + var i; + + for ( i = 0; i < 100; i++ ) { + y = ( randu()*100.0 ) - 50.0; + v = powf( NINF, y ); + t.equal( v, powf( -0.0, -y ), 'powf(-infinity,'+y+') returns pow(-0,-'+y+')' ); + } + v = powf( NINF, NINF ); + t.equal( v, powf( -0.0, PINF ), 'powf(-infinity,-infinity) returns pow(-0,+infinity)' ); + + v = powf( NINF, PINF ); + t.equal( v, powf( -0.0, NINF ), 'powf(-infinity,+infinity) returns pow(-0,-infinity)' ); + + v = powf( NINF, 5.0 ); + t.equal( v, powf( -0.0, -5.0 ), 'powf(-infinity,5) returns pow(-0,-5)' ); + + v = powf( NINF, 2.0 ); + t.equal( v, powf( -0.0, -2.0 ), 'powf(-infinity,2) returns pow(-0,-2)' ); + + v = powf( NINF, -5.0 ); + t.equal( v, powf( -0.0, 5.0 ), 'powf(-infinity,-5) returns pow(-0,5)' ); + + v = powf( NINF, -2.0 ); + t.equal( v, powf( -0.0, 2.0 ), 'powf(-infinity,-2) returns pow(-0,2)' ); + + t.end(); +}); + +tape( 'the function returns `0` if a positive number greater than `1` is raised to `-infinity`', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + x = 1.0 + ( randu()*1.0e5 ); + v = powf( x, NINF ); + t.equal( v, 0.0, 'pow('+x+',-infinity) returns 0' ); + } + t.end(); +}); + +tape( 'the function returns `0` if `+infinity` is raised to `-infinity`', function test( t ) { + var v = powf( PINF, NINF ); + t.equal( v, 0.0, 'returns 0' ); + t.end(); +}); + +tape( 'the function returns `0` if `+infinity` is raised to any negative finite number', function test( t ) { + var y; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + y = -(randu() * 1.0e5) - EPS; + v = powf( PINF, y ); + t.equal( isPositiveZero( v ), true, 'returns 0' ); + } + t.end(); +}); + +tape( 'the function returns `+infinity` if `+infinity` is raised to any positive finite number', function test( t ) { + var y; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + y = ( randu()*1.0e5 ) + EPS; + v = powf( PINF, y ); + t.equal( v, PINF, 'returns +infinity' ); + } + t.end(); +}); + +tape( 'the function returns `0` if a negative number less than `-1` is raised to `-infinity`', function test( t ) { + var x; + var v; + var i; + for ( i = 0; i < 100; i++ ) { + x = ( -randu()*1.0e5 ) - 1.0; + v = powf( x, NINF ); + t.equal( v, 0.0, 'powf('+x+',-infinity) returns 0' ); + } + t.end(); +}); + +tape( 'the function returns `NaN` if asked to raise a negative number to an exponent whose absolute value is greater than 0 but less than 1', function test( t ) { + var x; + var y; + var v; + var i; + + for ( i = 0; i < 100; i++ ) { + x = ( -randu()*1.0e5 ) - EPS; + y = randu(); + if ( y === 0.0 || y === 1.0 ) { + continue; + } + v = powf( x, y ); + t.equal( isnanf( v ), true, 'powf('+x+','+y+') returns NaN' ); + } + t.end(); +}); + +tape( 'if `y > 2^64` and `x` is greater than `1`, the function overflows', function test( t ) { + var x; + var y; + var v; + + x = 1.0 + EPS; // smallest value greater than 1.0 + y = 3.6893488147419103e19; // 2.0^65 + v = powf( x, y ); + t.equal( v, PINF, 'returns +infinity' ); + t.end(); +}); + +tape( 'if `y < -(2^64)` and `x` is greater than `1`, the function underflows', function test( t ) { + var x; + var y; + var v; + + x = 1.0 + EPS; // smallest value greater than 1.0 + y = -3.6893488147419103e19; // -(2.0)^65 + v = powf( x, y ); + t.equal( v, 0.0, 'returns 0' ); + t.end(); +}); + +tape( 'if `y > 2^64` and `x` is less than `1`, the function underflows', function test( t ) { + var x; + var y; + var v; + + x = 1.0 - EPS; // greatest value less than 1.0 + y = 3.6893488147419103e19; // 2.0^65 + v = powf( x, y ); + t.equal( v, 0.0, 'returns 0' ); + t.end(); +}); + +tape( 'if `y < -(2^64)` and `x` is less than `1`, the function overflows', function test( t ) { + var x; + var y; + var v; + + x = 1.0 - EPS; // greatest value less than 1.0 + y = -3.6893488147419103e19; // -(2.0^65) + v = powf( x, y ); + t.equal( v, PINF, 'returns +infinity' ); + t.end(); +}); + +tape( 'if `y > 2^31` and `|x|` significantly less than unity, the function underflows', function test( t ) { + var exp; + var x; + var y; + var v; + var i; + + for ( i = 0; i < 100; i++ ) { + x = 0.5 * randu(); + + exp = round( randu()*32.0 ) + 32; + y = powf( 2.0, exp ); + + v = powf( x, y ); + t.equal( isPositiveZero( v ), true, 'powf('+x+','+y+') returns +0' ); + + if ( y < FLOAT32_MAX_SAFE_INTEGER ) { + y += 1; + v = powf( -x, y ); + t.equal( isNegativeZero( v ), true, 'powf(-'+x+','+y+') returns -0' ); + } + } + t.end(); +}); + +tape( 'if `y < -(2^31)` and `|x|` significantly less than unity, the function overflows', function test( t ) { + var exp; + var x; + var y; + var v; + var i; + + for ( i = 0; i < 100; i++ ) { + x = 0.5 * randu(); + + exp = round( randu()*32.0 ) + 32; + y = -powf( 2.0, exp ); + + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + if ( absf(y) < FLOAT32_MAX_SAFE_INTEGER ) { + y -= 1; + v = powf( -x, y ); + t.equal( v, NINF, 'powf(-'+x+','+y+') returns -infinity' ); + } + } + t.end(); +}); + +tape( 'if `y < -(2^31)` and `|x|` significantly greater than unity, the function underflows', function test( t ) { + var exp; + var x; + var y; + var v; + var i; + + for ( i = 0; i < 100; i++ ) { + x = 2.0 + ( randu()*1.0e5 ); + + exp = round( randu()*32.0 ) + 32; + y = -powf( 2.0, exp ); + + v = powf( x, y ); + t.equal( isPositiveZero( v ), true, 'powf('+x+','+y+') returns +0' ); + + if ( absf(y) < FLOAT32_MAX_SAFE_INTEGER ) { + y -= 1; + v = powf( -x, y ); + t.equal( isNegativeZero( v ), true, 'powf(-'+x+','+y+') returns -0' ); + } + } + t.end(); +}); + +tape( 'if `y > 2^31` and `|x|` significantly greater than unity, the function overflows', function test( t ) { + var exp; + var x; + var y; + var v; + var i; + + for ( i = 0; i < 100; i++ ) { + x = 2.0 + ( randu()*1.0e5 ); + + exp = round( randu()*32.0 ) + 32; + y = powf( 2.0, exp ); + + v = powf( x, y ); + t.equal( v, PINF, 'powf('+x+','+y+') returns +infinity' ); + + if ( y < FLOAT32_MAX_SAFE_INTEGER ) { + y += 1; + v = powf( -x, y ); + t.equal( v, NINF, 'powf(-'+x+','+y+') returns -infinity' ); + } + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/powf/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/powf/test/test.native.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lib/node_modules/@stdlib/math/base/special/powf/test/test.x_is_zero.js b/lib/node_modules/@stdlib/math/base/special/powf/test/test.x_is_zero.js new file mode 100644 index 000000000000..12bb0317694a --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/powf/test/test.x_is_zero.js @@ -0,0 +1,109 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var PINF = require( '@stdlib/constants/float32/pinf' ); +var NINF = require( '@stdlib/constants/float32/ninf' ); +var isPositiveZerof = require( '@stdlib/math/base/assert/is-positive-zerof' ); +var isNegativeZerof = require( '@stdlib/math/base/assert/is-negative-zerof' ); +var powf = require( './../lib/x_is_zero.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof powf, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns `+infinity` if `y = -infinity`', function test( t ) { + var v; + + v = powf( 0.0, NINF ); + t.equal( v, PINF, 'returns +infinity' ); + + v = powf( -0.0, NINF ); + t.equal( v, PINF, 'returns +infinity' ); + + t.end(); +}); + +tape( 'the function returns `+0` if `y = +infinity`', function test( t ) { + var v; + + v = powf( 0.0, PINF ); + t.equal( isPositiveZerof( v ), true, 'returns +0' ); + + v = powf( -0.0, PINF ); + t.equal( isPositiveZerof( v ), true, 'returns +0' ); + + t.end(); +}); + +tape( 'the function returns `x` if `y` is an odd positive integer', function test( t ) { + var v; + + v = powf( 0.0, 5 ); + t.equal( isPositiveZerof( v ), true, 'returns +0' ); + + v = powf( -0.0, 5 ); + t.equal( isNegativeZerof( v ), true, 'returns -0' ); + + t.end(); +}); + +tape( 'the function returns `+0` if `y` is positive but not an odd integer', function test( t ) { + var v; + + v = powf( 0.0, 4 ); + t.equal( isPositiveZerof( v ), true, 'returns +0' ); + + v = powf( -0.0, 3.14 ); + t.equal( isPositiveZerof( v ), true, 'returns +0' ); + + t.end(); +}); + +tape( 'the function returns `+-infinity` if `y` is a negative odd integer', function test( t ) { + var v; + + v = powf( 0.0, -5 ); + t.equal( v, PINF, 'returns +infinity' ); + + v = powf( -0.0, -5 ); + t.equal( v, NINF, 'returns -infinity' ); + + t.end(); +}); + +tape( 'the function returns `+infinity` if `y` is negative but not an odd integer', function test( t ) { + var v; + + v = powf( 0.0, -4 ); + t.equal( v, PINF, 'returns +infinity' ); + + v = powf( -0.0, -3.14 ); + t.equal( v, PINF, 'returns +infinity' ); + + t.end(); +});