From daa14d97207971e9463c31267f7820086cc67454 Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Wed, 26 Mar 2025 00:42:47 -0700 Subject: [PATCH 1/3] chore: improve implementation and tests --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: passed - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../math/base/special/cabs/lib/main.js | 10 ++++- .../math/base/special/cabs/manifest.json | 15 ++++++-- .../@stdlib/math/base/special/cabs/src/main.c | 10 +++++ .../math/base/special/cabs/test/test.js | 38 +++++++++++++++++-- .../base/special/cabs/test/test.native.js | 38 +++++++++++++++++-- 5 files changed, 101 insertions(+), 10 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js b/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js index 79503c4e63a2..a5a6d7aec109 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js @@ -21,6 +21,9 @@ // MODULES // var hypot = require( '@stdlib/math/base/special/hypot' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var isInfinite = require( '@stdlib/math/base/assert/is-infinite' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); var real = require( '@stdlib/complex/float64/real' ); var imag = require( '@stdlib/complex/float64/imag' ); @@ -40,7 +43,12 @@ var imag = require( '@stdlib/complex/float64/imag' ); * // returns ~5.83 */ function cabs( z ) { - // TODO: consider whether to use C99 rules for special cases involving infinities and nans (see https://github.com/python/cpython/blob/f4c03484da59049eb62a9bf7777b963e2267d187/Objects/complexobject.c#L191) + if ( isnan( real( z ) ) || isnan( imag( z ) ) ) { + return NaN; + } + if ( isInfinite( real( z ) ) || isInfinite( imag( z ) ) ) { + return PINF; + } return hypot( real( z ), imag( z ) ); } diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json b/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json index e031be9bba9a..d4ef6847c680 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json +++ b/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json @@ -39,7 +39,10 @@ "@stdlib/math/base/napi/unary", "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim", - "@stdlib/math/base/special/hypot" + "@stdlib/math/base/special/hypot", + "@stdlib/math/base/assert/is-nan", + "@stdlib/math/base/assert/is-infinite", + "@stdlib/constants/float64/pinf" ] }, { @@ -55,7 +58,10 @@ "dependencies": [ "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim", - "@stdlib/math/base/special/hypot" + "@stdlib/math/base/special/hypot", + "@stdlib/math/base/assert/is-nan", + "@stdlib/math/base/assert/is-infinite", + "@stdlib/constants/float64/pinf" ] }, { @@ -71,7 +77,10 @@ "dependencies": [ "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim", - "@stdlib/math/base/special/hypot" + "@stdlib/math/base/special/hypot", + "@stdlib/math/base/assert/is-nan", + "@stdlib/math/base/assert/is-infinite", + "@stdlib/constants/float64/pinf" ] } ] diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c b/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c index 1ebbb4080d23..4e8dcb9ac7ae 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c @@ -18,6 +18,9 @@ #include "stdlib/math/base/special/cabs.h" #include "stdlib/math/base/special/hypot.h" +#include "stdlib/math/base/assert/is_nan.h" +#include "stdlib/math/base/assert/is_infinite.h" +#include "stdlib/constants/float64/pinf.h" #include "stdlib/complex/float64/ctor.h" #include "stdlib/complex/float64/reim.h" @@ -39,5 +42,12 @@ double stdlib_base_cabs( const stdlib_complex128_t z ) { double re; double im; stdlib_complex128_reim( z, &re, &im ); + + if ( stdlib_base_is_nan( re ) || stdlib_base_is_nan( im ) ) { + return 0.0 / 0.0; // NaN + } + if ( stdlib_base_is_infinite( re ) || stdlib_base_is_infinite( im ) ) { + return STDLIB_CONSTANT_FLOAT64_PINF; + } return stdlib_base_hypot( re, im ); } diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js index 801b6e32937f..85f868a922a6 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js +++ b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js @@ -23,6 +23,8 @@ var tape = require( 'tape' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var EPS = require( '@stdlib/constants/float64/eps' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); var abs = require( '@stdlib/math/base/special/abs' ); var Complex128 = require( '@stdlib/complex/float64/ctor' ); var cabs = require( './../lib' ); @@ -71,13 +73,43 @@ tape( 'if either the real or imaginary component is `NaN`, the function returns var v; v = cabs( new Complex128( NaN, 3.0 ) ); - t.strictEqual( isnan( v ), true, 'returns NaN' ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); v = cabs( new Complex128( 5.0, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns NaN' ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); v = cabs( new Complex128( NaN, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns NaN' ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'if either the real or imaginary component is `+Infinity`, the function returns `+Infinity`', function test( t ) { + var v; + + v = cabs( new Complex128( PINF, 3.0 ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( 5.0, PINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( PINF, PINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + t.end(); +}); + +tape( 'if either the real or imaginary component is `-Infinity`, the function returns `+Infinity`', function test( t ) { + var v; + + v = cabs( new Complex128( NINF, 3.0 ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( 5.0, NINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( NINF, NINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); t.end(); }); diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js index 4000a697045d..45f9ced7e8d3 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js +++ b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js @@ -24,6 +24,8 @@ var resolve = require( 'path' ).resolve; var tape = require( 'tape' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var EPS = require( '@stdlib/constants/float64/eps' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); var abs = require( '@stdlib/math/base/special/abs' ); var Complex128 = require( '@stdlib/complex/float64/ctor' ); var tryRequire = require( '@stdlib/utils/try-require' ); @@ -80,13 +82,43 @@ tape( 'if either the real or imaginary component is `NaN`, the function returns var v; v = cabs( new Complex128( NaN, 3.0 ) ); - t.strictEqual( isnan( v ), true, 'returns NaN' ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); v = cabs( new Complex128( 5.0, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns NaN' ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); v = cabs( new Complex128( NaN, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns NaN' ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'if either the real or imaginary component is `+Infinity`, the function returns `+Infinity`', opts, function test( t ) { + var v; + + v = cabs( new Complex128( PINF, 3.0 ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( 5.0, PINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( PINF, PINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + t.end(); +}); + +tape( 'if either the real or imaginary component is `-Infinity`, the function returns `+Infinity`', opts, function test( t ) { + var v; + + v = cabs( new Complex128( NINF, 3.0 ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( 5.0, NINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( NINF, NINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); t.end(); }); From ae3c95d15e66f039ebe03d21909f9ac09ad6f5c4 Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Wed, 2 Apr 2025 01:44:37 -0700 Subject: [PATCH 2/3] fix: update implementation to follow the C99 standard --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: passed - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../math/base/special/cabs/lib/main.js | 9 ---- .../math/base/special/cabs/manifest.json | 15 ++---- .../@stdlib/math/base/special/cabs/src/main.c | 9 ---- .../math/base/special/cabs/test/test.js | 46 ++++++++++++------- .../base/special/cabs/test/test.native.js | 46 ++++++++++++------- 5 files changed, 61 insertions(+), 64 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js b/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js index a5a6d7aec109..70e4872deb88 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/cabs/lib/main.js @@ -21,9 +21,6 @@ // MODULES // var hypot = require( '@stdlib/math/base/special/hypot' ); -var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var isInfinite = require( '@stdlib/math/base/assert/is-infinite' ); -var PINF = require( '@stdlib/constants/float64/pinf' ); var real = require( '@stdlib/complex/float64/real' ); var imag = require( '@stdlib/complex/float64/imag' ); @@ -43,12 +40,6 @@ var imag = require( '@stdlib/complex/float64/imag' ); * // returns ~5.83 */ function cabs( z ) { - if ( isnan( real( z ) ) || isnan( imag( z ) ) ) { - return NaN; - } - if ( isInfinite( real( z ) ) || isInfinite( imag( z ) ) ) { - return PINF; - } return hypot( real( z ), imag( z ) ); } diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json b/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json index d4ef6847c680..e031be9bba9a 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json +++ b/lib/node_modules/@stdlib/math/base/special/cabs/manifest.json @@ -39,10 +39,7 @@ "@stdlib/math/base/napi/unary", "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim", - "@stdlib/math/base/special/hypot", - "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/assert/is-infinite", - "@stdlib/constants/float64/pinf" + "@stdlib/math/base/special/hypot" ] }, { @@ -58,10 +55,7 @@ "dependencies": [ "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim", - "@stdlib/math/base/special/hypot", - "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/assert/is-infinite", - "@stdlib/constants/float64/pinf" + "@stdlib/math/base/special/hypot" ] }, { @@ -77,10 +71,7 @@ "dependencies": [ "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim", - "@stdlib/math/base/special/hypot", - "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/assert/is-infinite", - "@stdlib/constants/float64/pinf" + "@stdlib/math/base/special/hypot" ] } ] diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c b/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c index 4e8dcb9ac7ae..3308807ba731 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c @@ -18,9 +18,6 @@ #include "stdlib/math/base/special/cabs.h" #include "stdlib/math/base/special/hypot.h" -#include "stdlib/math/base/assert/is_nan.h" -#include "stdlib/math/base/assert/is_infinite.h" -#include "stdlib/constants/float64/pinf.h" #include "stdlib/complex/float64/ctor.h" #include "stdlib/complex/float64/reim.h" @@ -43,11 +40,5 @@ double stdlib_base_cabs( const stdlib_complex128_t z ) { double im; stdlib_complex128_reim( z, &re, &im ); - if ( stdlib_base_is_nan( re ) || stdlib_base_is_nan( im ) ) { - return 0.0 / 0.0; // NaN - } - if ( stdlib_base_is_infinite( re ) || stdlib_base_is_infinite( im ) ) { - return STDLIB_CONSTANT_FLOAT64_PINF; - } return stdlib_base_hypot( re, im ); } diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js index 85f868a922a6..6f21f97be530 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js +++ b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.js @@ -69,22 +69,7 @@ tape( 'the function computes the absolute value of a complex number', function t t.end(); }); -tape( 'if either the real or imaginary component is `NaN`, the function returns `NaN`', function test( t ) { - var v; - - v = cabs( new Complex128( NaN, 3.0 ) ); - t.strictEqual( isnan( v ), true, 'returns expected value' ); - - v = cabs( new Complex128( 5.0, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns expected value' ); - - v = cabs( new Complex128( NaN, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns expected value' ); - - t.end(); -}); - -tape( 'if either the real or imaginary component is `+Infinity`, the function returns `+Infinity`', function test( t ) { +tape( 'if either the real or imaginary component is `+infinity`, the function returns `+infinity`', function test( t ) { var v; v = cabs( new Complex128( PINF, 3.0 ) ); @@ -96,10 +81,16 @@ tape( 'if either the real or imaginary component is `+Infinity`, the function re v = cabs( new Complex128( PINF, PINF ) ); t.strictEqual( v, PINF, 'returns expected value' ); + v = cabs( new Complex128( NaN, PINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( PINF, NaN ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + t.end(); }); -tape( 'if either the real or imaginary component is `-Infinity`, the function returns `+Infinity`', function test( t ) { +tape( 'if either the real or imaginary component is `-infinity`, the function returns `+infinity`', function test( t ) { var v; v = cabs( new Complex128( NINF, 3.0 ) ); @@ -111,5 +102,26 @@ tape( 'if either the real or imaginary component is `-Infinity`, the function re v = cabs( new Complex128( NINF, NINF ) ); t.strictEqual( v, PINF, 'returns expected value' ); + v = cabs( new Complex128( NaN, NINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( NINF, NaN ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + t.end(); +}); + +tape( 'if either the real or imaginary component is `NaN` but not `+-infinity`, the function returns `NaN`', function test( t ) { + var v; + + v = cabs( new Complex128( NaN, 3.0 ) ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + + v = cabs( new Complex128( 5.0, NaN ) ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + + v = cabs( new Complex128( NaN, NaN ) ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + t.end(); }); diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js index 45f9ced7e8d3..959ba9d3a207 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js +++ b/lib/node_modules/@stdlib/math/base/special/cabs/test/test.native.js @@ -78,22 +78,7 @@ tape( 'the function computes the absolute value of a complex number', opts, func t.end(); }); -tape( 'if either the real or imaginary component is `NaN`, the function returns `NaN`', opts, function test( t ) { - var v; - - v = cabs( new Complex128( NaN, 3.0 ) ); - t.strictEqual( isnan( v ), true, 'returns expected value' ); - - v = cabs( new Complex128( 5.0, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns expected value' ); - - v = cabs( new Complex128( NaN, NaN ) ); - t.strictEqual( isnan( v ), true, 'returns expected value' ); - - t.end(); -}); - -tape( 'if either the real or imaginary component is `+Infinity`, the function returns `+Infinity`', opts, function test( t ) { +tape( 'if either the real or imaginary component is `+infinity`, the function returns `+infinity`', opts, function test( t ) { var v; v = cabs( new Complex128( PINF, 3.0 ) ); @@ -105,10 +90,16 @@ tape( 'if either the real or imaginary component is `+Infinity`, the function re v = cabs( new Complex128( PINF, PINF ) ); t.strictEqual( v, PINF, 'returns expected value' ); + v = cabs( new Complex128( NaN, PINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( PINF, NaN ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + t.end(); }); -tape( 'if either the real or imaginary component is `-Infinity`, the function returns `+Infinity`', opts, function test( t ) { +tape( 'if either the real or imaginary component is `-infinity`, the function returns `+infinity`', opts, function test( t ) { var v; v = cabs( new Complex128( NINF, 3.0 ) ); @@ -120,5 +111,26 @@ tape( 'if either the real or imaginary component is `-Infinity`, the function re v = cabs( new Complex128( NINF, NINF ) ); t.strictEqual( v, PINF, 'returns expected value' ); + v = cabs( new Complex128( NaN, NINF ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + v = cabs( new Complex128( NINF, NaN ) ); + t.strictEqual( v, PINF, 'returns expected value' ); + + t.end(); +}); + +tape( 'if either the real or imaginary component is `NaN` but not `+-infinity`, the function returns `NaN`', opts, function test( t ) { + var v; + + v = cabs( new Complex128( NaN, 3.0 ) ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + + v = cabs( new Complex128( 5.0, NaN ) ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + + v = cabs( new Complex128( NaN, NaN ) ); + t.strictEqual( isnan( v ), true, 'returns expected value' ); + t.end(); }); From cc1f448fac002b4f81ca7234da1d20a67bb53e4a Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Wed, 2 Apr 2025 01:46:01 -0700 Subject: [PATCH 3/3] chore: remove extra linebreak --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: passed - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- lib/node_modules/@stdlib/math/base/special/cabs/src/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c b/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c index 3308807ba731..1ebbb4080d23 100644 --- a/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/cabs/src/main.c @@ -39,6 +39,5 @@ double stdlib_base_cabs( const stdlib_complex128_t z ) { double re; double im; stdlib_complex128_reim( z, &re, &im ); - return stdlib_base_hypot( re, im ); }