From 9e46deda4c3f3362fbf95b8d70cc952ab6a8baa1 Mon Sep 17 00:00:00 2001 From: Neeraj Pathak Date: Wed, 28 Jan 2026 16:52:22 +0530 Subject: [PATCH 1/3] feat: add initial macro setup --- .../math/base/napi/quaternary/README.md | 103 +++++++ .../stdlib/math/base/napi/quaternary.h | 1 + .../stdlib/math/base/napi/quaternary/zzzz_z.h | 104 +++++++ .../math/base/napi/quaternary/manifest.json | 8 +- .../math/base/napi/quaternary/src/zzzz_z.c | 281 ++++++++++++++++++ 5 files changed, 495 insertions(+), 2 deletions(-) create mode 100644 lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h create mode 100644 lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md b/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md index a2acc38e124f..e7ed1f8df2c2 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md @@ -286,6 +286,109 @@ The function accepts the following arguments: void stdlib_math_base_napi_ffff_f( napi_env env, napi_callback_info info, float (*fcn)( float, float, float, float ) ); ``` +#### STDLIB_MATH_BASE_NAPI_MODULE_ZZZZ_Z( fcn ) + +Macro for registering a Node-API module exporting an interface for invoking a quaternary function accepting and returning double-precision complex floating-point numbers. + +```c +#include "stdlib/complex/float64/ctor.h" +#include "stdlib/complex/float64/reim.h" + +static stdlib_complex128_t add( const stdlib_complex128_t w, const stdlib_complex128_t x, const stdlib_complex128_t y, const stdlib_complex128_t z ) { + double wre; + double wim; + double xre; + double xim; + double yre; + double yim; + double zre; + double zim; + double re; + double im; + + stdlib_complex128_reim( w, &xre, &wim ); + stdlib_complex128_reim( x, &yre, &xim ); + stdlib_complex128_reim( y, &zre, &yim ); + stdlib_complex128_reim( z, &zre, &zim ); + + re = wre + xre + yre + zre; + im = wim + xim + yim + zim; + + return stdlib_complex128( re, im ); +} + +// ... + +// Register a Node-API module: +STDLIB_MATH_BASE_NAPI_MODULE_ZZZZ_Z( add ); +``` + +The macro expects the following arguments: + +- **fcn**: `stdlib_complex128_t (*fcn)( stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t )` quaternary function. + +When used, this macro should be used **instead of** `NAPI_MODULE`. The macro includes `NAPI_MODULE`, thus ensuring Node-API module registration. + +#### stdlib_math_base_napi_zzzz_z( env, info, fcn ) + +Invokes a quaternary function accepting and returning double-precision complex floating-point numbers. + +```c +#include "stdlib/complex/float64/ctor.h" +#include "stdlib/complex/float64/reim.h" +#include + +// ... + +static stdlib_complex128_t add( const stdlib_complex128_t w, const stdlib_complex128_t x, const stdlib_complex128_t y, const stdlib_complex128_t z ) { + double wre; + double wim; + double xre; + double xim; + double yre; + double yim; + double zre; + double zim; + double re; + double im; + + stdlib_complex128_reim( w, &xre, &wim ); + stdlib_complex128_reim( x, &yre, &xim ); + stdlib_complex128_reim( y, &zre, &yim ); + stdlib_complex128_reim( z, &zre, &zim ); + + re = wre + xre + yre + zre; + im = wim + xim + yim + zim; + + return stdlib_complex128( re, im ); +} + +// ... + +/** +* Receives JavaScript callback invocation data. +* +* @param env environment under which the function is invoked +* @param info callback data +* @return Node-API value +*/ +napi_value addon( napi_env env, napi_callback_info info ) { + return stdlib_math_base_napi_zzzz_z( env, info, add ); +} + +// ... +``` + +The function accepts the following arguments: + +- **env**: `[in] napi_env` environment under which the function is invoked. +- **info**: `[in] napi_callback_info` callback data. +- **fcn**: `[in] stdlib_complex128_t (*fcn)( stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t )` quaternary function. + +```c +void stdlib_math_base_napi_zzzz_z( napi_env env, napi_callback_info info, stdlib_complex128_t (*fcn)( stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t ) ); +``` + diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h index 921a9c35f2fb..3bce886cc661 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h @@ -23,5 +23,6 @@ #include "stdlib/math/base/napi/quaternary/dddd_d.h" #include "stdlib/math/base/napi/quaternary/diii_d.h" #include "stdlib/math/base/napi/quaternary/ffff_f.h" +#include "stdlib/math/base/napi/quaternary/zzzz_z.h" #endif // !STDLIB_MATH_BASE_NAPI_QUATERNARY_H diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h new file mode 100644 index 000000000000..d62d6de64315 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h @@ -0,0 +1,104 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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_NAPI_QUATERNARY_ZZZZ_Z_H +#define STDLIB_MATH_BASE_NAPI_QUATERNARY_ZZZZ_Z_H + +#include "stdlib/complex/float64/ctor.h" +#include +#include + +/** +* Macro for registering a Node-API module exporting an interface invoking a quaternary function accepting and returning double-precision complex floating-point numbers. +* +* @param fcn quaternary function +* +* @example +* #include "stdlib/complex/float64/ctor.h" +* #include "stdlib/complex/float64/reim.h" +* +* static stdlib_complex128_t add( const stdlib_complex128_t w, const stdlib_complex128_t x, const stdlib_complex128_t y, const stdlib_complex128_t z ) { +* double wre; +* double wim; +* double xre; +* double xim; +* double yre; +* double yim; +* double zre; +* double zim; +* double re; +* double im; +* +* stdlib_complex128_reim( w, &xre, &wim ); +* stdlib_complex128_reim( x, &xre, &xim ); +* stdlib_complex128_reim( y, &yre, &yim ); +* stdlib_complex128_reim( z, &zre, &zim ); +* +* re = wre + xre + yre + zre; +* im = wim + xim + yim + zim; +* +* return stdlib_complex128( re, im ); +* } +* +* // ... +* +* // Register a Node-API module: +* STDLIB_MATH_BASE_NAPI_MODULE_ZZZZ_Z( add ); +*/ +#define STDLIB_MATH_BASE_NAPI_MODULE_ZZZZ_Z( fcn ) \ + static napi_value stdlib_math_base_napi_zzzz_z_wrapper( \ + napi_env env, \ + napi_callback_info info \ + ) { \ + return stdlib_math_base_napi_zzzz_z( env, info, fcn ); \ + }; \ + static napi_value stdlib_math_base_napi_zzzz_z_init( \ + napi_env env, \ + napi_value exports \ + ) { \ + napi_value f; \ + napi_status status = napi_create_function( \ + env, \ + "exports", \ + NAPI_AUTO_LENGTH, \ + stdlib_math_base_napi_zzzz_z_wrapper, \ + NULL, \ + &f \ + ); \ + assert( status == napi_ok ); \ + return f; \ + }; \ + NAPI_MODULE( NODE_GYP_MODULE_NAME, stdlib_math_base_napi_zzzz_z_init ) + +/* +* 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 + +/** +* Invokes a quaternary function accepting and returning double-precision complex floating-point numbers. +*/ +napi_value stdlib_math_base_napi_zzzz_z( napi_env env, napi_callback_info info, stdlib_complex128_t (*fcn)( stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t ) ); + +#ifdef __cplusplus +} +#endif + +#endif // !STDLIB_MATH_BASE_NAPI_QUATERNARY_ZZZZ_Z_H diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json b/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json index f343df6aa8dc..4fd0db80e085 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json @@ -27,14 +27,18 @@ "src": [ "./src/dddd_d.c", "./src/diii_d.c", - "./src/ffff_f.c" + "./src/ffff_f.c", + "./src/zzzz_z.c" ], "include": [ "./include" ], "libraries": [], "libpath": [], - "dependencies": [] + "dependencies": [ + "@stdlib/complex/float64/ctor", + "@stdlib/complex/float64/reim" + ] } ] } diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c b/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c new file mode 100644 index 000000000000..efc0b6627419 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c @@ -0,0 +1,281 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT 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/napi/quaternary/zzzz_z.h" +#include "stdlib/complex/float64/ctor.h" +#include "stdlib/complex/float64/reim.h" +#include +#include + +/** +* Invokes a quaternary function accepting and returning double-precision complex floating-point numbers. +* +* ## Notes +* +* - This function expects that the callback `info` argument provides access to the following JavaScript arguments: +* +* - `w`: input value. +* - `x`: input value. +* - `y`: input value. +* - `z`: input value. +* +* @param env environment under which the function is invoked +* @param info callback data +* @param fcn quaternary function +* @return function return value as a Node-API complex-like object +*/ +napi_value stdlib_math_base_napi_zzzz_z( napi_env env, napi_callback_info info, stdlib_complex128_t (*fcn)( stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t, stdlib_complex128_t ) ) { + napi_status status; + + size_t argc = 4; + napi_value argv[ 4 ]; + status = napi_get_cb_info( env, info, &argc, argv, NULL, NULL ); + assert( status == napi_ok ); + + if ( argc < 4 ) { + status = napi_throw_error( env, NULL, "invalid invocation. Must provide four complex numbers." ); + assert( status == napi_ok ); + return NULL; + } + + bool hprop; + status = napi_has_named_property( env, argv[ 0 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value wre; + status = napi_get_named_property( env, argv[ 0 ], "re", &wre ); + assert( status == napi_ok ); + + napi_valuetype wretype; + status = napi_typeof( env, wre, &wretype ); + assert( status == napi_ok ); + if ( wretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 0 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value wim; + status = napi_get_named_property( env, argv[ 0 ], "im", &wim ); + assert( status == napi_ok ); + + napi_valuetype wimtype; + status = napi_typeof( env, wim, &wimtype ); + assert( status == napi_ok ); + if ( wimtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 1 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value xre; + status = napi_get_named_property( env, argv[ 1 ], "re", &xre ); + assert( status == napi_ok ); + + napi_valuetype xretype; + status = napi_typeof( env, xre, &xretype ); + assert( status == napi_ok ); + if ( xretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 1 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value xim; + status = napi_get_named_property( env, argv[ 1 ], "im", &xim ); + assert( status == napi_ok ); + + napi_valuetype ximtype; + status = napi_typeof( env, xim, &ximtype ); + assert( status == napi_ok ); + if ( ximtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 2 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value yre; + status = napi_get_named_property( env, argv[ 2 ], "re", &yre ); + assert( status == napi_ok ); + + napi_valuetype yretype; + status = napi_typeof( env, yre, &yretype ); + assert( status == napi_ok ); + if ( yretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 2 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value yim; + status = napi_get_named_property( env, argv[ 2 ], "im", &yim ); + assert( status == napi_ok ); + + napi_valuetype yimtype; + status = napi_typeof( env, yim, &yimtype ); + assert( status == napi_ok ); + if ( yimtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 3 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Fourth argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value zre; + status = napi_get_named_property( env, argv[ 3 ], "re", &zre ); + assert( status == napi_ok ); + + napi_valuetype zretype; + status = napi_typeof( env, zre, &zretype ); + assert( status == napi_ok ); + if ( zretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Fourth argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 3 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Fourth argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value zim; + status = napi_get_named_property( env, argv[ 3 ], "im", &zim ); + assert( status == napi_ok ); + + napi_valuetype zimtype; + status = napi_typeof( env, zim, &zimtype ); + assert( status == napi_ok ); + if ( zimtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Fourth argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + double re0; + status = napi_get_value_double( env, wre, &re0 ); + assert( status == napi_ok ); + + double im0; + status = napi_get_value_double( env, wim, &im0 ); + assert( status == napi_ok ); + + double re1; + status = napi_get_value_double( env, xre, &re1 ); + assert( status == napi_ok ); + + double im1; + status = napi_get_value_double( env, xim, &im1 ); + assert( status == napi_ok ); + + double re2; + status = napi_get_value_double( env, yre, &re2 ); + assert( status == napi_ok ); + + double im2; + status = napi_get_value_double( env, yim, &im2 ); + assert( status == napi_ok ); + + double re3; + status = napi_get_value_double( env, zre, &re3 ); + assert( status == napi_ok ); + + double im3; + status = napi_get_value_double( env, zim, &im3 ); + assert( status == napi_ok ); + + stdlib_complex128_t v = fcn( stdlib_complex128( re0, im0 ), stdlib_complex128( re1, im1 ), stdlib_complex128( re2, im2 ), stdlib_complex128( re3, im3 ) ); + double re; + double im; + stdlib_complex128_reim( v, &re, &im ); + + napi_value obj; + status = napi_create_object( env, &obj ); + assert( status == napi_ok ); + + napi_value vre; + status = napi_create_double( env, re, &vre ); + assert( status == napi_ok ); + + status = napi_set_named_property( env, obj, "re", vre ); + assert( status == napi_ok ); + + napi_value vim; + status = napi_create_double( env, im, &vim ); + assert( status == napi_ok ); + + status = napi_set_named_property( env, obj, "im", vim ); + assert( status == napi_ok ); + + return obj; +} From c373b03ef9bf3bae6f36ca25bede7b2c794223c6 Mon Sep 17 00:00:00 2001 From: Neeraj Pathak Date: Wed, 28 Jan 2026 16:58:57 +0530 Subject: [PATCH 2/3] chore: clean up --- .../@stdlib/math/base/napi/quaternary/src/zzzz_z.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c b/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c index efc0b6627419..c20fe2e40098 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/src/zzzz_z.c @@ -180,7 +180,7 @@ napi_value stdlib_math_base_napi_zzzz_z( napi_env env, napi_callback_info info, return NULL; } - status = napi_has_named_property( env, argv[ 3 ], "re", &hprop ); + status = napi_has_named_property( env, argv[ 3 ], "re", &hprop ); assert( status == napi_ok ); if ( !hprop ) { status = napi_throw_type_error( env, NULL, "invalid argument. Fourth argument must have a real component." ); @@ -246,7 +246,7 @@ napi_value stdlib_math_base_napi_zzzz_z( napi_env env, napi_callback_info info, status = napi_get_value_double( env, yim, &im2 ); assert( status == napi_ok ); - double re3; + double re3; status = napi_get_value_double( env, zre, &re3 ); assert( status == napi_ok ); From 7af80b7b62a261fb75a75a8a09ea47b441522dad Mon Sep 17 00:00:00 2001 From: Neeraj Pathak Date: Wed, 28 Jan 2026 17:04:51 +0530 Subject: [PATCH 3/3] chore: update markdown --- .../@stdlib/math/base/napi/quaternary/README.md | 6 +++--- .../include/stdlib/math/base/napi/quaternary/zzzz_z.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md b/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md index e7ed1f8df2c2..bc0a6bf1b884 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md @@ -352,9 +352,9 @@ static stdlib_complex128_t add( const stdlib_complex128_t w, const stdlib_comple double re; double im; - stdlib_complex128_reim( w, &xre, &wim ); - stdlib_complex128_reim( x, &yre, &xim ); - stdlib_complex128_reim( y, &zre, &yim ); + stdlib_complex128_reim( w, &wre, &wim ); + stdlib_complex128_reim( x, &xre, &xim ); + stdlib_complex128_reim( y, &yre, &yim ); stdlib_complex128_reim( z, &zre, &zim ); re = wre + xre + yre + zre; diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h index d62d6de64315..5d331e9dd29b 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/zzzz_z.h @@ -44,7 +44,7 @@ * double re; * double im; * -* stdlib_complex128_reim( w, &xre, &wim ); +* stdlib_complex128_reim( w, &wre, &wim ); * stdlib_complex128_reim( x, &xre, &xim ); * stdlib_complex128_reim( y, &yre, &yim ); * stdlib_complex128_reim( z, &zre, &zim );