Repository navigation
Conversation
Coverage Report
The above coverage report was generated for the changes in this PR. |
|
Could you please apply the same changes discussed in #14718 to this PR as well? |
0PrashantYadav0
left a comment
There was a problem hiding this comment.
Several fixes made in #14718 after review apply here too (src/main.c, test/test.js, test/test.native.js).
| */ | ||
| #include "stdlib/stats/base/ndarray/sstdevch.h" | ||
| #include "stdlib/stats/strided/sstdevch.h" | ||
| #include "stdlib/ndarray/ctor.h" | ||
| #include "stdlib/blas/base/shared.h" | ||
|
|
||
| /** | ||
| * Computes the standard deviation of a one-dimensional single-precision floating-point ndarray using a one-pass trial mean algorithm. | ||
| * | ||
| * @param arrays list containing an input ndarray and a zero-dimensional ndarray specifying the degrees of freedom adjustment | ||
| * @return standard deviation | ||
| */ | ||
| float stdlib_stats_sstdevch( const struct ndarray *arrays[] ) { | ||
| const struct ndarray *x = arrays[ 0 ]; | ||
| const struct ndarray *correction = arrays[ 1 ]; | ||
| float c; | ||
|
|
||
| // For zero-dimensional arrays, `stdlib_ndarray_iget_float32` returns the first (and only) indexed element, regardless of the supplied index: | ||
| stdlib_ndarray_iget_float32( correction, 0, &c ); | ||
|
|
||
| return API_SUFFIX(stdlib_strided_sstdevch_ndarray)( stdlib_ndarray_dimension( x, 0 ), c, (const float *)stdlib_ndarray_data( x ), stdlib_ndarray_stride_elements( x, 0 ), stdlib_ndarray_offset_elements( x ) ); | ||
| } |
There was a problem hiding this comment.
| */ | |
| #include "stdlib/stats/base/ndarray/sstdevch.h" | |
| #include "stdlib/stats/strided/sstdevch.h" | |
| #include "stdlib/ndarray/ctor.h" | |
| #include "stdlib/blas/base/shared.h" | |
| /** | |
| * Computes the standard deviation of a one-dimensional single-precision floating-point ndarray using a one-pass trial mean algorithm. | |
| * | |
| * @param arrays list containing an input ndarray and a zero-dimensional ndarray specifying the degrees of freedom adjustment | |
| * @return standard deviation | |
| */ | |
| float stdlib_stats_sstdevch( const struct ndarray *arrays[] ) { | |
| const struct ndarray *x = arrays[ 0 ]; | |
| const struct ndarray *correction = arrays[ 1 ]; | |
| float c; | |
| // For zero-dimensional arrays, `stdlib_ndarray_iget_float32` returns the first (and only) indexed element, regardless of the supplied index: | |
| stdlib_ndarray_iget_float32( correction, 0, &c ); | |
| return API_SUFFIX(stdlib_strided_sstdevch_ndarray)( stdlib_ndarray_dimension( x, 0 ), c, (const float *)stdlib_ndarray_data( x ), stdlib_ndarray_stride_elements( x, 0 ), stdlib_ndarray_offset_elements( x ) ); | |
| } | |
| */ | |
| #include "stdlib/stats/base/ndarray/sstdevch.h" | |
| #include "stdlib/stats/strided/sstdevch.h" | |
| #include "stdlib/ndarray/ctor.h" | |
| #include "stdlib/blas/base/shared.h" | |
| /** | |
| * Computes the standard deviation of a one-dimensional single-precision floating-point ndarray using a one-pass trial mean algorithm. | |
| * | |
| * ## Notes | |
| * | |
| * - The function expects the following ndarrays: | |
| * | |
| * - a one-dimensional input ndarray. | |
| * - a zero-dimensional ndarray specifying the degrees of freedom adjustment. | |
| * | |
| * @param arrays list containing ndarrays | |
| * @return standard deviation | |
| */ | |
| float stdlib_stats_sstdevch( const struct ndarray *arrays[] ) { | |
| const struct ndarray *x = arrays[ 0 ]; | |
| float correction; | |
| stdlib_ndarray_get_float32( arrays[ 1 ], NULL, &correction ); | |
| return API_SUFFIX(stdlib_strided_sstdevch_ndarray)( stdlib_ndarray_dimension( x, 0 ), correction, (const float *)stdlib_ndarray_data( x ), stdlib_ndarray_stride_elements( x, 0 ), stdlib_ndarray_offset_elements( x ) ); | |
| } |
Match svariancech/src/main.c (#15008) and sstdevyc (#15003) for the correction argument. Same missing blank line after the license header in src/addon.c:17, examples/c/example.c:17, benchmark/c/benchmark.length.c:17.
| # 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 |
There was a problem hiding this comment.
| # 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 | |
| # 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 |
This is a copy of examples/c/Makefile; match svariancech/src/Makefile.
| $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES) | ||
|
|
||
| #/ | ||
| # Runs compiled examples. |
There was a problem hiding this comment.
| # Runs compiled examples. | |
| # Runs compiled benchmarks. |
| * Generates a random number on the interval [0, 1). | ||
| * | ||
| * @return random number | ||
| */ | ||
| static double rand_double( void ) { | ||
| return (double)rand() / ( (double)RAND_MAX + 1.0 ); | ||
| } |
There was a problem hiding this comment.
| * Generates a random number on the interval [0, 1). | |
| * | |
| * @return random number | |
| */ | |
| static double rand_double( void ) { | |
| return (double)rand() / ( (double)RAND_MAX + 1.0 ); | |
| } | |
| * Generates a random number on the interval [0,1). | |
| * | |
| * @return random number | |
| */ | |
| static float rand_float( void ) { | |
| int r = rand(); | |
| return (float)r / ( (float)RAND_MAX + 1.0f ); | |
| } |
And data[ i ] = ( rand_float() * 20000.0f ) - 10000.0f; at L134, as in svariancech/benchmark/c/benchmark.length.c. Same as #15170 (comment).
| // Create an input ndarray: | ||
| const float xbuf[] = { 1.0f, 2.0f, 3.0f, 4.0f }; | ||
| int64_t xshape[] = { 4 }; | ||
| int64_t xstrides[] = { STDLIB_NDARRAY_FLOAT32_BYTES_PER_ELEMENT }; | ||
| int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; | ||
| struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)xbuf, 1, xshape, xstrides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes ); | ||
|
|
||
| // Create a zero-dimensional ndarray specifying the degrees of freedom adjustment: | ||
| const float cbuf[] = { 1.0f }; | ||
| int64_t *cshape = NULL; | ||
| int64_t cstrides[] = { 0 }; | ||
| struct ndarray *correction = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)cbuf, 0, cshape, cstrides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 0, submodes ); | ||
|
|
||
| // Compute the standard deviation: | ||
| const struct ndarray *arrays[] = { x, correction }; | ||
| float v = stdlib_stats_sstdevch( arrays ); | ||
| // returns ~2.0817 | ||
|
|
||
| // Free allocated memory: | ||
| stdlib_ndarray_free( x ); | ||
| stdlib_ndarray_free( correction ); |
There was a problem hiding this comment.
| // Create an input ndarray: | |
| const float xbuf[] = { 1.0f, 2.0f, 3.0f, 4.0f }; | |
| int64_t xshape[] = { 4 }; | |
| int64_t xstrides[] = { STDLIB_NDARRAY_FLOAT32_BYTES_PER_ELEMENT }; | |
| int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; | |
| struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)xbuf, 1, xshape, xstrides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes ); | |
| // Create a zero-dimensional ndarray specifying the degrees of freedom adjustment: | |
| const float cbuf[] = { 1.0f }; | |
| int64_t *cshape = NULL; | |
| int64_t cstrides[] = { 0 }; | |
| struct ndarray *correction = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)cbuf, 0, cshape, cstrides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 0, submodes ); | |
| // Compute the standard deviation: | |
| const struct ndarray *arrays[] = { x, correction }; | |
| float v = stdlib_stats_sstdevch( arrays ); | |
| // returns ~2.0817 | |
| // Free allocated memory: | |
| stdlib_ndarray_free( x ); | |
| stdlib_ndarray_free( correction ); | |
| // Create an ndarray: | |
| const float data[] = { 1.0f, -2.0f, 2.0f }; | |
| int64_t shape[] = { 3 }; | |
| int64_t strides[] = { STDLIB_NDARRAY_FLOAT32_BYTES_PER_ELEMENT }; | |
| int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR }; | |
| struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)data, 1, shape, strides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes ); | |
| // Create an ndarray for specifying the degrees of freedom adjustment: | |
| const float cdata[] = { 1.0f }; | |
| int64_t cstrides[] = { 0 }; | |
| struct ndarray *corr = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)cdata, 0, NULL, cstrides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes ); | |
| // Compute the result: | |
| const struct ndarray *arrays[] = { x, corr }; | |
| float v = stdlib_stats_sstdevch( arrays ); | |
| // returns ~2.0817f | |
| // Free allocated memory: | |
| stdlib_ndarray_free( x ); | |
| stdlib_ndarray_free( corr ); |
~2.0817 is wrong for { 1, 2, 3, 4 } (that gives ~1.2910); this matches the JS example and svariancech's README.
|
|
||
| The function accepts the following arguments: | ||
|
|
||
| - **arrays**: `[in] struct ndarray**` list containing the following ndarrays: a one-dimensional input ndarray and a zero-dimensional ndarray specifying the degrees of freedom adjustment. |
There was a problem hiding this comment.
| - **arrays**: `[in] struct ndarray**` list containing the following ndarrays: a one-dimensional input ndarray and a zero-dimensional ndarray specifying the degrees of freedom adjustment. | |
| - **arrays**: `[in] struct ndarray**` list containing the following ndarrays: | |
| - `[in] struct ndarray*` a one-dimensional input ndarray. | |
| - `[in] struct ndarray*` a zero-dimensional ndarray specifying the degrees of freedom adjustment. Providing a non-zero degrees of freedom adjustment has the effect of adjusting the divisor during the calculation of the [standard deviation][standard-deviation] according to `N-c` where `N` is the number of elements in the input ndarray and `c` corresponds to the provided degrees of freedom adjustment. When computing the [standard deviation][standard-deviation] of a population, setting this parameter to `0` is the standard choice (i.e., the provided array contains data constituting an entire population). When computing the corrected sample [standard deviation][standard-deviation], setting this parameter to `1` is the standard choice (i.e., the provided array contains data sampled from a larger population; this is commonly referred to as Bessel's correction). |
Match svariancech's README.
| int64_t cstrides[] = { 0 }; | ||
|
|
||
| // cppcheck-suppress invalidPointerCast | ||
| struct ndarray *correction = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)cbuf, 0, cshape, cstrides, offset, order, imode, 0, submodes ); |
There was a problem hiding this comment.
| struct ndarray *correction = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)cbuf, 0, cshape, cstrides, offset, order, imode, 0, submodes ); | |
| struct ndarray *correction = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)cbuf, 0, cshape, cstrides, offset, order, imode, nsubmodes, submodes ); |
Same in README.md:318.
| * var opts = { | ||
| * 'dtype': 'float32' | ||
| * }); | ||
| * }; | ||
| * | ||
| * var x = new Float32Vector( [ 1.0, -2.0, 2.0 ] ); | ||
| * | ||
| * var correction = scalar2ndarray( 1.0, opts ); |
There was a problem hiding this comment.
| * var opts = { | |
| * 'dtype': 'float32' | |
| * }); | |
| * }; | |
| * | |
| * var x = new Float32Vector( [ 1.0, -2.0, 2.0 ] ); | |
| * | |
| * var correction = scalar2ndarray( 1.0, opts ); | |
| * var x = new Float32Vector( [ 1.0, -2.0, 2.0 ] ); | |
| * var correction = scalar2ndarray( 1.0, { | |
| * 'dtype': 'float32' | |
| * }); |
Unrelated to the C implementation; please revert.
| @@ -0,0 +1,229 @@ | |||
| /** | |||
There was a problem hiding this comment.
test/test.js still duplicates these tests; replace it with the proxyquire dispatcher test from svariancech/test/test.js, as requested in #14718 (comment).
| tape( 'the function calculates the standard deviation of a one-dimensional ndarray using a one-pass trial mean algorithm', opts, function test( t ) { | ||
| var correction; | ||
| var expected; | ||
| var optsD; |
There was a problem hiding this comment.
| var optsD; | |
| var opts; |
Rename optsD to opts throughout, as in svariancech/test/test.native.js and #14718 (comment).
Resolves a part of #14034
Description
This pull request:
ndarrayimplementation forstats/base/ndarray/sstdevchlib/native.jsand updateslib/index.jsto prefer the native add-on with a fallback to the existing JavaScript implementationtest/test.main.jsandtest/test.native.jsto separately exercise the JavaScript and native code pathsexamples/c/example.c,benchmark/c/benchmark.length.c) alongside abenchmark/benchmark.native.jsREADME.mddocumentingstdlib_stats_sstdevchpackage.json(gypfile,browser,include/srcdirectories) to support building the add-onRelated Issues
This pull request has the following related issues:
@stdlib/stats/base/ndarraypackages (tracking issue) #14034Questions
No.
Other
No.
Checklist
AI Assistance
If you answered "yes" above, how did you use AI assistance?
Disclosure
{{TODO: add disclosure if applicable}}
@stdlib-js/reviewers