Skip to content

Commit 004b3c4

Browse files
feat: refactor and add protocol support to stats/base/nanvariancetk
--- 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: passed - task: lint_package_json status: na - task: lint_repl_help status: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - 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: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed ---
1 parent 87abb74 commit 004b3c4

File tree

13 files changed

+542
-147
lines changed

13 files changed

+542
-147
lines changed

lib/node_modules/@stdlib/stats/base/nanvariancetk/README.md

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ The use of the term `n-1` is commonly referred to as Bessel's correction. Note,
9898
var nanvariancetk = require( '@stdlib/stats/base/nanvariancetk' );
9999
```
100100

101-
#### nanvariancetk( N, correction, x, stride )
101+
#### nanvariancetk( N, correction, x, strideX )
102102

103103
Computes the [variance][variance] of a strided array `x` ignoring `NaN` values and using a one-pass textbook algorithm.
104104

@@ -114,17 +114,14 @@ The function has the following parameters:
114114
- **N**: number of indexed elements.
115115
- **correction**: degrees of freedom adjustment. Setting this parameter to a value other than `0` has the effect of adjusting the divisor during the calculation of the [variance][variance] according to `n-c` where `c` corresponds to the provided degrees of freedom adjustment and `n` corresponds to the number of non-`NaN` indexed elements. When computing the [variance][variance] 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 unbiased sample [variance][variance], 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).
116116
- **x**: input [`Array`][mdn-array] or [`typed array`][mdn-typed-array].
117-
- **stride**: index increment for `x`.
117+
- **strideX**: stride length for `x`.
118118

119-
The `N` and `stride` parameters determine which elements in `x` are accessed at runtime. For example, to compute the [variance][variance] of every other element in `x`,
119+
The `N` and stride parameters determine which elements in the strided array are accessed at runtime. For example, to compute the [variance][variance] of every other element in `x`,
120120

121121
```javascript
122-
var floor = require( '@stdlib/math/base/special/floor' );
123-
124122
var x = [ 1.0, 2.0, 2.0, -7.0, -2.0, 3.0, 4.0, 2.0, NaN ];
125-
var N = floor( x.length / 2 );
126123

127-
var v = nanvariancetk( N, 1, x, 2 );
124+
var v = nanvariancetk( 4, 1, x, 2 );
128125
// returns 6.25
129126
```
130127

@@ -134,18 +131,15 @@ Note that indexing is relative to the first index. To introduce an offset, use [
134131

135132
```javascript
136133
var Float64Array = require( '@stdlib/array/float64' );
137-
var floor = require( '@stdlib/math/base/special/floor' );
138134

139135
var x0 = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN ] );
140136
var x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
141137

142-
var N = floor( x0.length / 2 );
143-
144-
var v = nanvariancetk( N, 1, x1, 2 );
138+
var v = nanvariancetk( 4, 1, x1, 2 );
145139
// returns 6.25
146140
```
147141

148-
#### nanvariancetk.ndarray( N, correction, x, stride, offset )
142+
#### nanvariancetk.ndarray( N, correction, x, strideX, offsetX )
149143

150144
Computes the [variance][variance] of a strided array ignoring `NaN` values and using a one-pass textbook algorithm and alternative indexing semantics.
151145

@@ -158,17 +152,14 @@ var v = nanvariancetk.ndarray( x.length, 1, x, 1, 0 );
158152

159153
The function has the following additional parameters:
160154

161-
- **offset**: starting index for `x`.
155+
- **offsetX**: starting index for `x`.
162156

163-
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to calculate the [variance][variance] for every other value in `x` starting from the second value
157+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameter supports indexing semantics based on a starting index. For example, to calculate the [variance][variance] for every other element in the strided array starting from the second element
164158

165159
```javascript
166-
var floor = require( '@stdlib/math/base/special/floor' );
167-
168160
var x = [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ];
169-
var N = floor( x.length / 2 );
170161

171-
var v = nanvariancetk.ndarray( N, 1, x, 2, 1 );
162+
var v = nanvariancetk.ndarray( 4, 1, x, 2, 1 );
172163
// returns 6.25
173164
```
174165

@@ -181,6 +172,7 @@ var v = nanvariancetk.ndarray( N, 1, x, 2, 1 );
181172
## Notes
182173

183174
- If `N <= 0`, both functions return `NaN`.
175+
- Both functions support array-like objects having getter and setter accessors for array element access (e.g., [`@stdlib/array/base/accessor`][@stdlib/array/base/accessor]).
184176
- If `n - c` is less than or equal to `0` (where `c` corresponds to the provided degrees of freedom adjustment and `n` corresponds to the number of non-`NaN` indexed elements), both functions return `NaN`.
185177
- Some caution should be exercised when using the one-pass textbook algorithm. Literature overwhelmingly discourages the algorithm's use for two reasons: 1) the lack of safeguards against underflow and overflow and 2) the risk of catastrophic cancellation when subtracting the two sums if the sums are large and the variance small. These concerns have merit; however, the one-pass textbook algorithm should not be dismissed outright. For data distributions with a moderately large standard deviation to mean ratio (i.e., **coefficient of variation**), the one-pass textbook algorithm may be acceptable, especially when performance is paramount and some precision loss is acceptable (including a risk of returning a negative variance due to floating-point rounding errors!). In short, no single "best" algorithm for computing the variance exists. The "best" algorithm depends on the underlying data distribution, your performance requirements, and your minimum precision requirements. When evaluating which algorithm to use, consider the relative pros and cons, and choose the algorithm which best serves your needs.
186178
- Depending on the environment, the typed versions ([`dnanvariancetk`][@stdlib/stats/base/dnanvariancetk], [`snanvariancetk`][@stdlib/stats/base/snanvariancetk], etc.) are likely to be significantly more performant.
@@ -196,18 +188,12 @@ var v = nanvariancetk.ndarray( N, 1, x, 2, 1 );
196188
<!-- eslint no-undef: "error" -->
197189

198190
```javascript
199-
var randu = require( '@stdlib/random/base/randu' );
200-
var round = require( '@stdlib/math/base/special/round' );
201-
var Float64Array = require( '@stdlib/array/float64' );
191+
var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
202192
var nanvariancetk = require( '@stdlib/stats/base/nanvariancetk' );
203193

204-
var x;
205-
var i;
206-
207-
x = new Float64Array( 10 );
208-
for ( i = 0; i < x.length; i++ ) {
209-
x[ i ] = round( (randu()*100.0) - 50.0 );
210-
}
194+
var x = discreteUniform( 10, -50, 50, {
195+
'dtype': 'float64'
196+
});
211197
console.log( x );
212198

213199
var v = nanvariancetk( x.length, 1, x, 1 );
@@ -258,6 +244,8 @@ console.log( v );
258244

259245
[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
260246

247+
[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
248+
261249
[@ling:1974a]: https://doi.org/10.2307/2286154
262250

263251
<!-- <related-links> -->

lib/node_modules/@stdlib/stats/base/nanvariancetk/benchmark/benchmark.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,18 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var randu = require( '@stdlib/random/base/randu' );
24+
var uniform = require( '@stdlib/random/array/uniform' );
2525
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2626
var pow = require( '@stdlib/math/base/special/pow' );
2727
var pkg = require( './../package.json' ).name;
28-
var nanvariancetk = require( './../lib/nanvariancetk.js' );
28+
var nanvariancetk = require( './../lib/main.js' );
29+
30+
31+
// VARIABLES //
32+
33+
var options = {
34+
'dtype': 'generic'
35+
};
2936

3037

3138
// FUNCTIONS //
@@ -38,17 +45,7 @@ var nanvariancetk = require( './../lib/nanvariancetk.js' );
3845
* @returns {Function} benchmark function
3946
*/
4047
function createBenchmark( len ) {
41-
var x;
42-
var i;
43-
44-
x = [];
45-
for ( i = 0; i < len; i++ ) {
46-
if ( randu() < 0.2 ) {
47-
x.push( NaN );
48-
} else {
49-
x.push( ( randu()*20.0 ) - 10.0 );
50-
}
51-
}
48+
var x = uniform( len, -10, 10, options );
5249
return benchmark;
5350

5451
function benchmark( b ) {

lib/node_modules/@stdlib/stats/base/nanvariancetk/benchmark/benchmark.ndarray.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var randu = require( '@stdlib/random/base/randu' );
24+
var uniform = require( '@stdlib/random/array/uniform' );
2525
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2626
var pow = require( '@stdlib/math/base/special/pow' );
2727
var pkg = require( './../package.json' ).name;
2828
var nanvariancetk = require( './../lib/ndarray.js' );
2929

3030

31+
// VARIABLES //
32+
33+
var options = {
34+
'dtype': 'generic'
35+
};
36+
37+
3138
// FUNCTIONS //
3239

3340
/**
@@ -38,17 +45,7 @@ var nanvariancetk = require( './../lib/ndarray.js' );
3845
* @returns {Function} benchmark function
3946
*/
4047
function createBenchmark( len ) {
41-
var x;
42-
var i;
43-
44-
x = [];
45-
for ( i = 0; i < len; i++ ) {
46-
if ( randu() < 0.2 ) {
47-
x.push( NaN );
48-
} else {
49-
x.push( ( randu()*20.0 ) - 10.0 );
50-
}
51-
}
48+
var x = uniform( len, -10, 10, options );
5249
return benchmark;
5350

5451
function benchmark( b ) {

lib/node_modules/@stdlib/stats/base/nanvariancetk/docs/repl.txt

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11

2-
{{alias}}( N, correction, x, stride )
2+
{{alias}}( N, correction, x, strideX )
33
Computes the variance of a strided array ignoring `NaN` values and using a
44
one-pass textbook algorithm.
55

6-
The `N` and `stride` parameters determine which elements in `x` are accessed
7-
at runtime.
6+
The `N` and `stride` parameters determine which elements
7+
in the strided array are accessed at runtime.
88

99
Indexing is relative to the first index. To introduce an offset, use a typed
1010
array view.
@@ -34,8 +34,8 @@
3434
x: Array<number>|TypedArray
3535
Input array.
3636

37-
stride: integer
38-
Index increment.
37+
strideX: integer
38+
Stride length.
3939

4040
Returns
4141
-------
@@ -49,22 +49,19 @@
4949
> {{alias}}( x.length, 1, x, 1 )
5050
~4.3333
5151

52-
// Using `N` and `stride` parameters:
52+
// Using `N` and stride parameters:
5353
> x = [ -2.0, 1.0, 1.0, -5.0, 2.0, -1.0 ];
54-
> var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
55-
> var stride = 2;
56-
> {{alias}}( N, 1, x, stride )
54+
> {{alias}}( 3, 1, x, 2 )
5755
~4.3333
5856

5957
// Using view offsets:
6058
> var x0 = new {{alias:@stdlib/array/float64}}( [ 1.0, -2.0, 3.0, 2.0, 5.0, -1.0 ] );
6159
> var x1 = new {{alias:@stdlib/array/float64}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 );
62-
> N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 );
63-
> stride = 2;
64-
> {{alias}}( N, 1, x1, stride )
60+
> {{alias}}( 3, 1, x1, 2 )
6561
~4.3333
6662

67-
{{alias}}.ndarray( N, correction, x, stride, offset )
63+
64+
{{alias}}.ndarray( N, correction, x, strideX, offsetX )
6865
Computes the variance of a strided array ignoring `NaN` values and using a
6966
one-pass textbook algorithm and alternative indexing semantics.
7067

@@ -93,10 +90,10 @@
9390
x: Array<number>|TypedArray
9491
Input array.
9592

96-
stride: integer
97-
Index increment.
93+
strideX: integer
94+
Stride length.
9895

99-
offset: integer
96+
offsetX: integer
10097
Starting index.
10198

10299
Returns
@@ -113,8 +110,7 @@
113110

114111
// Using offset parameter:
115112
> var x = [ 1.0, -2.0, 3.0, 2.0, 5.0, -1.0 ];
116-
> var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
117-
> {{alias}}.ndarray( N, 1, x, 2, 1 )
113+
> {{alias}}.ndarray( 3, 1, x, 2, 1 )
118114
~4.3333
119115

120116
See Also

lib/node_modules/@stdlib/stats/base/nanvariancetk/docs/types/index.d.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@
2020

2121
/// <reference types="@stdlib/types"/>
2222

23-
import { NumericArray } from '@stdlib/types/array';
23+
import { NumericArray, Collection, AccessorArrayLike } from '@stdlib/types/array';
24+
25+
/**
26+
* Input array.
27+
*/
28+
type InputArray = NumericArray | Collection<number> | AccessorArrayLike<number>;
2429

2530
/**
2631
* Interface describing `nanvariancetk`.
@@ -32,7 +37,7 @@ interface Routine {
3237
* @param N - number of indexed elements
3338
* @param correction - degrees of freedom adjustment
3439
* @param x - input array
35-
* @param stride - stride length
40+
* @param strideX - stride length
3641
* @returns variance
3742
*
3843
* @example
@@ -41,16 +46,16 @@ interface Routine {
4146
* var v = nanvariancetk( x.length, 1, x, 1 );
4247
* // returns ~4.3333
4348
*/
44-
( N: number, correction: number, x: NumericArray, stride: number ): number;
49+
( N: number, correction: number, x: InputArray, strideX: number ): number;
4550

4651
/**
4752
* Computes the variance of a strided array ignoring `NaN` values and using a one-pass textbook algorithm and alternative indexing semantics.
4853
*
4954
* @param N - number of indexed elements
5055
* @param correction - degrees of freedom adjustment
5156
* @param x - input array
52-
* @param stride - stride length
53-
* @param offset - starting index
57+
* @param strideX - stride length
58+
* @param offsetX - starting index
5459
* @returns variance
5560
*
5661
* @example
@@ -59,7 +64,7 @@ interface Routine {
5964
* var v = nanvariancetk.ndarray( x.length, 1, x, 1, 0 );
6065
* // returns ~4.3333
6166
*/
62-
ndarray( N: number, correction: number, x: NumericArray, stride: number, offset: number ): number;
67+
ndarray( N: number, correction: number, x: InputArray, strideX: number, offset: number ): number;
6368
}
6469

6570
/**
@@ -68,7 +73,7 @@ interface Routine {
6873
* @param N - number of indexed elements
6974
* @param correction - degrees of freedom adjustment
7075
* @param x - input array
71-
* @param stride - stride length
76+
* @param strideX - stride length
7277
* @returns variance
7378
*
7479
* @example

lib/node_modules/@stdlib/stats/base/nanvariancetk/docs/types/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* limitations under the License.
1717
*/
1818

19+
import AccessorArray = require( '@stdlib/array/base/accessor' );
1920
import nanvariancetk = require( './index' );
2021

2122

@@ -26,6 +27,7 @@ import nanvariancetk = require( './index' );
2627
const x = new Float64Array( 10 );
2728

2829
nanvariancetk( x.length, 1, x, 1 ); // $ExpectType number
30+
nanvariancetk( x.length, 1, new AccessorArray( x ), 1 ); // $ExpectType number
2931
}
3032

3133
// The compiler throws an error if the function is provided a first argument which is not a number...
@@ -101,6 +103,7 @@ import nanvariancetk = require( './index' );
101103
const x = new Float64Array( 10 );
102104

103105
nanvariancetk.ndarray( x.length, 1, x, 1, 0 ); // $ExpectType number
106+
nanvariancetk.ndarray( x.length, 1, new AccessorArray( x ), 1, 0 ); // $ExpectType number
104107
}
105108

106109
// The compiler throws an error if the `ndarray` method is provided a first argument which is not a number...

lib/node_modules/@stdlib/stats/base/nanvariancetk/examples/index.js

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,12 @@
1818

1919
'use strict';
2020

21-
var randu = require( '@stdlib/random/base/randu' );
22-
var round = require( '@stdlib/math/base/special/round' );
23-
var Float64Array = require( '@stdlib/array/float64' );
21+
var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
2422
var nanvariancetk = require( './../lib' );
2523

26-
var x;
27-
var i;
28-
29-
x = new Float64Array( 10 );
30-
for ( i = 0; i < x.length; i++ ) {
31-
if ( randu() < 0.2 ) {
32-
x[ i ] = NaN;
33-
} else {
34-
x[ i ] = round( (randu()*100.0) - 50.0 );
35-
}
36-
}
24+
var x = discreteUniform( 10, -50, 50, {
25+
'dtype': 'float64'
26+
});
3727
console.log( x );
3828

3929
var v = nanvariancetk( x.length, 1, x, 1 );

0 commit comments

Comments
 (0)