From ed561b656979ecd88c3719865cc394040fc14632 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 10:09:27 +0530 Subject: [PATCH 01/15] add c-api documentation in readme --- .../math/base/special/ellipk/README.md | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/README.md b/lib/node_modules/@stdlib/math/base/special/ellipk/README.md index eb4b6e93e0d5..4ff90a120c20 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/README.md +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/README.md @@ -2,7 +2,7 @@ @license Apache-2.0 -Copyright (c) 2019 The Stdlib Authors. +Copyright (c) 2022 The Stdlib Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -110,6 +110,96 @@ for ( i = 0; i < 100; i++ ) { + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/math/base/special/ellipk.h" +``` + +#### stdlib_base_ellipk( x ) + +Computes the [complete elliptic integral of the first kind][elliptic-integral]. + +```c +double out = stdlib_base_ellipk( 0.5 ); +// returns ~1.854 + +out = stdlib_base_ellipk( -1.0 ); +// returns ~1.311 +``` + +The function accepts the following arguments: + +- **x**: `[in] double` input value. + +```c +double stdlib_base_ellipk( const double x ); +``` + +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/math/base/special/ellipk.h" +#include +#include + +int main() { + double x; + double v; + int i; + + for ( i = 0; i < 100; i++ ) { + x = -1.0 + ( (double)rand() / (double)RAND_MAX ) * 2.0; + v = stdlib_base_ellipk( x ); + printf( "ellipk(%lf) = %lf\n", x, v ); + } +} +``` + +
+ + + +
+ + + * * *
From 887a7155edc7c41a54192faa9c171a8b174f3f60 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 10:11:08 +0530 Subject: [PATCH 02/15] add include.gypi and binding.gyp --- .../math/base/special/ellipk/binding.gyp | 170 ++++++++++++++++++ .../math/base/special/ellipk/include.gypi | 53 ++++++ 2 files changed, 223 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/binding.gyp create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/include.gypi diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/binding.gyp b/lib/node_modules/@stdlib/math/base/special/ellipk/binding.gyp new file mode 100644 index 000000000000..1058b57bab16 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/binding.gyp @@ -0,0 +1,170 @@ +# @license Apache-2.0 +# +# Copyright (c) 2022 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/ellipk/include.gypi b/lib/node_modules/@stdlib/math/base/special/ellipk/include.gypi new file mode 100644 index 000000000000..3b437d524797 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/include.gypi @@ -0,0 +1,53 @@ +# @license Apache-2.0 +# +# Copyright (c) 2022 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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': [ + ' Date: Sat, 24 Dec 2022 10:12:33 +0530 Subject: [PATCH 03/15] add ellipk.h --- .../include/stdlib/math/base/special/ellipk.h | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h b/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h new file mode 100644 index 000000000000..e1c167b0d3f3 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h @@ -0,0 +1,38 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef STDLIB_MATH_BASE_SPECIAL_ELLIPK_H +#define STDLIB_MATH_BASE_SPECIAL_ELLIPK_H + +/* +* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +/** +* Computes the complete elliptic integral of the first kind. +*/ +double stdlib_base_ellipk( const double x ); + +#ifdef __cplusplus +} +#endif + +#endif // !STDLIB_MATH_BASE_SPECIAL_ELLIPK_H From cc026bcb65a590115464e095d5ea8d6d52176bd1 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 10:59:15 +0530 Subject: [PATCH 04/15] add Makefile, addon.c and main.c in src/ --- .../math/base/special/ellipk/src/Makefile | 70 ++++ .../math/base/special/ellipk/src/addon.c | 23 ++ .../math/base/special/ellipk/src/main.c | 365 ++++++++++++++++++ 3 files changed, 458 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/src/Makefile create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/src/addon.c create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/src/Makefile b/lib/node_modules/@stdlib/math/base/special/ellipk/src/Makefile new file mode 100644 index 000000000000..f79b87238713 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/src/Makefile @@ -0,0 +1,70 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2022 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/ellipk/src/addon.c b/lib/node_modules/@stdlib/math/base/special/ellipk/src/addon.c new file mode 100644 index 000000000000..6e5c10258f41 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/src/addon.c @@ -0,0 +1,23 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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/ellipk.h" +#include "stdlib/math/base/napi/unary.h" + +// cppcheck-suppress shadowFunction +STDLIB_MATH_BASE_NAPI_MODULE_D_D( stdlib_base_ellipk ) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c b/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c new file mode 100644 index 000000000000..371ebc488763 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c @@ -0,0 +1,365 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* +* ## Notice +* +* The original Julia code and copyright notice are from the [Julia library]{@link https://github.com/JuliaMath/SpecialFunctions.jl/blob/master/src/ellip.jl}. The implementation has been modified for JavaScript. +* +* ```text +* The MIT License (MIT) +* +* Copyright (c) 2017 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and others: +* +* https://github.com/JuliaMath/SpecialFunctions.jl/graphs/contributors +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* ``` +*/ + +#include "stdlib/math/base/special/ellipk.h" +#include "stdlib/math/base/special/sqrt.h" +#include "stdlib/math/base/special/ln.h" +#include "stdlib/constants/float64/pinf.h" +#include "stdlib/constants/float64/half_pi.h" + +static const double ONE_DIV_PI = 0.3183098861837907; + +/* Begin auto-generated functions. The following functions are auto-generated. Do not edit directly. */ + +// BEGIN: poly_p1 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p1( const double x ) { + return 1.5910034537907922 + (x * (0.41600074399178694 + (x * (0.24579151426410342 + (x * (0.17948148291490615 + (x * (0.14455605708755515 + (x * (0.12320099331242772 + (x * (0.10893881157429353 + (x * (0.09885340987159291 + (x * (0.09143962920174975 + (x * (0.0858425915954139 + (x * 0.08154111871830322))))))))))))))))))); +} + +// END: poly_p1 + +// BEGIN: poly_p2 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p2( const double x ) { + return 1.63525673226458 + (x * (0.4711906261487323 + (x * (0.3097284108314996 + (x * (0.2522083117731357 + (x * (0.22672562321968465 + (x * (0.21577444672958598 + (x * (0.21310877187734892 + (x * (0.21602912460518828 + (x * (0.2232558316330579 + (x * (0.23418050129420992 + (x * (0.24855768297226408 + (x * 0.26636380989261754))))))))))))))))))))); +} + +// END: poly_p2 + +// BEGIN: poly_p3 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p3( const double x ) { + return 1.685750354812596 + (x * (0.5417318486132803 + (x * (0.40152443839069024 + (x * (0.3696424734208891 + (x * (0.37606071535458363 + (x * (0.4052358870851259 + (x * (0.45329438175399905 + (x * (0.5205189476511842 + (x * (0.609426039204995 + (x * (0.7242635222829089 + (x * (0.8710138477098124 + (x * 1.057652872753547))))))))))))))))))))); +} + +// END: poly_p3 + +// BEGIN: poly_p4 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p4( const double x ) { + return 1.7443505972256133 + (x * (0.6348642753719353 + (x * (0.5398425641644455 + (x * (0.5718927051937874 + (x * (0.6702951362654062 + (x * (0.8325865900109772 + (x * (1.0738574482479333 + (x * (1.4220914606754977 + (x * (1.9203871834023047 + (x * (2.6325525483316543 + (x * (3.6521097473190394 + (x * (5.115867135558866 + (x * 7.224080007363877))))))))))))))))))))))); +} + +// END: poly_p4 + +// BEGIN: poly_p5 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p5( const double x ) { + return 1.8138839368169826 + (x * (0.7631632457005573 + (x * (0.7619286053215958 + (x * (0.9510746536684279 + (x * (1.315180671703161 + (x * (1.9285606934774109 + (x * (2.9375093425313787 + (x * (4.594894405442878 + (x * (7.33007122188172 + (x * (11.871512597425301 + (x * (19.45851374822938 + (x * (32.20638657246427 + (x * (53.73749198700555 + (x * 90.27388602941))))))))))))))))))))))))); +} + +// END: poly_p5 + +// BEGIN: poly_p6 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p6( const double x ) { + return 1.8989249102715535 + (x * (0.9505217946182445 + (x * (1.1510775899590158 + (x * (1.7502391069863006 + (x * (2.952676812636875 + (x * (5.285800396121451 + (x * (9.83248571665998 + (x * (18.787148683275596 + (x * (36.61468615273698 + (x * (72.45292395127771 + (x * (145.1079577347069 + (x * (293.4786396308497 + (x * (598.385181505501 + (x * (1228.4200130758634 + (x * 2536.5297553827645))))))))))))))))))))))))))); +} + +// END: poly_p6 + +// BEGIN: poly_p7 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p7( const double x ) { + return 2.0075983984243764 + (x * (1.2484572312123474 + (x * (1.9262346570764797 + (x * (3.7512896400875877 + (x * (8.119944554932045 + (x * (18.665721308735552 + (x * (44.603924842914374 + (x * (109.50920543094983 + (x * (274.2779548232414 + (x * (697.5598008606327 + (x * (1795.7160145002472 + (x * (4668.38171679039 + (x * (12235.762468136643 + (x * (32290.17809718321 + (x * (85713.07608195965 + (x * (228672.1890493117 + (x * 612757.2711915852))))))))))))))))))))))))))))))); +} + +// END: poly_p7 + +// BEGIN: poly_p8 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p8( const double x ) { + return 2.1565156474996434 + (x * (1.7918056418494632 + (x * (3.8267512874657132 + (x * (10.386724683637972 + (x * (31.403314054680703 + (x * (100.92370394986955 + (x * (337.3268282632273 + (x * (1158.7079305678278 + (x * (4060.9907421936323 + (x * (14454.001840343448 + (x * (52076.661075994045 + (x * (189493.65914621568 + (x * (695184.5762413896 + (x * (2567994.048255285 + (x * (9541921.966748387 + (x * (35634927.44218076 + (x * (133669298.46120408 + (x * (503352186.68662846 + (x * (1901975729.53866 + (x * 7208915015.330104))))))))))))))))))))))))))))))))))))); +} + +// END: poly_p8 + +// BEGIN: poly_p9 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p9( const double x ) { + return 2.3181226217125106 + (x * (2.6169201502912327 + (x * (7.897935075731356 + (x * (30.502397154466724 + (x * (131.48693655235286 + (x * (602.9847637356492 + (x * (2877.024617809973 + (x * (14110.519919151804 + (x * (70621.4408815654 + (x * (358977.266582531 + (x * (1847238.2637239718 + (x * (9600515.416049214 + (x * (50307677.08502367 + (x * (265444188.6527128 + (x * (1408862325.0287027 + (x * 7515687935.373775))))))))))))))))))))))))))))); +} + +// END: poly_p9 + +// BEGIN: poly_p10 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p10( const double x ) { + return 2.473596173751344 + (x * (3.727624244118099 + (x * (15.607393035549306 + (x * (84.12850842805888 + (x * (506.98181970406137 + (x * (3252.2770581451236 + (x * (21713.242419574344 + (x * (149037.04518909327 + (x * (1043999.3310899908 + (x * (7427974.817042039 + (x * (53503839.67558661 + (x * (389249886.99487084 + (x * (2855288351.1008105 + (x * (21090077038.76684 + (x * (156699833947.7902 + (x * (1170222242422.44 + (x * (8777948323668.9375 + (x * (66101242752484.95 + (x * (499488053713388.8 + (x * 37859743397240296.0))))))))))))))))))))))))))))))))))))); +} + +// END: poly_p10 + +// BEGIN: poly_p11 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p11( const double x ) { + return 0.0 + (x * (0.0625 + (x * (0.03125 + (x * (0.0205078125 + (x * (0.01513671875 + (x * (0.011934280395507812 + (x * (0.009816169738769531 + (x * (0.008315593004226685 + (x * (0.007199153304100037 + (x * (0.00633745662344154 + (x * (0.00565311038371874 + (x * (0.005097046040418718 + (x * (0.004636680381850056 + (x * (0.004249547423822886 + (x * 0.003919665602267974))))))))))))))))))))))))))); +} + +// END: poly_p11 + +// BEGIN: poly_p12 + +/** +* Evaluates a polynomial. +* +* ## Notes +* +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the polynomial +* @return evaluated polynomial +*/ +static double poly_p12( const double x ) { + return 1.5910034537907922 + (x * (0.41600074399178694 + (x * (0.24579151426410342 + (x * (0.17948148291490615 + (x * (0.14455605708755515 + (x * (0.12320099331242772 + (x * (0.10893881157429353 + (x * (0.09885340987159291 + (x * (0.09143962920174975 + (x * (0.0858425915954139 + (x * 0.08154111871830322))))))))))))))))))); +} + +// END: poly_p12 + +/* End auto-generated functions. */ + +/** +* Computes the complete elliptic integral of the first kind. +* +* @param x input value +* @return output value +* +* @example +* double out = stdlib_base_ellipk( 0.5 ); +* // returns ~1.854 +*/ +double stdlib_base_ellipk( const double m ) { + int32_t FLG = 0; + double kdm; + double td; + double qd; + double t; + double x; + + x = m; + if ( m < 0.0 ) { + x = m / ( m - 1.0 ); + FLG = 1; + } + if ( x == 0.0 ) { + return STDLIB_CONSTANT_FLOAT64_HALF_PI + } + if ( x == 1.0 ) { + return STDLIB_CONSTANT_FLOAT64_PINF + } + if ( x > 1.0 ) { + return 0.0 / 0.0; //NaN + } + if ( x < 0.1 ) { + t = poly_p1( x - 0.05 ); + } else if ( x < 0.2 ) { + t = poly_p2( x - 0.15 ); + } else if ( x < 0.3 ) { + t = poly_p3( x - 0.25 ); + } else if ( x < 0.4 ) { + t = poly_p4( x - 0.35 ); + } else if ( x < 0.5 ) { + t = poly_p5( x - 0.45 ); + } else if ( x < 0.6 ) { + t = poly_p6( x - 0.55 ); + } else if ( x < 0.7 ) { + t = poly_p7( x - 0.65 ); + } else if ( x < 0.8 ) { + t = poly_p8( x - 0.75 ); + } else if ( x < 0.85 ) { + t = poly_p9( x - 0.825 ); + } else if ( x < 0.9 ) { + t = poly_p10( x - 0.875 ); + } else { + td = 1.0 - x; + qd = poly_p11( td ); + kdm = poly_p12( td - 0.05 ); + t = -stdlib_base_ln( qd ) * ( kdm * ONE_DIV_PI ); + } + if ( FLG == 1) { + // Complete the transformation mentioned above for m < 0: + return t / stdlib_base_sqrt( 1.0 - m ); + } + return t; +} From cd83e24fa90aeb45d4c6f1258effe0589f8c4a05 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 10:59:31 +0530 Subject: [PATCH 05/15] update evalpoly.js --- .../base/special/ellipk/scripts/evalpoly.js | 94 ++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/scripts/evalpoly.js b/lib/node_modules/@stdlib/math/base/special/ellipk/scripts/evalpoly.js index 3f8b4c89099d..061a63b8ae71 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/scripts/evalpoly.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/scripts/evalpoly.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2019 The Stdlib Authors. +* Copyright (c) 2022 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +24,15 @@ // MODULES // var resolve = require( 'path' ).resolve; +var readFileSync = require( '@stdlib/fs/read-file' ).sync; var writeFileSync = require( '@stdlib/fs/write-file' ).sync; var currentYear = require( '@stdlib/time/current-year' ); +var substringBefore = require( '@stdlib/string/substring-before' ); +var substringAfter = require( '@stdlib/string/substring-after' ); +var format = require( '@stdlib/string/format' ); var licenseHeader = require( '@stdlib/_tools/licenses/header' ); var compile = require( '@stdlib/math/base/tools/evalpoly-compile' ); +var compileC = require( '@stdlib/math/base/tools/evalpoly-compile-c' ); // VARIABLES // @@ -266,6 +271,33 @@ var header = licenseHeader( 'Apache-2.0', 'js', { header += '\n/* This is a generated file. Do not edit directly. */\n'; +// FUNCTIONS // + +/** +* Inserts a compiled function into file content. +* +* @private +* @param {string} text - source content +* @param {string} id - function identifier +* @param {string} str - function string +* @returns {string} updated content +*/ +function insert( text, id, str ) { + var before; + var after; + var begin; + var end; + + begin = '// BEGIN: '+id; + end = '// END: '+id; + + before = substringBefore( text, begin ); + after = substringAfter( text, end ); + + return format( '%s// BEGIN: %s\n\n%s\n%s%s', before, id, str, end, after ); +} + + // MAIN // /** @@ -275,7 +307,9 @@ header += '\n/* This is a generated file. Do not edit directly. */\n'; */ function main() { var fpath; + var copts; var opts; + var file; var str; opts = { @@ -329,6 +363,64 @@ function main() { fpath = resolve( __dirname, '..', 'lib', 'poly_p12.js' ); str = header + compile( P12 ); writeFileSync( fpath, str, opts ); + + copts = { + 'dtype': 'double', + 'name': '' + }; + + fpath = resolve( __dirname, '..', 'src', 'main.c' ); + file = readFileSync( fpath, opts ); + + copts.name = 'poly_p1'; + str = compileC( P1, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p2'; + str = compileC( P2, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p3'; + str = compileC( P3, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p4'; + str = compileC( P4, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p5'; + str = compileC( P5, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p6'; + str = compileC( P6, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p7'; + str = compileC( P7, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p8'; + str = compileC( P8, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p9'; + str = compileC( P9, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p10'; + str = compileC( P10, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p11'; + str = compileC( P11, copts ); + file = insert( file, copts.name, str ); + + copts.name = 'poly_p12'; + str = compileC( P12, copts ); + file = insert( file, copts.name, str ); + + writeFileSync( fpath, file, opts ); } main(); From fb2d904c23f3f402bd4917caeb798e80dace4208 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:00:25 +0530 Subject: [PATCH 06/15] change variable x to m in readme and ellipk.h --- .../@stdlib/math/base/special/ellipk/README.md | 12 ++++++------ .../ellipk/include/stdlib/math/base/special/ellipk.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/README.md b/lib/node_modules/@stdlib/math/base/special/ellipk/README.md index 4ff90a120c20..a0e38f5362c5 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/README.md +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/README.md @@ -136,7 +136,7 @@ for ( i = 0; i < 100; i++ ) { #include "stdlib/math/base/special/ellipk.h" ``` -#### stdlib_base_ellipk( x ) +#### stdlib_base_ellipk( m ) Computes the [complete elliptic integral of the first kind][elliptic-integral]. @@ -153,7 +153,7 @@ The function accepts the following arguments: - **x**: `[in] double` input value. ```c -double stdlib_base_ellipk( const double x ); +double stdlib_base_ellipk( const double m ); ```
@@ -180,14 +180,14 @@ double stdlib_base_ellipk( const double x ); #include int main() { - double x; + double m; double v; int i; for ( i = 0; i < 100; i++ ) { - x = -1.0 + ( (double)rand() / (double)RAND_MAX ) * 2.0; - v = stdlib_base_ellipk( x ); - printf( "ellipk(%lf) = %lf\n", x, v ); + m = -1.0 + ( (double)rand() / (double)RAND_MAX ) * 2.0; + v = stdlib_base_ellipk( m ); + printf( "ellipk(%lf) = %lf\n", m, v ); } } ``` diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h b/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h index e1c167b0d3f3..d83d054d9773 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/include/stdlib/math/base/special/ellipk.h @@ -29,7 +29,7 @@ extern "C" { /** * Computes the complete elliptic integral of the first kind. */ -double stdlib_base_ellipk( const double x ); +double stdlib_base_ellipk( const double m ); #ifdef __cplusplus } From 392162a99f74a6b83dff18ed2df1a44ad3c3ac31 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:02:09 +0530 Subject: [PATCH 07/15] add manifest.json --- .../math/base/special/ellipk/manifest.json | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json b/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json new file mode 100644 index 000000000000..d735fc73d603 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json @@ -0,0 +1,81 @@ +{ + "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/math/base/napi/unary", + "@stdlib/constants/float64/hal-pi", + "@stdlib/constants/float64/pinf", + "@stdlib/math/base/special/sqrt", + "@stdlib/math/base/special/ln" + ] + }, + { + "task": "benchmark", + "src": [ + "./src/main.c" + ], + "include": [ + "./include" + ], + "libraries": [], + "libpath": [], + "dependencies": [ + "@stdlib/constants/float64/hal-pi", + "@stdlib/constants/float64/pinf", + "@stdlib/math/base/special/sqrt", + "@stdlib/math/base/special/ln" + ] + }, + { + "task": "examples", + "src": [ + "./src/main.c" + ], + "include": [ + "./include" + ], + "libraries": [], + "libpath": [], + "dependencies": [ + "@stdlib/constants/float64/hal-pi", + "@stdlib/constants/float64/pinf", + "@stdlib/math/base/special/sqrt", + "@stdlib/math/base/special/ln" + ] + } + ] +} From a108fb392e1a4c72423d0c0f6a13dbe89c0e2f75 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:03:25 +0530 Subject: [PATCH 08/15] add native.js in lib/ --- .../math/base/special/ellipk/lib/native.js | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js b/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js new file mode 100644 index 000000000000..8d5a55dea450 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js @@ -0,0 +1,62 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var addon = require( './../src/addon.node' ); + + +// MAIN // + +/** +* Computes the complete elliptic integral of the first kind. +* +* @private + +* @param {number} m - input value +* @returns {number} evaluated elliptic integral +* +* @example +* var v = ellipk( 0.5 ); +* // returns ~1.854 +* +* v = ellipk( 2.0 ); +* // returns NaN +* +* v = ellipk( -1.0 ); +* // returns ~1.311 +* +* v = ellipk( Infinity ); +* // returns NaN +* +* v = ellipk( -Infinity ); +* // returns NaN +* +* v = ellipk( NaN ); +* // returns NaN +*/ +function ellipk( m ) { + return addon( m ); +} + + +// EXPORTS // + +module.exports = ellipk; From b92975d1c3decd754c4ef8ae3a6acfd4ba55a2cd Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:07:42 +0530 Subject: [PATCH 09/15] fix dependency in manifest.json --- .../@stdlib/math/base/special/ellipk/manifest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json b/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json index d735fc73d603..436f90cc4854 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/manifest.json @@ -37,7 +37,7 @@ "libpath": [], "dependencies": [ "@stdlib/math/base/napi/unary", - "@stdlib/constants/float64/hal-pi", + "@stdlib/constants/float64/half-pi", "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/sqrt", "@stdlib/math/base/special/ln" @@ -54,7 +54,7 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/constants/float64/hal-pi", + "@stdlib/constants/float64/half-pi", "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/sqrt", "@stdlib/math/base/special/ln" @@ -71,7 +71,7 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/constants/float64/hal-pi", + "@stdlib/constants/float64/half-pi", "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/sqrt", "@stdlib/math/base/special/ln" From dbad64474d3c1f0204f87abcc90e690d282311de Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:07:57 +0530 Subject: [PATCH 10/15] add missing ; in main.c --- lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c b/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c index 371ebc488763..9ccad444bbe7 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c @@ -52,6 +52,7 @@ #include "stdlib/math/base/special/ln.h" #include "stdlib/constants/float64/pinf.h" #include "stdlib/constants/float64/half_pi.h" +#include static const double ONE_DIV_PI = 0.3183098861837907; @@ -323,10 +324,10 @@ double stdlib_base_ellipk( const double m ) { FLG = 1; } if ( x == 0.0 ) { - return STDLIB_CONSTANT_FLOAT64_HALF_PI + return STDLIB_CONSTANT_FLOAT64_HALF_PI; } if ( x == 1.0 ) { - return STDLIB_CONSTANT_FLOAT64_PINF + return STDLIB_CONSTANT_FLOAT64_PINF; } if ( x > 1.0 ) { return 0.0 / 0.0; //NaN From 39e43a84f3add921de15b2455fd27d1b70bde36a Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:08:10 +0530 Subject: [PATCH 11/15] add c examples --- .../base/special/ellipk/examples/c/Makefile | 146 ++++++++++++++++++ .../base/special/ellipk/examples/c/example.c | 33 ++++ 2 files changed, 179 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/Makefile create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/Makefile b/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/Makefile new file mode 100644 index 000000000000..91d364d19fc3 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2022 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/ellipk/examples/c/example.c b/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c new file mode 100644 index 000000000000..8ed584b54a02 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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/ellipk.h" +#include +#include + +int main() { + double m; + double v; + int i; + + for ( i = 0; i < 100; i++ ) { + m = -1.0 + ( (double)rand() / (double)RAND_MAX ) * 2.0; + v = stdlib_base_ellipk( m ); + printf( "ellipk(%lf) = %lf\n", m, v ); + } +} From 404a93cddf9303c1e1a918922158a521a5881ab4 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:12:10 +0530 Subject: [PATCH 12/15] add native benchmark for c and js --- .../ellipk/benchmark/benchmark.native.js | 58 +++++++ .../ellipk/benchmark/cpp/native/Makefile | 146 ++++++++++++++++++ .../ellipk/benchmark/cpp/native/benchmark.c | 136 ++++++++++++++++ 3 files changed, 340 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/benchmark.native.js create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/Makefile create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/benchmark.c diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/benchmark.native.js b/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/benchmark.native.js new file mode 100644 index 000000000000..6316b6f8c6e9 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/benchmark.native.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var tryRequire = require( '@stdlib/utils/try-require' ); +var pkg = require( './../package.json' ).name; + + +// VARIABLES // + +var ellipk = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( ellipk instanceof Error ) +}; + + +// MAIN // + +bench( pkg+'::native', opts, function benchmark( b ) { + var y; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + y = ellipk( randu() ); + if ( isnan( y ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( y ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/Makefile b/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/Makefile new file mode 100644 index 000000000000..d6b58c7f5d3e --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/Makefile @@ -0,0 +1,146 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2022 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/ellipk/benchmark/cpp/native/benchmark.c b/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/benchmark.c new file mode 100644 index 000000000000..b92284d35837 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/benchmark/cpp/native/benchmark.c @@ -0,0 +1,136 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** +* Benchmark `ellipk`. +*/ +#include "stdlib/math/base/special/ellipk.h" +#include +#include +#include +#include +#include + +#define NAME "ellipk" +#define ITERATIONS 1000000 +#define REPEATS 3 + +/** +* Prints the TAP version. +*/ +void print_version() { + printf( "TAP version 13\n" ); +} + +/** +* Prints the TAP summary. +* +* @param total total number of tests +* @param passing total number of passing tests +*/ +void print_summary( int total, int passing ) { + printf( "#\n" ); + printf( "1..%d\n", total ); // TAP plan + printf( "# total %d\n", total ); + printf( "# pass %d\n", passing ); + printf( "#\n" ); + printf( "# ok\n" ); +} + +/** +* Prints benchmarks results. +* +* @param elapsed elapsed time in seconds +*/ +void print_results( double elapsed ) { + double rate = (double)ITERATIONS / elapsed; + printf( " ---\n" ); + printf( " iterations: %d\n", ITERATIONS ); + printf( " elapsed: %0.9f\n", elapsed ); + printf( " rate: %0.9f\n", rate ); + printf( " ...\n" ); +} + +/** +* Returns a clock time. +* +* @return clock time +*/ +double tic() { + struct timeval now; + gettimeofday( &now, NULL ); + return (double)now.tv_sec + (double)now.tv_usec/1.0e6; +} + +/** +* Generates a random number on the interval [0,1]. +* +* @return random number +*/ +double rand_double() { + int r = rand(); + return (double)r / ( (double)RAND_MAX + 1.0 ); +} + +/** +* Runs a benchmark. +* +* @return elapsed time in seconds +*/ +double benchmark() { + double elapsed; + double x; + double y; + double t; + int i; + + t = tic(); + for ( i = 0; i < ITERATIONS; i++ ) { + x = rand_double(); + y = stdlib_base_ellipk( x ); + if ( y != y ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( y != y ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + +/** +* Main execution sequence. +*/ +int main( void ) { + double elapsed; + int i; + + // Use the current time to seed the random number generator: + srand( time( NULL ) ); + + print_version(); + for ( i = 0; i < REPEATS; i++ ) { + printf( "# c::native::%s\n", NAME ); + elapsed = benchmark(); + print_results( elapsed ); + printf( "ok %d benchmark finished\n", i+1 ); + } + print_summary( REPEATS, REPEATS ); +} From 4bac97fb14e3d14124c6c56c4d003f563c3cfbbf Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sat, 24 Dec 2022 11:13:47 +0530 Subject: [PATCH 13/15] Add native tests --- .../base/special/ellipk/test/test.native.js | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 lib/node_modules/@stdlib/math/base/special/ellipk/test/test.native.js diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/ellipk/test/test.native.js new file mode 100644 index 000000000000..0035308d6948 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/test/test.native.js @@ -0,0 +1,178 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2022 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF 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 tryRequire = require( '@stdlib/utils/try-require' ); +var EPS = require( '@stdlib/constants/float64/eps' ); +var abs = require( '@stdlib/math/base/special/abs' ); + + +// FIXTURES // + +var mediumPositive = require( './fixtures/cpp/medium_positive.json' ); +var closeToUnity = require( './fixtures/cpp/close_to_unity.json' ); +var mediumNegative = require( './fixtures/cpp/medium_negative.json' ); +var largeNegative = require( './fixtures/cpp/large_negative.json' ); + + +// VARIABLES // + +var ellipk = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( ellipk instanceof Error ) +}; + + +// TESTS // + +tape( 'main export is a function', opts, function test( t ) { + t.ok( true, __filename ); + t.equal( typeof ellipk, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function evaluates the complete elliptic integral of the first kind (medium positive values)', opts, function test( t ) { + var expected; + var delta; + var tol; + var x; + var y; + var i; + + expected = mediumPositive.expected; + x = mediumPositive.x; + for ( i = 0; i < x.length; i++ ) { + y = ellipk( x[i] ); + if ( y === expected[i] ) { + t.equal( y, expected[i], 'x: '+x[i]+', y: '+y+', expected: '+expected[i] ); + } else { + delta = abs( y - expected[i] ); + tol = 25.0 * EPS * abs( expected[i] ); + t.equal( delta <= tol, true, 'within tolerance. x: '+x[i]+'. y: '+y+'. E: '+expected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function evaluates the complete elliptic integral of the first kind (values close to positive unity)', opts, function test( t ) { + var expected; + var delta; + var tol; + var x; + var y; + var i; + + expected = closeToUnity.expected; + x = closeToUnity.x; + for ( i = 0; i < x.length; i++ ) { + y = ellipk( x[i] ); + if ( y === expected[i] ) { + t.equal( y, expected[i], 'x: '+x[i]+', y: '+y+', expected: '+expected[i] ); + } else { + delta = abs( y - expected[i] ); + tol = 8000.0 * EPS * abs( expected[i] ); + t.equal( delta <= tol, true, 'within tolerance. x: '+x[i]+'. y: '+y+'. E: '+expected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function evaluates the complete elliptic integral of the first kind (medium negative values)', opts, function test( t ) { + var expected; + var delta; + var tol; + var x; + var y; + var i; + + expected = mediumNegative.expected; + x = mediumNegative.x; + for ( i = 0; i < x.length; i++ ) { + y = ellipk( x[i] ); + if ( y === expected[i] ) { + t.equal( y, expected[i], 'x: '+x[i]+', y: '+y+', expected: '+expected[i] ); + } else { + delta = abs( y - expected[i] ); + tol = 1.5 * EPS * abs( expected[i] ); + t.equal( delta <= tol, true, 'within tolerance. x: '+x[i]+'. y: '+y+'. E: '+expected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function evaluates the complete elliptic integral of the first kind (large negative values)', opts, function test( t ) { + var expected; + var delta; + var tol; + var x; + var y; + var i; + + expected = largeNegative.expected; + x = largeNegative.x; + for ( i = 0; i < x.length; i++ ) { + y = ellipk( x[i] ); + if ( y === expected[i] ) { + t.equal( y, expected[i], 'x: '+x[i]+', y: '+y+', expected: '+expected[i] ); + } else { + delta = abs( y - expected[i] ); + tol = 1e9 * EPS * abs( expected[i] ); + t.equal( delta <= tol, true, 'within tolerance. x: '+x[i]+'. y: '+y+'. E: '+expected[i]+'. Δ: '+delta+'. tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'the function returns `NaN` if provided values larger than `1.0`', opts, function test( t ) { + var v = ellipk( 1.01 ); + t.equal( isnan( v ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns `+infinity` if provided `1.0`', opts, function test( t ) { + var v = ellipk( 1.0 ); + t.equal( v, PINF, 'return expected value' ); + t.end(); +}); + +tape( 'the function returns `NaN` if provided `+infinity`', opts, function test( t ) { + var v = ellipk( PINF ); + t.equal( isnan( v ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns `NaN` if provided `-infinity`', opts, function test( t ) { + var v = ellipk( NINF ); + t.equal( isnan( v ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns `π/2` if provided `0`', opts, function test( t ) { + var v = ellipk( 0 ); + t.equal( v, HALF_PI, 'returns expected value' ); + t.end(); +}); From ebc5696eb267de2a225271076169abac4bd61d33 Mon Sep 17 00:00:00 2001 From: Pranav <85227306+Pranavchiku@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:15:51 +0530 Subject: [PATCH 14/15] Update lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js --- lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js b/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js index 8d5a55dea450..18257915e529 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/lib/native.js @@ -29,7 +29,6 @@ var addon = require( './../src/addon.node' ); * Computes the complete elliptic integral of the first kind. * * @private - * @param {number} m - input value * @returns {number} evaluated elliptic integral * From 1726fccde19050b47ba6c11a1b4cf874f6bd2f90 Mon Sep 17 00:00:00 2001 From: Athan Date: Mon, 13 Feb 2023 20:09:20 -0800 Subject: [PATCH 15/15] Apply suggestions from code review --- lib/node_modules/@stdlib/math/base/special/ellipk/README.md | 2 +- .../@stdlib/math/base/special/ellipk/examples/c/example.c | 2 +- lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/README.md b/lib/node_modules/@stdlib/math/base/special/ellipk/README.md index a0e38f5362c5..39a6d7bdb0ad 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/README.md +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/README.md @@ -185,7 +185,7 @@ int main() { int i; for ( i = 0; i < 100; i++ ) { - m = -1.0 + ( (double)rand() / (double)RAND_MAX ) * 2.0; + m = -1.0 + ( ( (double)rand() / (double)RAND_MAX ) * 2.0 ); v = stdlib_base_ellipk( m ); printf( "ellipk(%lf) = %lf\n", m, v ); } diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c b/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c index 8ed584b54a02..01d0063739c8 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/examples/c/example.c @@ -26,7 +26,7 @@ int main() { int i; for ( i = 0; i < 100; i++ ) { - m = -1.0 + ( (double)rand() / (double)RAND_MAX ) * 2.0; + m = -1.0 + ( ( (double)rand() / (double)RAND_MAX ) * 2.0 ); v = stdlib_base_ellipk( m ); printf( "ellipk(%lf) = %lf\n", m, v ); } diff --git a/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c b/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c index 9ccad444bbe7..dfa4efc4dfe0 100644 --- a/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/ellipk/src/main.c @@ -311,7 +311,7 @@ static double poly_p12( const double x ) { * // returns ~1.854 */ double stdlib_base_ellipk( const double m ) { - int32_t FLG = 0; + int8_t FLG = 0; double kdm; double td; double qd; @@ -358,7 +358,7 @@ double stdlib_base_ellipk( const double m ) { kdm = poly_p12( td - 0.05 ); t = -stdlib_base_ln( qd ) * ( kdm * ONE_DIV_PI ); } - if ( FLG == 1) { + if ( FLG == 1 ) { // Complete the transformation mentioned above for m < 0: return t / stdlib_base_sqrt( 1.0 - m ); }