Skip to content

Commit 457241a

Browse files
committed
Refactor: added stats/incr/nanmmax
1 parent 87abb74 commit 457241a

File tree

6 files changed

+493
-0
lines changed

6 files changed

+493
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var randu = require( '@stdlib/random/base/randu' );
25+
var pkg = require( './../package.json' ).name;
26+
var nanmmax = require( './../lib' );
27+
28+
// MAIN //
29+
30+
bench( pkg, function benchmark( b ) {
31+
var f;
32+
var i;
33+
var v;
34+
35+
f = nanmmax( 5 );
36+
37+
b.tic();
38+
for ( i = 0; i < b.iterations; i++ ) {
39+
v = f( randu() );
40+
if ( v === void 0 ) {
41+
b.fail( 'should not return undefined' );
42+
}
43+
}
44+
b.toc();
45+
if ( v === void 0 ) {
46+
b.fail( 'should not return undefined' );
47+
}
48+
b.pass( 'benchmark finished' );
49+
b.end();
50+
});
51+
52+
bench( pkg+':mixed', function benchmark( b ) {
53+
var f;
54+
var i;
55+
var v;
56+
57+
f = nanmmax( 5 );
58+
59+
b.tic();
60+
for ( i = 0; i < b.iterations; i++ ) {
61+
v = f( (randu() < 0.2) ? NaN : randu() );
62+
if ( v === void 0 ) {
63+
b.fail( 'should not return undefined' );
64+
}
65+
}
66+
b.toc();
67+
if ( v === void 0 ) {
68+
b.fail( 'should not return undefined' );
69+
}
70+
b.pass( 'benchmark finished' );
71+
b.end();
72+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
var randu = require( '@stdlib/random/base/randu' );
22+
var nanmmax = require( './../lib' );
23+
24+
var accumulator;
25+
var v;
26+
var i;
27+
28+
// Initialize an accumulator:
29+
accumulator = nanmmax( 5 );
30+
31+
// For each simulated datum, update the moving maximum:
32+
console.log( '\nValue\tMax\n' );
33+
for ( i = 0; i < 100; i++ ) {
34+
if ( randu() < 0.2 ) {
35+
v = NaN;
36+
} else {
37+
v = randu() * 100.0;
38+
}
39+
console.log( '%d\t%d', v, accumulator( v ) );
40+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
/**
22+
* Returns an accumulator function which incrementally computes a moving maximum value, ignoring NaN values.
23+
*
24+
* @module @stdlib/stats/incr/nanmmax
25+
*
26+
* @example
27+
* var nanmmax = require( '@stdlib/stats/incr/nanmmax' );
28+
*
29+
* var accumulator = nanmmax( 3 );
30+
*
31+
* var v = accumulator();
32+
* // returns null
33+
*
34+
* v = accumulator( 2.0 );
35+
* // returns 2.0
36+
*
37+
* v = accumulator( -5.0 );
38+
* // returns 2.0
39+
*
40+
* v = accumulator( NaN );
41+
* // returns 2.0
42+
*
43+
* v = accumulator( 3.0 );
44+
* // returns 3.0
45+
*
46+
* v = accumulator();
47+
* // returns 3.0
48+
*/
49+
50+
// MODULES //
51+
52+
var main = require( './main.js' );
53+
54+
// EXPORTS //
55+
56+
module.exports = main;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var isPositiveInteger = require('@stdlib/assert/is-positive-integer').isPrimitive;
24+
var isnan = require('@stdlib/math/base/assert/is-nan');
25+
var format = require('@stdlib/string/format');
26+
27+
// MAIN //
28+
29+
/**
30+
* Returns an accumulator function which incrementally computes a moving maximum value, ignoring NaN values.
31+
*
32+
* @param {PositiveInteger} W - window size
33+
* @throws {TypeError} must provide a positive integer
34+
* @returns {Function} accumulator function
35+
*
36+
* @example
37+
* var accumulator = nanmmax( 3 );
38+
*
39+
* var v = accumulator();
40+
* // returns null
41+
*
42+
* v = accumulator( 2.0 );
43+
* // returns 2.0
44+
*
45+
* v = accumulator( -5.0 );
46+
* // returns 2.0
47+
*
48+
* v = accumulator( NaN );
49+
* // returns 2.0
50+
*
51+
* v = accumulator( 3.0 );
52+
* // returns 3.0
53+
*
54+
* v = accumulator();
55+
* // returns 3.0
56+
*/
57+
function nanmmax( W ) {
58+
var buffer;
59+
var count;
60+
var head;
61+
62+
if ( !isPositiveInteger( W ) ) {
63+
throw new TypeError( format( 'invalid argument. Must provide a positive integer. Value: `%s`.', W ) );
64+
}
65+
// Initialize a circular buffer for storing values:
66+
buffer = new Array( W );
67+
count = 0;
68+
head = -1;
69+
70+
return accumulator;
71+
72+
/**
73+
* If provided a value, the accumulator function returns an updated moving maximum. If not provided a value, the accumulator function returns the current moving maximum.
74+
*
75+
* @private
76+
* @param {number} [x] - input value
77+
* @returns {(number|null)} moving maximum or null
78+
*/
79+
function accumulator( x ) {
80+
var oldestIdx;
81+
var max;
82+
var i;
83+
84+
if ( arguments.length === 0 ) {
85+
if ( count === 0 ) {
86+
return null;
87+
}
88+
// Calculate max of current window:
89+
max = null;
90+
for ( i = 0; i < count; i++ ) {
91+
if ( !isnan( buffer[i] ) && (max === null || buffer[i] > max) ) {
92+
max = buffer[i];
93+
}
94+
}
95+
return max;
96+
}
97+
// Update circular buffer:
98+
oldestIdx = count === W ? (head + 1) % W : -1;
99+
head = (head + 1) % W;
100+
buffer[ head ] = x;
101+
if ( count < W ) {
102+
count += 1;
103+
}
104+
105+
// Calculate max of current window:
106+
max = null;
107+
for ( i = 0; i < count; i++ ) {
108+
if ( !isnan( buffer[i] ) && (max === null || buffer[i] > max) ) {
109+
max = buffer[i];
110+
}
111+
}
112+
return max;
113+
}
114+
}
115+
116+
// EXPORTS //
117+
118+
module.exports = nanmmax;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"name": "@stdlib/stats/incr/nanmmax",
3+
"version": "0.0.0",
4+
"description": "Moving maximum ignoring NaN values.",
5+
"license": "Apache-2.0",
6+
"author": {
7+
"name": "The Stdlib Authors",
8+
"url": "https://github.com/stdlib-js/stdlib/graphs/contributors"
9+
},
10+
"contributors": [
11+
{
12+
"name": "The Stdlib Authors",
13+
"url": "https://github.com/stdlib-js/stdlib/graphs/contributors"
14+
}
15+
],
16+
"main": "./lib",
17+
"directories": {
18+
"benchmark": "./benchmark",
19+
"doc": "./docs",
20+
"example": "./examples",
21+
"lib": "./lib",
22+
"test": "./test"
23+
},
24+
"types": "./docs/types",
25+
"scripts": {},
26+
"homepage": "https://github.com/stdlib-js/stdlib",
27+
"repository": {
28+
"type": "git",
29+
"url": "git://github.com/stdlib-js/stdlib.git"
30+
},
31+
"bugs": {
32+
"url": "https://github.com/stdlib-js/stdlib/issues"
33+
},
34+
"dependencies": {
35+
"@stdlib/assert": "^0.0.x",
36+
"@stdlib/math": "^0.0.x",
37+
"@stdlib/string": "^0.0.x",
38+
"@stdlib/types": "^0.0.x"
39+
},
40+
"devDependencies": {},
41+
"engines": {
42+
"node": ">=0.10.0",
43+
"npm": ">2.7.0"
44+
},
45+
"os": [
46+
"aix",
47+
"darwin",
48+
"freebsd",
49+
"linux",
50+
"macos",
51+
"openbsd",
52+
"sunos",
53+
"win32",
54+
"windows"
55+
],
56+
"keywords": [
57+
"stdlib",
58+
"stdmath",
59+
"statistics",
60+
"stats",
61+
"mathematics",
62+
"math",
63+
"maximum",
64+
"max",
65+
"moving",
66+
"sliding",
67+
"window",
68+
"incremental",
69+
"accumulator",
70+
"nan"
71+
]
72+
}

0 commit comments

Comments
 (0)