diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/README.md b/lib/node_modules/@stdlib/math/base/special/ellipj/README.md index a45e55abb8fa..4088b97dfea8 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/README.md +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/README.md @@ -24,7 +24,7 @@ limitations under the License.
-The [Jacobi elliptic functions][jacobi-elliptic] may be defined as the inverse of the [incomplete elliptic integral of the first kind][incomplete-elliptic]. Accordingly, they compute the value `φ` which satisfies the equation +The [Jacobi elliptic functions][jacobi-elliptic] may be defined as the inverse of the [incomplete elliptic integral of the first kind][incomplete-elliptic]. Accordingly, they compute the value `φ` which satisfies the equation @@ -166,6 +166,105 @@ for ( i = 0; i < 100; i++ ) { + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/math/base/special/ellipj.h" +``` + +#### stdlib_base_ellipj( x, m, &sn, &cn, &dn, &am ) + +Computes the [Jacobi elliptic functions][jacobi-elliptic] functions `sn`, `cn`, and `dn`, and the Jacobi amplitude `am`. + +```c +double sn; +double cn; +double dn; +double am; + +stdlib_base_ellipj( 0.3, 0.5, &sn, &cn, &dn, &am ); +``` + +The function accepts the following arguments: + +- **x**: `[in] double` input value. +- **m**: `[in] double` modulus `m`, equivalent to `k²`. +- **sn**: `[out] double*` destination for the sine amplitude. +- **cn**: `[out] double*` destination for the cosine amplitude. +- **dn**: `[out] double*` destination for the delta amplitude. +- **am**: `[out] double*` destination for the Jacobi amplitude. + +```c +void stdlib_base_ellipj( const double u, const double m, double* sn, double* cn, double* dn, double* am ); +``` + +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/math/base/special/ellipj.h" +#include +#include + +int main( void ) { + double sn; + double cn; + double dn; + double am; + double x; + int i; + + for ( i = 0; i < 100; i++ ) { + x = 2.0 * ( (double)rand() / (double)RAND_MAX ); + stdlib_base_ellipj( x, 0.7, &sn, &cn, &dn, &am ); + printf( "x: %lf, m: %lf => sn: %lf, cn: %lf, dn: %lf, am: %lf\n", x, 0.7, sn, cn, dn, am ); + } +} +``` + +
+ + + +
+ + + * * *
diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.js b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.js index 921ac93a0858..d167bc2ef45f 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.js @@ -23,7 +23,7 @@ var bench = require( '@stdlib/bench' ); var isArray = require( '@stdlib/assert/is-array' ); var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; -var randu = require( '@stdlib/random/base/randu' ); +var uniform = require( '@stdlib/random/array/uniform' ); var pkg = require( './../package.json' ).name; var ellipj = require( './../lib' ); @@ -32,15 +32,16 @@ var ellipj = require( './../lib' ); bench( pkg, function benchmark( b ) { var out; - var u; + var x; var m; var i; + x = uniform( 100, -50.0, 50.0 ); + m = uniform( 100, 0.0, 1.0 ); + b.tic(); for ( i = 0; i < b.iterations; i++ ) { - u = (randu() * 100.0) - 50.0; - m = randu(); - out = ellipj( u, m ); + out = ellipj( x[ i%x.length ], m[ i%m.length ] ); if ( typeof out !== 'object' ) { b.fail( 'should return an object' ); } diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.native.js b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.native.js new file mode 100644 index 000000000000..d605eb6875a1 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/benchmark.native.js @@ -0,0 +1,69 @@ +/** +* @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 isFloat64Array = require( '@stdlib/assert/is-float64array' ); +var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var uniform = require( '@stdlib/random/array/uniform' ); +var tryRequire = require( '@stdlib/utils/try-require' ); +var pkg = require( './../package.json' ).name; + + +// VARIABLES // + +var ellipj = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( ellipj instanceof Error ) +}; + + +// MAIN // + +bench( pkg+'::native', opts, function benchmark( b ) { + var out; + var x; + var m; + var i; + + x = uniform( 100, -50.0, 50.0 ); + m = uniform( 100, 0.0, 1.0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = ellipj( x[ i%x.length ], m[ i%m.length ] ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isFloat64Array( out ) ) { + b.fail( 'should return a Float64Array' ); + } + for ( i = 0; i < 4; i++ ) { + if ( !isNumber( out[ i ] ) ) { + b.fail( 'should return a number' ); + } + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/c/native/Makefile b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/c/native/Makefile new file mode 100644 index 000000000000..a4bd7b38fd74 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/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/ellipj/benchmark/c/native/benchmark.c b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/c/native/benchmark.c new file mode 100644 index 000000000000..64751e29cde8 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/benchmark/c/native/benchmark.c @@ -0,0 +1,141 @@ +/** +* @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/ellipj.h" +#include +#include +#include +#include +#include + +#define NAME "ellipj" +#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 [min,max). +* +* @param min minimum value (inclusive) +* @param max maximum value (exclusive) +* @return random number +*/ +static double random_uniform( const double min, const double max ) { + double v = (double)rand() / ( (double)RAND_MAX + 1.0 ); + return min + ( v*(max-min) ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +static double benchmark( void ) { + double x[ 100 ]; + double elapsed; + double sn; + double cn; + double dn; + double am; + double t; + int i; + + for ( i = 0; i < 100; i++ ) { + x[ i ] = random_uniform( 0.0, 2.0 ); + } + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + stdlib_base_ellipj( x[ i%100 ], 0.7, &sn, &cn, &dn, &am ); + if ( sn != sn || cn != cn || dn != dn || am != am ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( sn != sn || cn != cn || dn != dn || am != am ) { + 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/ellipj/binding.gyp b/lib/node_modules/@stdlib/math/base/special/ellipj/binding.gyp new file mode 100644 index 000000000000..68a1ca11d160 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/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/ellipj/examples/c/Makefile b/lib/node_modules/@stdlib/math/base/special/ellipj/examples/c/Makefile new file mode 100644 index 000000000000..25ced822f96a --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/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/ellipj/examples/c/example.c b/lib/node_modules/@stdlib/math/base/special/ellipj/examples/c/example.c new file mode 100644 index 000000000000..1f12892d47c5 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/examples/c/example.c @@ -0,0 +1,36 @@ +/** +* @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/ellipj.h" +#include +#include + +int main( void ) { + double sn; + double cn; + double dn; + double am; + double x; + int i; + + for ( i = 0; i < 100; i++ ) { + x = 2.0 * ( (double)rand() / (double)RAND_MAX ); + stdlib_base_ellipj( x, 0.7, &sn, &cn, &dn, &am ); + printf( "x: %lf, m: %lf => sn: %lf, cn: %lf, dn: %lf, am: %lf\n", x, 0.7, sn, cn, dn, am ); + } +} diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/include.gypi b/lib/node_modules/@stdlib/math/base/special/ellipj/include.gypi new file mode 100644 index 000000000000..ecfaf82a3279 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/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.293, ~0.956, ~0.978, ~0.298 ] +* +* @example +* var v = ellipj( 0.0, 0.0 ); +* // returns [ ~0.0, ~1.0, ~1.0, ~0.0 ] +* +* @example +* var v = ellipj( Infinity, 1.0 ); +* // returns [ ~1.0, ~0.0, ~0.0, ~1.571 ] +* +* @example +* var v = ellipj( 0.0, -2.0 ); +* // returns [ ~0.0, ~1.0, ~1.0, NaN ] +* +* @example +* var v = ellipj( NaN, NaN ); +* // returns [ NaN, NaN, NaN, NaN ] +*/ +function ellipj( x, m ) { + var out = new Float64Array( 4 ); + addon( x, m, out ); + return out; +} + + +// EXPORTS // + +module.exports = ellipj; diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/lib/sn.js b/lib/node_modules/@stdlib/math/base/special/ellipj/lib/sn.js index 0204bfb0568f..de64d629a7a5 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/lib/sn.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/lib/sn.js @@ -38,26 +38,24 @@ var tmp = [ 0.0, 0.0, 0.0, 0.0 ]; * @returns {number} sn(u, m) * * @example -* var sn = require( '@stdlib/math/base/special/ellipj' ).sn; * var v = sn( 0.3, 0.5 ); * // returns ~0.293 * * @example -* v = sn( 0.0, 0.0 ); +* var v = sn( 0.0, 0.0 ); * // returns ~0.0 * * @example -* v = sn( Infinity, 1.0 ); +* var v = sn( Infinity, 1.0 ); * // returns ~1.0 * * @example -* v = sn( 0.0, -2.0 ); +* var v = sn( 0.0, -2.0 ); * // returns ~0.0 * * @example -* v = sn( NaN, NaN ); +* var v = sn( NaN, NaN ); * // returns NaN -* */ function sn( u, m ) { assign( u, m, tmp, 1, 0 ); diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/manifest.json b/lib/node_modules/@stdlib/math/base/special/ellipj/manifest.json new file mode 100644 index 000000000000..00be502cf2a4 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/manifest.json @@ -0,0 +1,120 @@ +{ + "options": { + "task": "build" + }, + "fields": [ + { + "field": "src", + "resolve": true, + "relative": true + }, + { + "field": "include", + "resolve": true, + "relative": true + }, + { + "field": "libraries", + "resolve": false, + "relative": false + }, + { + "field": "libpath", + "resolve": true, + "relative": false + } + ], + "confs": [ + { + "task": "build", + "src": [ + "./src/main.c" + ], + "include": [ + "./include" + ], + "libraries": [], + "libpath": [], + "dependencies": [ + "@stdlib/napi/argv", + "@stdlib/napi/argv-double", + "@stdlib/napi/argv-float64array", + "@stdlib/napi/export", + "@stdlib/math/base/special/sincos", + "@stdlib/math/base/special/ellipk", + "@stdlib/math/base/special/floor", + "@stdlib/math/base/special/fmod", + "@stdlib/math/base/special/sqrt", + "@stdlib/math/base/special/sinh", + "@stdlib/math/base/special/cosh", + "@stdlib/math/base/special/tanh", + "@stdlib/math/base/special/atan", + "@stdlib/math/base/special/asin", + "@stdlib/math/base/special/sin", + "@stdlib/math/base/special/cos", + "@stdlib/math/base/special/abs", + "@stdlib/constants/float64/sqrt-eps", + "@stdlib/constants/float64/eps", + "@stdlib/constants/float64/pi" + ] + }, + { + "task": "benchmark", + "src": [ + "./src/main.c" + ], + "include": [ + "./include" + ], + "libraries": [], + "libpath": [], + "dependencies": [ + "@stdlib/math/base/special/sincos", + "@stdlib/math/base/special/ellipk", + "@stdlib/math/base/special/floor", + "@stdlib/math/base/special/fmod", + "@stdlib/math/base/special/sqrt", + "@stdlib/math/base/special/sinh", + "@stdlib/math/base/special/cosh", + "@stdlib/math/base/special/tanh", + "@stdlib/math/base/special/atan", + "@stdlib/math/base/special/asin", + "@stdlib/math/base/special/sin", + "@stdlib/math/base/special/cos", + "@stdlib/math/base/special/abs", + "@stdlib/constants/float64/sqrt-eps", + "@stdlib/constants/float64/eps", + "@stdlib/constants/float64/pi" + ] + }, + { + "task": "examples", + "src": [ + "./src/main.c" + ], + "include": [ + "./include" + ], + "libraries": [], + "libpath": [], + "dependencies": [ + "@stdlib/math/base/special/sincos", + "@stdlib/math/base/special/ellipk", + "@stdlib/math/base/special/floor", + "@stdlib/math/base/special/fmod", + "@stdlib/math/base/special/sqrt", + "@stdlib/math/base/special/sinh", + "@stdlib/math/base/special/cosh", + "@stdlib/math/base/special/tanh", + "@stdlib/math/base/special/atan", + "@stdlib/math/base/special/asin", + "@stdlib/math/base/special/sin", + "@stdlib/math/base/special/cos", + "@stdlib/math/base/special/abs", + "@stdlib/constants/float64/sqrt-eps", + "@stdlib/constants/float64/eps", + "@stdlib/constants/float64/pi" + ] + } + ] +} diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/package.json b/lib/node_modules/@stdlib/math/base/special/ellipj/package.json index e0f763c6dffa..03ac2bd67869 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/package.json +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/package.json @@ -14,11 +14,14 @@ } ], "main": "./lib", + "gypfile": true, "directories": { "benchmark": "./benchmark", "doc": "./docs", "example": "./examples", + "include": "./include", "lib": "./lib", + "src": "./src", "test": "./test" }, "types": "./docs/types", diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/src/Makefile b/lib/node_modules/@stdlib/math/base/special/ellipj/src/Makefile new file mode 100644 index 000000000000..7733b6180cb4 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/src/Makefile @@ -0,0 +1,70 @@ +#/ +# @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 + + +# RULES # + +#/ +# Removes generated files for building an add-on. +# +# @example +# make clean-addon +#/ +clean-addon: + $(QUIET) -rm -f *.o *.node + +.PHONY: clean-addon + +#/ +# Removes generated files. +# +# @example +# make clean +#/ +clean: clean-addon + +.PHONY: clean diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/src/addon.c b/lib/node_modules/@stdlib/math/base/special/ellipj/src/addon.c new file mode 100644 index 000000000000..ce0d03592122 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/src/addon.c @@ -0,0 +1,42 @@ +/** +* @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/ellipj.h" +#include "stdlib/napi/argv.h" +#include "stdlib/napi/argv_double.h" +#include "stdlib/napi/argv_float64array.h" +#include "stdlib/napi/export.h" +#include + +/** +* Receives JavaScript callback invocation data. +* +* @param env environment under which the function is invoked +* @param info callback data +* @return Node-API value +*/ +static napi_value addon( napi_env env, napi_callback_info info ) { + STDLIB_NAPI_ARGV( env, info, argv, argc, 3 ); + STDLIB_NAPI_ARGV_DOUBLE( env, x, argv, 0 ); + STDLIB_NAPI_ARGV_DOUBLE( env, m, argv, 1 ); + STDLIB_NAPI_ARGV_FLOAT64ARRAY( env, y, ylen, argv, 2 ); + stdlib_base_ellipj( x, m, &y[ 0 ], &y[ 1 ], &y[ 2 ], &y[ 3 ] ); + return NULL; +} + +STDLIB_NAPI_MODULE_EXPORT_FCN( addon ) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/src/main.c b/lib/node_modules/@stdlib/math/base/special/ellipj/src/main.c new file mode 100644 index 000000000000..70393ba4e742 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/src/main.c @@ -0,0 +1,219 @@ +/** +* @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/sincos.h" +#include "stdlib/math/base/special/ellipk.h" +#include "stdlib/math/base/special/floor.h" +#include "stdlib/math/base/special/fmod.h" +#include "stdlib/math/base/special/sqrt.h" +#include "stdlib/math/base/special/cosh.h" +#include "stdlib/math/base/special/sinh.h" +#include "stdlib/math/base/special/tanh.h" +#include "stdlib/math/base/special/atan.h" +#include "stdlib/math/base/special/asin.h" +#include "stdlib/math/base/special/sin.h" +#include "stdlib/math/base/special/cos.h" +#include "stdlib/math/base/special/abs.h" +#include "stdlib/constants/float64/sqrt_eps.h" +#include "stdlib/constants/float64/eps.h" +#include "stdlib/constants/float64/pi.h" +#include +#include + +/** +* Simultaneously computes the Jacobi elliptic functions sn, cn, and dn, and am. +* +* ## Notes +* +* - Values are computed using the arithmetic-geometric from Abramowitz and Stegun 16.4. +* - When m < 0 or m > 1, `sn`, `cn`, and `dn` are computed in terms of elliptic functions with 0 < m < 1 using the transformations from Abramowitz and Stegun 16.10 and 16.11, respectively. Thus the domain of m is any real number. When m < 0 or m > 1, `am` is not computed and will be returned as NaN. +* - Values for small m (m < SQRT_EPS) are computed using the approximations of Abramowitz and Stegun 16.13. For each evaluation, the complete elliptic integral of the first kind, K(m), is computed in order to reduce the period and ensure valid output for all u. +* - Values for m near unity (m > 1 - SQRT_EPS) are computed using the approximations of Abramowitz and Stegun 16.15. For each evaluation, the complete elliptic integral of the first kind, K(m), is computed in order to reduce the period and ensure valid output for all u. +* +* @param u input value +* @param m modulus `m`, equivalent to `k²` +* @param sn destination for the sine amplitude +* @param cn destination for the cosine amplitude +* @param dn destination for the delta amplitude +* @param am destination for the Jacobi amplitude +* +* @example +* double x = 0.3; +* double m = 0.5; +* +* double sn; +* double cn; +* double dn; +* double am; +* stdlib_base_ellipj( x, m, &sn, &cn, &dn, &am ); +*/ +void stdlib_base_ellipj( const double u, const double m, double* sn, double* cn, double* dn, double* am ) { + double out[ 4 ]; + double ca[ 9 ]; + double sc[ 4 ]; + double dnDenom; + double uK2cen; + double k1inv; + double sechu; + double sinhu; + double tanhu; + bool NANFLG; + double phi0; + double phi1; + double atmp; + double gdu; + double uK2; + double uK4; + int32_t N; + double mu; + double K2; + double K4; + double u0; + double k; + double s; + double c; + double f; + double a; + double b; + bool FLG; + + if ( m < 0.0 ) { + // A&S 16.10.1 for a negative parameter, mapping -m to 0 < mu < 1: + mu = -m / ( 1.0 - m ); + k1inv = stdlib_base_sqrt( 1.0 - m ); + stdlib_base_ellipj( u * k1inv, mu, out, out+1, out+2, out+3 ); + *sn = ( out[ 0 ] / out[ 2 ] ) / k1inv; + *cn = out[ 1 ] / out[ 2 ]; + *dn = 1.0 / out[ 2 ]; + *am = 0.0 / 0.0; // NaN + return; + } else if ( m > 1.0 ) { + // A&S 16.11.1 for reciprocal parameter, mapping m > 1 to 0 < mu < 1: + k = stdlib_base_sqrt( m ); + stdlib_base_ellipj( u * k, 1.0 / m, out, out+1, out+2, out+3 ); + *sn = out[ 0 ] / k; + *cn = out[ 2 ]; + *dn = out[ 1 ]; + *am = 0.0 / 0.0; // NaN + return; + } else if ( m == 0.0 ) { + // A&S table 16.6, limiting case m = 0: circular trigonometric functions: + stdlib_base_sincos( u, sc, sc+1 ); + *sn = sc[ 0 ]; + *cn = sc[ 1 ]; + *dn = 1.0; + *am = u; + return; + } else if ( m == 1.0 ) { + // A&S table 16.6: limiting case m = 1: hyperbolic functions: + *sn = stdlib_base_tanh( u ); + *cn = 1.0 / stdlib_base_cosh( u ); + *dn = *cn; + *am = stdlib_base_atan( stdlib_base_sinh( u ) ); + return; + } else if ( m < STDLIB_CONSTANT_FLOAT64_SQRT_EPS ) { + // A&S 16.13.1 for small-u approximations. Additionally, compute K at extra cost in order to ensure returned values are correct outside the range [0, K]: + K4 = 4.0 * stdlib_base_ellipk( m ); + u0 = stdlib_base_fmod( stdlib_base_fmod( u, K4 ) + K4, K4 ); + stdlib_base_sincos( u0, sc, sc+1 ); + s = sc[ 0 ]; + c = sc[ 1 ]; + f = 0.25 * m * ( u0 - ( s * c ) ); + *sn = s - ( f * c ); + *cn = c + ( f * s ); + *dn = 1.0 - ( 0.5 * m * s * s ); + *am = u - ( 0.25 * m * ( u - ( s * c ) ) ); + return; + } else if ( m > 1.0 - STDLIB_CONSTANT_FLOAT64_SQRT_EPS ) { + // A&S 16.15.1 - 16.15.4 for near-unity approximations. Additionally, compute K at extra cost so that we may reflect as needed to ensure the returned values are correct... + + // Reduce by the half-period 2K, centered about u = 0: + K2 = stdlib_base_ellipk( m ) * 2.0; + uK2cen = ( u / K2 ) + 0.5; + uK2 = K2 * ( stdlib_base_fmod( uK2cen, 1.0 ) - 0.5 ); + + // Flip sn and cn in this range to get the reflections correct. We must be careful about precisely reusing uK2cen in order to get the edge cases correct... + uK4 = stdlib_base_fmod( uK2cen, 4.0 ); + FLG = ( uK4 >= 1.0 ) && ( uK4 < 2.0 ); + + sinhu = stdlib_base_sinh( uK2 ); + sechu = 1.0 / stdlib_base_cosh( uK2 ); + tanhu = stdlib_base_tanh( uK2 ); + gdu = ( stdlib_base_floor( uK2cen ) * STDLIB_CONSTANT_FLOAT64_PI ) + stdlib_base_atan( sinhu ); + + a = 0.25 * ( 1.0 - m ); + b = a * ( sinhu - ( uK2 * sechu ) ); + *sn = tanhu + ( b * sechu ); + *cn = sechu - ( b * tanhu ); + *dn = sechu + ( a * ( sinhu + ( uK2 * sechu ) ) * tanhu ); + *am = gdu + b; + + if ( FLG ) { + *sn = -*sn; + *cn = -*cn; + } + return; + } else { + // A&S 16.4.1. Compute using the arithmetic-geometric mean... + a = 1.0; + b = stdlib_base_sqrt( 1.0 - m ); + N = -1; + NANFLG = false; + do { + N += 1; + if ( N > 8 ) { + // Warning: Overflow encountered in iteration. Returning NaN for all output values: + NANFLG = true; + *sn = 0.0 / 0.0; // NaN + *cn = 0.0 / 0.0; // NaN + *dn = 0.0 / 0.0; // NaN + *am = 0.0 / 0.0; // NaN + break; + } + atmp = ( a + b ) * 0.5; + c = ( a - b ) * 0.5; + b = stdlib_base_sqrt( a * b ); + a = atmp; + ca[ N ] = c / a; + } while ( ca[ N ] >= STDLIB_CONSTANT_FLOAT64_EPS ); + + if ( !NANFLG ) { + // A&S 16.4.3: + phi1 = ( 1 << N ) * ( u * a ); + while ( N > 1 ) { + N -= 1; + phi1 = 0.5 * ( phi1 + stdlib_base_asin( ca[ N ] * stdlib_base_sin( phi1 ) ) ); + } + phi0 = 0.5 * ( phi1 + stdlib_base_asin( ca[ 0 ] * stdlib_base_sin( phi1 ) ) ); + + *am = phi0; + stdlib_base_sincos( *am, sc, sc+1 ); + *sn = sc[ 0 ]; + *cn = sc[ 1 ]; + + // When the denominator is small, switch to the definition of dn in terms of sn. Otherwise compute dn from the last two iterates: + dnDenom = stdlib_base_cos( phi1 - phi0 ); + if ( stdlib_base_abs( dnDenom ) < 0.1 ) { + *dn = stdlib_base_sqrt( 1.0 - ( m * (*sn) * (*sn) ) ); + } else { + *dn = *cn / dnDenom; + } + } + return; + } +} diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.assign.js b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.assign.js index c41795584043..7307d0975849 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.assign.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.assign.js @@ -52,11 +52,11 @@ tape( 'the function returns the correct limits for `+infinity` with modulus `1.0 var y; var v = [ 0.0, 0.0, 0.0, 0.0 ]; y = ellipj( PINF, 1.0, v, 1, 0 ); - t.equal( y, v, 'returns output array' ); - t.equal( v[ 0 ], 1.0, 'returns expected value for sn' ); - t.equal( v[ 1 ], 0.0, 'returns expected value for cn' ); - t.equal( v[ 2 ], 0.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], HALF_PI, 'returns expected value for am' ); + t.strictEqual( y, v, 'returns output array' ); + t.strictEqual( v[ 0 ], 1.0, 'returns expected value for sn' ); + t.strictEqual( v[ 1 ], 0.0, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 0.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], HALF_PI, 'returns expected value for am' ); t.end(); }); @@ -64,11 +64,11 @@ tape( 'the function returns the correct limits for `-infinity` with modulus `1.0 var y; var v = [ 0.0, 0.0, 0.0, 0.0 ]; y = ellipj( NINF, 1.0, v, 1, 0 ); - t.equal( y, v, 'returns output array' ); - t.equal( v[ 0 ], -1.0, 'returns expected value for sn' ); - t.equal( v[ 1 ], 0.0, 'returns expected value for cn' ); - t.equal( v[ 2 ], 0.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], -HALF_PI, 'returns expected value for am' ); + t.strictEqual( y, v, 'returns output array' ); + t.strictEqual( v[ 0 ], -1.0, 'returns expected value for sn' ); + t.strictEqual( v[ 1 ], 0.0, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 0.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], -HALF_PI, 'returns expected value for am' ); t.end(); }); @@ -76,11 +76,11 @@ tape( 'the function returns the correct limits for `+infinity` with modulus `0.0 var y; var v = [ 0.0, 0.0, 0.0, 0.0 ]; y = ellipj( PINF, 0.0, v, 1, 0 ); - t.equal( y, v, 'returns output array' ); - t.equal( isnan(v[ 0 ]), true, 'returns expected value for sn' ); - t.equal( isnan(v[ 1 ]), true, 'returns expected value for cn' ); - t.equal( v[ 2 ], 1.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], PINF, 'returns expected value for am' ); + t.strictEqual( y, v, 'returns output array' ); + t.strictEqual( isnan(v[ 0 ]), true, 'returns expected value for sn' ); + t.strictEqual( isnan(v[ 1 ]), true, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 1.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], PINF, 'returns expected value for am' ); t.end(); }); @@ -88,11 +88,11 @@ tape( 'the function returns the correct limits for `-infinity` with modulus `0.0 var y; var v = [ 0.0, 0.0, 0.0, 0.0 ]; y = ellipj( NINF, 0.0, v, 1, 0 ); - t.equal( y, v, 'returns output array' ); - t.equal( isnan(v[ 0 ]), true, 'returns expected value for sn' ); - t.equal( isnan(v[ 1 ]), true, 'returns expected value for cn' ); - t.equal( v[ 2 ], 1.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], NINF, 'returns expected value for am' ); + t.strictEqual( y, v, 'returns output array' ); + t.strictEqual( isnan(v[ 0 ]), true, 'returns expected value for sn' ); + t.strictEqual( isnan(v[ 1 ]), true, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 1.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], NINF, 'returns expected value for am' ); t.end(); }); @@ -119,33 +119,33 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (medium po v = [ 0.0, 0.0, 0.0, 0.0 ]; for ( i = 0; i < u.length; i++ ) { y = ellipj( u[i], m[i], v, 1, 0 ); - t.equal( y, v, 'returns output array' ); + t.strictEqual( y, v, 'returns output array' ); sn = y[0]; cn = y[1]; dn = y[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 18.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 14.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 40.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -174,33 +174,33 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (modulus n v = [ 0.0, 0.0, 0.0, 0.0 ]; for ( i = 0; i < u.length; i++ ) { y = ellipj( u[i], m[i], v, 1, 0 ); - t.equal( y, v, 'returns output array' ); + t.strictEqual( y, v, 'returns output array' ); sn = y[0]; cn = y[1]; dn = y[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 7.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 5.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 5.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -229,33 +229,33 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (small pos v = [ 0.0, 0.0, 0.0, 0.0 ]; for ( i = 0; i < u.length; i++ ) { y = ellipj( u[i], m[i], v, 1, 0 ); - t.equal( y, v, 'returns output array' ); + t.strictEqual( y, v, 'returns output array' ); sn = y[0]; cn = y[1]; dn = y[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 12.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 12.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -284,29 +284,29 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (zero modu v = [ 0.0, 0.0, 0.0, 0.0 ]; for ( i = 0; i < u.length; i++ ) { y = ellipj( u[i], m[i], v, 1, 0 ); - t.equal( y, v, 'returns output array' ); + t.strictEqual( y, v, 'returns output array' ); sn = y[0]; cn = y[1]; dn = y[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } // There is no reason for this to be anything but exactly identical, i.e. 1.0. - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } t.end(); }); @@ -334,33 +334,33 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (unity mod v = [ 0.0, 0.0, 0.0, 0.0 ]; for ( i = 0; i < u.length; i++ ) { y = ellipj( u[i], m[i], v, 1, 0 ); - t.equal( y, v, 'returns output array' ); + t.strictEqual( y, v, 'returns output array' ); sn = y[0]; cn = y[1]; dn = y[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -393,7 +393,7 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (spot chec v = [ 0.0, 0.0, 0.0, 0.0 ]; for ( i = 0; i < u.length; i++ ) { y = ellipj( u[i], m[i], v, 1, 0 ); - t.equal( y, v, 'returns output array' ); + t.strictEqual( y, v, 'returns output array' ); sn = y[0]; cn = y[1]; dn = y[2]; @@ -402,37 +402,37 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (spot chec tolerance = spotChecks.tolerance[ i ]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = tolerance * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = tolerance * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = tolerance * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( amExpected[i] === null ) { - t.equal( isnan(am), true, 'is NaN. u: '+u[i]+'. m: '+m[i]+', am: '+am+'.' ); + t.strictEqual( isnan(am), true, 'is NaN. u: '+u[i]+'. m: '+m[i]+', am: '+am+'.' ); } else if ( am === amExpected[i] ) { - t.equal( am, amExpected[i], 'u: '+u[i]+', m: '+m[i]+', am: '+am+', amExpected: '+amExpected[i] ); + t.strictEqual( am, amExpected[i], 'u: '+u[i]+', m: '+m[i]+', am: '+am+', amExpected: '+amExpected[i] ); } else { delta = abs( am - amExpected[i] ); tol = tolerance * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', am: '+am+'. E: '+amExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', am: '+am+'. E: '+amExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.main.js b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.main.js index c210756cebd7..c4ae271b8157 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.main.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.main.js @@ -49,37 +49,37 @@ tape( 'main export is a function', function test( t ) { tape( 'the function returns the correct limits for `+infinity` with modulus `1.0`', function test( t ) { var v = ellipj( PINF, 1.0 ); - t.equal( v[ 0 ], 1.0, 'returns expected value for sn' ); - t.equal( v[ 1 ], 0.0, 'returns expected value for cn' ); - t.equal( v[ 2 ], 0.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], HALF_PI, 'returns expected value for am' ); + t.strictEqual( v[ 0 ], 1.0, 'returns expected value for sn' ); + t.strictEqual( v[ 1 ], 0.0, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 0.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], HALF_PI, 'returns expected value for am' ); t.end(); }); tape( 'the function returns the correct limits for `-infinity` with modulus `1.0`', function test( t ) { var v = ellipj( NINF, 1.0 ); - t.equal( v[ 0 ], -1.0, 'returns expected value for sn' ); - t.equal( v[ 1 ], 0.0, 'returns expected value for cn' ); - t.equal( v[ 2 ], 0.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], -HALF_PI, 'returns expected value for am' ); + t.strictEqual( v[ 0 ], -1.0, 'returns expected value for sn' ); + t.strictEqual( v[ 1 ], 0.0, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 0.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], -HALF_PI, 'returns expected value for am' ); t.end(); }); tape( 'the function returns the correct limits for `+infinity` with modulus `0.0`', function test( t ) { var v = ellipj( PINF, 0.0 ); - t.equal( isnan(v[ 0 ]), true, 'returns expected value for sn' ); - t.equal( isnan(v[ 1 ]), true, 'returns expected value for cn' ); - t.equal( v[ 2 ], 1.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], PINF, 'returns expected value for am' ); + t.strictEqual( isnan(v[ 0 ]), true, 'returns expected value for sn' ); + t.strictEqual( isnan(v[ 1 ]), true, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 1.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], PINF, 'returns expected value for am' ); t.end(); }); tape( 'the function returns the correct limits for `-infinity` with modulus `0.0`', function test( t ) { var v = ellipj( NINF, 0.0 ); - t.equal( isnan(v[ 0 ]), true, 'returns expected value for sn' ); - t.equal( isnan(v[ 1 ]), true, 'returns expected value for cn' ); - t.equal( v[ 2 ], 1.0, 'returns expected value for dn' ); - t.equal( v[ 3 ], NINF, 'returns expected value for am' ); + t.strictEqual( isnan(v[ 0 ]), true, 'returns expected value for sn' ); + t.strictEqual( isnan(v[ 1 ]), true, 'returns expected value for cn' ); + t.strictEqual( v[ 2 ], 1.0, 'returns expected value for dn' ); + t.strictEqual( v[ 3 ], NINF, 'returns expected value for am' ); t.end(); }); @@ -109,27 +109,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (medium po dn = sncndn[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 18.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 14.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 40.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -161,27 +161,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (modulus n dn = sncndn[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 7.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 5.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 5.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -213,27 +213,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (small pos dn = sncndn[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 12.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 12.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -265,23 +265,23 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (zero modu dn = sncndn[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } // There is no reason for this to be anything but exactly identical, i.e. 1.0. - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } t.end(); }); @@ -312,27 +312,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (unity mod dn = sncndn[2]; if ( sn === snExpected[i] ) { - t.equal( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); } else { delta = abs( sn - snExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cn === cnExpected[i] ) { - t.equal( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cn - cnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dn === dnExpected[i] ) { - t.equal( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dn - dnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.native.js new file mode 100644 index 000000000000..a7425e324bfb --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.native.js @@ -0,0 +1,348 @@ +/** +* @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 tape = require( 'tape' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); +var HALF_PI = require( '@stdlib/constants/float64/half-pi' ); +var EPS = require( '@stdlib/constants/float64/eps' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var tryRequire = require( '@stdlib/utils/try-require' ); + + +// VARIABLES // + +var ellipj = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( ellipj instanceof Error ) +}; + + +// FIXTURES // + +var mediumPositiveModulus = require( './fixtures/cpp/medium_positive_modulus.json' ); +var nearUnityModulus = require( './fixtures/cpp/near_unity_modulus.json' ); +var smallPositiveModulus = require( './fixtures/cpp/small_positive_modulus.json' ); +var zeroModulus = require( './fixtures/cpp/zero_modulus.json' ); +var unityModulus = require( './fixtures/cpp/unity_modulus.json' ); + + +// TESTS // + +tape( 'main export is a function', opts, function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ellipj, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns the correct limits for `+infinity` with modulus `1.0`', opts, function test( t ) { + var v = ellipj( PINF, 1.0 ); + t.strictEqual( v[ 0 ], 1.0, 'returns expected value' ); + t.strictEqual( v[ 1 ], 0.0, 'returns expected value' ); + t.strictEqual( v[ 2 ], 0.0, 'returns expected value' ); + t.strictEqual( v[ 3 ], HALF_PI, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the correct limits for `-infinity` with modulus `1.0`', opts, function test( t ) { + var v = ellipj( NINF, 1.0 ); + t.strictEqual( v[ 0 ], -1.0, 'returns expected value' ); + t.strictEqual( v[ 1 ], 0.0, 'returns expected value' ); + t.strictEqual( v[ 2 ], 0.0, 'returns expected value' ); + t.strictEqual( v[ 3 ], -HALF_PI, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the correct limits for `+infinity` with modulus `0.0`', opts, function test( t ) { + var v = ellipj( PINF, 0.0 ); + t.strictEqual( isnan(v[ 0 ]), true, 'returns expected value' ); + t.strictEqual( isnan(v[ 1 ]), true, 'returns expected value' ); + t.strictEqual( v[ 2 ], 1.0, 'returns expected value' ); + t.strictEqual( v[ 3 ], PINF, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the correct limits for `-infinity` with modulus `0.0`', opts, function test( t ) { + var v = ellipj( NINF, 0.0 ); + t.strictEqual( isnan(v[ 0 ]), true, 'returns expected value' ); + t.strictEqual( isnan(v[ 1 ]), true, 'returns expected value' ); + t.strictEqual( v[ 2 ], 1.0, 'returns expected value' ); + t.strictEqual( v[ 3 ], NINF, 'returns expected value' ); + t.end(); +}); + +tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (medium positive modulus)', opts, function test( t ) { + var snExpected; + var cnExpected; + var dnExpected; + var sncndn; + var delta; + var tol; + var sn; + var cn; + var dn; + var u; + var m; + var i; + + snExpected = mediumPositiveModulus.sn_expected; + cnExpected = mediumPositiveModulus.cn_expected; + dnExpected = mediumPositiveModulus.dn_expected; + u = mediumPositiveModulus.u; + m = mediumPositiveModulus.m; + for ( i = 0; i < u.length; i++ ) { + sncndn = ellipj( u[i], m[i] ); + sn = sncndn[0]; + cn = sncndn[1]; + dn = sncndn[2]; + + if ( sn === snExpected[i] ) { + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + } else { + delta = abs( sn - snExpected[i] ); + tol = 18.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( cn === cnExpected[i] ) { + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + } else { + delta = abs( cn - cnExpected[i] ); + tol = 14.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( dn === dnExpected[i] ) { + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + } else { + delta = abs( dn - dnExpected[i] ); + tol = 40.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (modulus near unity)', opts, function test( t ) { + var snExpected; + var cnExpected; + var dnExpected; + var sncndn; + var delta; + var tol; + var sn; + var cn; + var dn; + var u; + var m; + var i; + + snExpected = nearUnityModulus.sn_expected; + cnExpected = nearUnityModulus.cn_expected; + dnExpected = nearUnityModulus.dn_expected; + u = nearUnityModulus.u; + m = nearUnityModulus.m; + for ( i = 0; i < u.length; i++ ) { + sncndn = ellipj( u[i], m[i] ); + sn = sncndn[0]; + cn = sncndn[1]; + dn = sncndn[2]; + + if ( sn === snExpected[i] ) { + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + } else { + delta = abs( sn - snExpected[i] ); + tol = 7.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( cn === cnExpected[i] ) { + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + } else { + delta = abs( cn - cnExpected[i] ); + tol = 5.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( dn === dnExpected[i] ) { + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + } else { + delta = abs( dn - dnExpected[i] ); + tol = 5.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (small positive modulus)', opts, function test( t ) { + var snExpected; + var cnExpected; + var dnExpected; + var sncndn; + var delta; + var tol; + var sn; + var cn; + var dn; + var u; + var m; + var i; + + snExpected = smallPositiveModulus.sn_expected; + cnExpected = smallPositiveModulus.cn_expected; + dnExpected = smallPositiveModulus.dn_expected; + u = smallPositiveModulus.u; + m = smallPositiveModulus.m; + for ( i = 0; i < u.length; i++ ) { + sncndn = ellipj( u[i], m[i] ); + sn = sncndn[0]; + cn = sncndn[1]; + dn = sncndn[2]; + + if ( sn === snExpected[i] ) { + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + } else { + delta = abs( sn - snExpected[i] ); + tol = 12.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( cn === cnExpected[i] ) { + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + } else { + delta = abs( cn - cnExpected[i] ); + tol = 12.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( dn === dnExpected[i] ) { + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + } else { + delta = abs( dn - dnExpected[i] ); + tol = 1.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (zero modulus)', opts, function test( t ) { + var snExpected; + var cnExpected; + var dnExpected; + var sncndn; + var delta; + var tol; + var sn; + var cn; + var dn; + var u; + var m; + var i; + + snExpected = zeroModulus.sn_expected; + cnExpected = zeroModulus.cn_expected; + dnExpected = zeroModulus.dn_expected; + u = zeroModulus.u; + m = zeroModulus.m; + for ( i = 0; i < u.length; i++ ) { + sncndn = ellipj( u[i], m[i] ); + sn = sncndn[0]; + cn = sncndn[1]; + dn = sncndn[2]; + + if ( sn === snExpected[i] ) { + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + } else { + delta = abs( sn - snExpected[i] ); + tol = 1.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( cn === cnExpected[i] ) { + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + } else { + delta = abs( cn - cnExpected[i] ); + tol = 1.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + // There is no reason for this to be anything but exactly identical, i.e. 1.0. + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + } + t.end(); +}); + +tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (unity modulus)', opts, function test( t ) { + var snExpected; + var cnExpected; + var dnExpected; + var sncndn; + var delta; + var tol; + var sn; + var cn; + var dn; + var u; + var m; + var i; + + snExpected = unityModulus.sn_expected; + cnExpected = unityModulus.cn_expected; + dnExpected = unityModulus.dn_expected; + u = unityModulus.u; + m = unityModulus.m; + for ( i = 0; i < u.length; i++ ) { + sncndn = ellipj( u[i], m[i] ); + sn = sncndn[0]; + cn = sncndn[1]; + dn = sncndn[2]; + + if ( sn === snExpected[i] ) { + t.strictEqual( sn, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+sn+', snExpected: '+snExpected[i] ); + } else { + delta = abs( sn - snExpected[i] ); + tol = 1.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+sn+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( cn === cnExpected[i] ) { + t.strictEqual( cn, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cn+', cnExpected: '+cnExpected[i] ); + } else { + delta = abs( cn - cnExpected[i] ); + tol = 1.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cn+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + + if ( dn === dnExpected[i] ) { + t.strictEqual( dn, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dn+', dnExpected: '+dnExpected[i] ); + } else { + delta = abs( dn - dnExpected[i] ); + tol = 1.0 * EPS; + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dn+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.sncndn.js b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.sncndn.js index 122acab66163..7c124969891f 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.sncndn.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipj/test/test.sncndn.js @@ -16,6 +16,8 @@ * limitations under the License. */ +/* eslint-disable stdlib/first-unit-test */ + 'use strict'; // MODULES // @@ -69,34 +71,34 @@ tape( 'am export is a function', function test( t ) { }); tape( 'the function returns the correct limits for `+infinity` with modulus `1.0`', function test( t ) { - t.equal( sn( PINF, 1.0 ), 1.0, 'returns expected value for sn' ); - t.equal( cn( PINF, 1.0 ), 0.0, 'returns expected value for cn' ); - t.equal( dn( PINF, 1.0 ), 0.0, 'returns expected value for dn' ); - t.equal( am( PINF, 1.0 ), HALF_PI, 'returns expected value for am' ); + t.strictEqual( sn( PINF, 1.0 ), 1.0, 'returns expected value for sn' ); + t.strictEqual( cn( PINF, 1.0 ), 0.0, 'returns expected value for cn' ); + t.strictEqual( dn( PINF, 1.0 ), 0.0, 'returns expected value for dn' ); + t.strictEqual( am( PINF, 1.0 ), HALF_PI, 'returns expected value for am' ); t.end(); }); tape( 'the function returns the correct limits for `-infinity` with modulus `1.0`', function test( t ) { - t.equal( sn( NINF, 1.0 ), -1.0, 'returns expected value for sn' ); - t.equal( cn( NINF, 1.0 ), 0.0, 'returns expected value for cn' ); - t.equal( dn( NINF, 1.0 ), 0.0, 'returns expected value for dn' ); - t.equal( am( NINF, 1.0 ), -HALF_PI, 'returns expected value for am' ); + t.strictEqual( sn( NINF, 1.0 ), -1.0, 'returns expected value for sn' ); + t.strictEqual( cn( NINF, 1.0 ), 0.0, 'returns expected value for cn' ); + t.strictEqual( dn( NINF, 1.0 ), 0.0, 'returns expected value for dn' ); + t.strictEqual( am( NINF, 1.0 ), -HALF_PI, 'returns expected value for am' ); t.end(); }); tape( 'the function returns the correct limits for `+infinity` with modulus `0.0`', function test( t ) { - t.equal( isnan(sn( PINF, 0.0 )), true, 'returns expected value for sn' ); - t.equal( isnan(cn( PINF, 0.0 )), true, 'returns expected value for cn' ); - t.equal( dn( PINF, 0.0 ), 1.0, 'returns expected value for dn' ); - t.equal( am( PINF, 0.0 ), PINF, 'returns expected value for am' ); + t.strictEqual( isnan(sn( PINF, 0.0 )), true, 'returns expected value for sn' ); + t.strictEqual( isnan(cn( PINF, 0.0 )), true, 'returns expected value for cn' ); + t.strictEqual( dn( PINF, 0.0 ), 1.0, 'returns expected value for dn' ); + t.strictEqual( am( PINF, 0.0 ), PINF, 'returns expected value for am' ); t.end(); }); tape( 'the function returns the correct limits for `-infinity` with modulus `0.0`', function test( t ) { - t.equal( isnan(sn( NINF, 0.0 )), true, 'returns expected value for sn' ); - t.equal( isnan(cn( NINF, 0.0 )), true, 'returns expected value for cn' ); - t.equal( dn( NINF, 0.0 ), 1.0, 'returns expected value for dn' ); - t.equal( am( NINF, 0.0 ), NINF, 'returns expected value for am' ); + t.strictEqual( isnan(sn( NINF, 0.0 )), true, 'returns expected value for sn' ); + t.strictEqual( isnan(cn( NINF, 0.0 )), true, 'returns expected value for cn' ); + t.strictEqual( dn( NINF, 0.0 ), 1.0, 'returns expected value for dn' ); + t.strictEqual( am( NINF, 0.0 ), NINF, 'returns expected value for am' ); t.end(); }); @@ -124,27 +126,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (medium po dnval = dn( u[i], m[i] ); if ( snval === snExpected[i] ) { - t.equal( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); + t.strictEqual( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); } else { delta = abs( snval - snExpected[i] ); tol = 18.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cnval === cnExpected[i] ) { - t.equal( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cnval - cnExpected[i] ); tol = 14.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dnval === dnExpected[i] ) { - t.equal( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dnval - dnExpected[i] ); tol = 40.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -174,27 +176,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (modulus n dnval = dn( u[i], m[i] ); if ( snval === snExpected[i] ) { - t.equal( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); + t.strictEqual( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); } else { delta = abs( snval - snExpected[i] ); tol = 7.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cnval === cnExpected[i] ) { - t.equal( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cnval - cnExpected[i] ); tol = 5.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dnval === dnExpected[i] ) { - t.equal( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dnval - dnExpected[i] ); tol = 5.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -224,27 +226,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (small pos dnval = dn( u[i], m[i] ); if ( snval === snExpected[i] ) { - t.equal( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); + t.strictEqual( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); } else { delta = abs( snval - snExpected[i] ); tol = 12.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cnval === cnExpected[i] ) { - t.equal( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cnval - cnExpected[i] ); tol = 12.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dnval === dnExpected[i] ) { - t.equal( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dnval - dnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end(); @@ -274,23 +276,23 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (zero modu dnval = dn( u[i], m[i] ); if ( snval === snExpected[i] ) { - t.equal( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); + t.strictEqual( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); } else { delta = abs( snval - snExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cnval === cnExpected[i] ) { - t.equal( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cnval - cnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } // There is no reason for this to be anything but exactly identical, i.e. 1.0. - t.equal( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); } t.end(); }); @@ -319,27 +321,27 @@ tape( 'the function evaluates the Jacobi elliptic functions sn, cn dn (unity mod dnval = dn( u[i], m[i] ); if ( snval === snExpected[i] ) { - t.equal( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); + t.strictEqual( snval, snExpected[i], 'u: '+u[i]+', m: '+m[i]+', sn: '+snval+', snExpected: '+snExpected[i] ); } else { delta = abs( snval - snExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', sn: '+snval+'. E: '+snExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( cnval === cnExpected[i] ) { - t.equal( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); + t.strictEqual( cnval, cnExpected[i], 'u: '+u[i]+', m: '+m[i]+', cn: '+cnval+', cnExpected: '+cnExpected[i] ); } else { delta = abs( cnval - cnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', cn: '+cnval+'. E: '+cnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } if ( dnval === dnExpected[i] ) { - t.equal( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); + t.strictEqual( dnval, dnExpected[i], 'u: '+u[i]+', m: '+m[i]+', dn: '+dnval+', dnExpected: '+dnExpected[i] ); } else { delta = abs( dnval - dnExpected[i] ); tol = 1.0 * EPS; - t.equal( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + t.strictEqual( delta <= tol, true, 'within tolerance. u: '+u[i]+'. m: '+m[i]+', dn: '+dnval+'. E: '+dnExpected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); } } t.end();