From 48f947c7885429a3bb26c0fb21524b0117b36a90 Mon Sep 17 00:00:00 2001 From: Vivek Maurya Date: Tue, 10 Dec 2024 10:33:38 +0530 Subject: [PATCH 1/5] feat(add C implementation): add stats/base/dists/arcsine --- .../stats/base/dists/arcsine/logcdf/README.md | 91 +++++++++ .../dists/arcsine/logcdf/benchmark/c/Makefile | 146 +++++++++++++++ .../arcsine/logcdf/benchmark/c/benchmark.c | 137 ++++++++++++++ .../base/dists/arcsine/logcdf/binding.gyp | 170 +++++++++++++++++ .../dists/arcsine/logcdf/examples/c/Makefile | 146 +++++++++++++++ .../dists/arcsine/logcdf/examples/c/example.c | 37 ++++ .../base/dists/arcsine/logcdf/include.gypi | 53 ++++++ .../stdlib/stats/base/dists/arcsine/logcdf.h | 38 ++++ .../base/dists/arcsine/logcdf/lib/native.js | 75 ++++++++ .../base/dists/arcsine/logcdf/manifest.json | 94 ++++++++++ .../base/dists/arcsine/logcdf/package.json | 3 + .../base/dists/arcsine/logcdf/src/Makefile | 70 +++++++ .../base/dists/arcsine/logcdf/src/addon.c | 23 +++ .../base/dists/arcsine/logcdf/src/main.c | 59 ++++++ .../dists/arcsine/logcdf/test/test.native.js | 174 ++++++++++++++++++ 15 files changed, 1316 insertions(+) create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/Makefile create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/benchmark.c create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/binding.gyp create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/Makefile create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/example.c create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/include.gypi create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/include/stdlib/stats/base/dists/arcsine/logcdf.h create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/lib/native.js create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/manifest.json create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/src/Makefile create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/src/addon.c create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/src/main.c create mode 100644 lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/test/test.native.js diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/README.md b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/README.md index 191e1d965834..8f047bd32041 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/README.md +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/README.md @@ -147,6 +147,97 @@ for ( i = 0; i < 25; i++ ) { + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/stats/base/dists/arcsine/logcdf.h" +``` + +#### stdlib_base_dists_arcsine_logcdf( a, b ) + +Evaluates the logarithm of the [cumulative distribution function][cdf] (CDF) for an [arcsine][arcsine-distribution] distribution with parameters `a` (minimum support) and `b` (maximum support). + +```c +double out = stdlib_base_dists_arcsine_logcdf( 9.0, 0.0, 10.0 ); +// returns ~-0.23 +``` + +The function accepts the following arguments: + +- **x**: `[in] double` minimum support +- **a**: `[in] double` minimum support +- **b**: `[in] double` maximum support + +```c +double stdlib_base_dists_arcsine_logcdf( const double x, const double a, const double b ); +``` +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/stats/base/dists/arcsine/logcdf.h" +#include +#include +int main( void ) { + double x; + double a; + double b; + double y; + int i; + + for ( i = 0; i < 25; i++ ) { + x = ( (double)rand() / (double)RAND_MAX ) * 20.0 - 10.0; + a = ( (double)rand() / (double)RAND_MAX ) * 20.0 - 20.0; + b = a + ( (double)rand() / (double)RAND_MAX ) * 40.0; + y = stdlib_base_dists_arcsine_logcdf( x, a, b ); + printf( "x: %lf ,a: %lf, b: %lf, ln(F;x,a,b): %lf\n", x, a, b, y ); + } +} +``` + +
+ + + +
+ + + @@ -213,6 +214,12 @@ double stdlib_base_dists_arcsine_logcdf( const double x, const double a, const d #include "stdlib/stats/base/dists/arcsine/logcdf.h" #include #include + +static double random_uniform( const double min, const double max ) { + double v = (double)rand() / ( (double)RAND_MAX + 1.0 ); + return min + ( v*(max-min) ); +} + int main( void ) { double x; double a; @@ -221,12 +228,12 @@ int main( void ) { int i; for ( i = 0; i < 25; i++ ) { - x = ( (double)rand() / (double)RAND_MAX ) * 20.0 - 10.0; - a = ( (double)rand() / (double)RAND_MAX ) * 20.0 - 20.0; - b = a + ( (double)rand() / (double)RAND_MAX ) * 40.0; - y = stdlib_base_dists_arcsine_logcdf( x, a, b ); - printf( "x: %lf ,a: %lf, b: %lf, ln(F;x,a,b): %lf\n", x, a, b, y ); - } + x = random_uniform( -10.0, 10.0 ); + a = random_uniform( -20.0, 0.0 ); + b = random_uniform( a, a+40.0 ); + y = stdlib_base_dists_arcsine_logcdf( x, a, b ); + printf( "x: %lf, a: %lf, b: %lf, F(x;a,b): %lf\n", x, a, b, y ); + } } ``` diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.js index f8b8531dc0e9..7e3dda883717 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.js @@ -21,6 +21,8 @@ // MODULES // var bench = require( '@stdlib/bench' ); +var Float64Array = require( '@stdlib/array/float64' ); +var uniform = require( '@stdlib/random/array/uniform' ); var randu = require( '@stdlib/random/base/randu' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var pkg = require( './../package.json' ).name; @@ -32,16 +34,24 @@ var logcdf = require( './../lib' ); bench( pkg, function benchmark( b ) { var min; var max; + var len; var x; var y; var i; + len = 100; + x = new Float64Array( len ); + min = new Float64Array( len ); + max = new Float64Array( len ); + for ( i = 0; i < len; i++ ) { + x[ i ] = ( randu() * 20.0 ) - 10.0; + min[ i ] = ( randu() * 20.0 ) - 20.0; + max[ i ] = min[ i ] + ( randu() * 40.0 ); + } + b.tic(); for ( i = 0; i < b.iterations; i++ ) { - x = ( randu() * 20.0 ) - 10.0; - min = ( randu() * 20.0 ) - 20.0; - max = min + ( randu() * 40.0 ); - y = logcdf( x, min, max ); + y = logcdf( x[ i % len ], min[ i % len ], max[ i % len ] ); if ( isnan( y ) ) { b.fail( 'should not return NaN' ); } @@ -65,11 +75,11 @@ bench( pkg+':factory', function benchmark( b ) { min = -1.5; max = 1.5; mylogcdf = logcdf.factory( min, max ); + x = uniform( 100, -2.0, 2.0 ); b.tic(); for ( i = 0; i < b.iterations; i++ ) { - x = ( randu()*2.0 ) - 2.0; - y = mylogcdf( x ); + y = mylogcdf( x[ i % x.length ] ); if ( isnan( y ) ) { b.fail( 'should not return NaN' ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.native.js b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.native.js new file mode 100644 index 000000000000..ac2853a9bbdb --- /dev/null +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/benchmark.native.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 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 Float64Array = require( '@stdlib/array/float64' ); +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 logcdf = tryRequire( resolve( __dirname, './../lib/native.js' ) ); +var opts = { + 'skip': ( logcdf instanceof Error ) +}; + + +// MAIN // + +bench( pkg+'::native', opts, function benchmark( b ) { + var len; + var min; + var max; + var x; + var y; + var i; + + len = 100; + x = new Float64Array( len ); + min = new Float64Array( len ); + max = new Float64Array( len ); + for ( i = 0; i < len; i++ ) { + x[ i ] = ( randu() * 20.0 ) - 10.0; + min[ i ] = ( randu() * 20.0 ) - 20.0; + max[ i ] = min[ i ] + ( randu() * 40.0 ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + y = logcdf( x[ i % len ], min[ i % len ], max[ i % len ] ); + 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/stats/base/dists/arcsine/logcdf/benchmark/c/Makefile b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/Makefile index 0ebf4545e1a9..f69e9da2b4d3 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/Makefile +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/Makefile @@ -143,4 +143,4 @@ run: $(c_targets) clean: $(QUIET) -rm -f *.o *.out -.PHONY: clean \ No newline at end of file +.PHONY: clean diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/benchmark.c b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/benchmark.c index 6110ad2d39e0..7bc28d6a8de4 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/benchmark.c +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/benchmark/c/benchmark.c @@ -75,13 +75,15 @@ static double tic( void ) { } /** -* Generates a random number on the interval [0,1). +* Generates a random number on the interval [min,max). * -* @return random number +* @param min minimum value (inclusive) +* @param max maximum value (exclusive) +* @return random number */ -static double rand_double( void ) { - int r = rand(); - return (double)r / ( (double)RAND_MAX + 1.0 ); +static double random_uniform( const double min, const double max ) { + double v = (double)rand() / ( (double)RAND_MAX + 1.0 ); + return min + ( v*(max-min) ); } /** @@ -91,19 +93,22 @@ static double rand_double( void ) { */ static double benchmark( void ) { double elapsed; - double x; - double a; - double b; + double x[ 100 ]; + double a[ 100 ]; + double b[ 100 ]; double y; double t; int i; + for ( i = 0; i < 100; i++ ) { + x[ i ] = random_uniform( -10.0, 10.0 ); + a[ i ] = random_uniform( -20.0, 0.0 ); + b[ i ] = random_uniform( a[ i ], a[ i ]+40.0 ); + } + t = tic(); for ( i = 0; i < ITERATIONS; i++ ) { - x = ( 20.0 * rand_double() ) - 10.0; - a = ( 20.0 * rand_double() ) - 20.0; - b = a + ( 40.0 * rand_double() ); - y = stdlib_base_dists_arcsine_logcdf( x, a, b ); + y = stdlib_base_dists_arcsine_logcdf( x[ i%100 ], a[ i%100 ], b[ i%100 ] ); if ( y != y ) { printf( "should not return NaN\n" ); break; @@ -134,4 +139,4 @@ int main( void ) { printf( "ok %d benchmark finished\n", i+1 ); } print_summary( REPEATS, REPEATS ); -} \ No newline at end of file +} diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/binding.gyp b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/binding.gyp index 507cb00291e7..ec3992233442 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/binding.gyp +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/binding.gyp @@ -167,4 +167,4 @@ ], # end actions }, # end target copy_addon ], # end targets -} \ No newline at end of file +} diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/Makefile b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/Makefile index d53ef397c77d..6aed70daf167 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/Makefile +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/Makefile @@ -143,4 +143,4 @@ run: $(c_targets) clean: $(QUIET) -rm -f *.o *.out -.PHONY: clean \ No newline at end of file +.PHONY: clean diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/example.c b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/example.c index 86d5bd3a28f7..68b87c668dfc 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/example.c +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/examples/c/example.c @@ -34,4 +34,4 @@ int main( void ) { y = stdlib_base_dists_arcsine_logcdf( x, a, b ); printf( "x: %lf ,a: %lf, b: %lf, ln(F;x,a,b): %lf\n", x, a, b, y ); } -} \ No newline at end of file +} diff --git a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/include.gypi b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/include.gypi index c6495fc1da3f..575cb043c0bf 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/include.gypi +++ b/lib/node_modules/@stdlib/stats/base/dists/arcsine/logcdf/include.gypi @@ -50,4 +50,4 @@ '= b`, the function returns `NaN`', function test( t ) { +tape( 'if provided `a >= b`, the function returns `NaN`', opts, function test( t ) { var y; y = logcdf( 2.0, -1.0, -1.0 ); @@ -93,7 +93,7 @@ tape( 'if provided `a >= b`, the function returns `NaN`', function test( t ) { t.end(); }); -tape( 'the function evaluates the logcdf for `x` given a small range `b - a`', function test( t ) { +tape( 'the function evaluates the logcdf for `x` given a small range `b - a`', opts, function test( t ) { var expected; var delta; var tol; @@ -120,7 +120,7 @@ tape( 'the function evaluates the logcdf for `x` given a small range `b - a`', f t.end(); }); -tape( 'the function evaluates the logcdf for `x` given a medium range `b - a`', function test( t ) { +tape( 'the function evaluates the logcdf for `x` given a medium range `b - a`', opts, function test( t ) { var expected; var delta; var tol; @@ -147,7 +147,7 @@ tape( 'the function evaluates the logcdf for `x` given a medium range `b - a`', t.end(); }); -tape( 'the function evaluates the logcdf for `x` given a large range `b - a`', function test( t ) { +tape( 'the function evaluates the logcdf for `x` given a large range `b - a`', opts, function test( t ) { var expected; var delta; var tol;