Skip to content

Commit 75c2cb7

Browse files
feat: add C implementation in stats/base/ndarray/smean
1 parent 9799508 commit 75c2cb7

File tree

4 files changed

+399
-126
lines changed

4 files changed

+399
-126
lines changed

lib/node_modules/@stdlib/stats/base/ndarray/smean/lib/index.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,23 @@
3737

3838
// MODULES //
3939

40+
var join = require( 'path' ).join;
41+
var tryRequire = require( '@stdlib/utils/try-require' );
42+
var isError = require( '@stdlib/assert/is-error' );
4043
var main = require( './main.js' );
4144

4245

46+
// MAIN //
47+
48+
var smean;
49+
var tmp = tryRequire( join( __dirname, './native.js' ) );
50+
if ( isError( tmp ) ) {
51+
smean = main;
52+
} else {
53+
smean = tmp;
54+
}
55+
56+
4357
// EXPORTS //
4458

45-
module.exports = main;
59+
module.exports = smean;
Lines changed: 29 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @license Apache-2.0
33
*
4-
* Copyright (c) 2025 The Stdlib Authors.
4+
* Copyright (c) 2026 The Stdlib Authors.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -21,28 +21,16 @@
2121
// MODULES //
2222

2323
var tape = require( 'tape' );
24-
var isnan = require( '@stdlib/math/base/assert/is-nan' );
25-
var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
26-
var Float32Array = require( '@stdlib/array/float32' );
27-
var ndarray = require( '@stdlib/ndarray/base/ctor' );
24+
var proxyquire = require( 'proxyquire' );
25+
var IS_BROWSER = require( '@stdlib/assert/is-browser' );
2826
var smean = require( './../lib' );
2927

3028

31-
// FUNCTIONS //
29+
// VARIABLES //
3230

33-
/**
34-
* Returns a one-dimensional ndarray.
35-
*
36-
* @private
37-
* @param {Collection} buffer - underlying data buffer
38-
* @param {NonNegativeInteger} length - number of indexed elements
39-
* @param {integer} stride - stride length
40-
* @param {NonNegativeInteger} offset - index offset
41-
* @returns {ndarray} one-dimensional ndarray
42-
*/
43-
function vector( buffer, length, stride, offset ) {
44-
return new ndarray( 'float32', buffer, [ length ], [ stride ], offset, 'row-major' );
45-
}
31+
var opts = {
32+
'skip': IS_BROWSER
33+
};
4634

4735

4836
// TESTS //
@@ -53,121 +41,37 @@ tape( 'main export is a function', function test( t ) {
5341
t.end();
5442
});
5543

56-
tape( 'the function has an arity of 1', function test( t ) {
57-
t.strictEqual( smean.length, 1, 'has expected arity' );
58-
t.end();
59-
});
60-
61-
tape( 'the function calculates the arithmetic mean of a one-dimensional ndarray', function test( t ) {
62-
var x;
63-
var v;
64-
65-
x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0 ] );
66-
v = smean( [ vector( x, 6, 1, 0 ) ] );
67-
t.strictEqual( v, 0.5, 'returns expected value' );
68-
69-
x = new Float32Array( [ -4.0, -5.0 ] );
70-
v = smean( [ vector( x, 2, 1, 0 ) ] );
71-
t.strictEqual( v, -4.5, 'returns expected value' );
72-
73-
x = new Float32Array( [ -0.0, 0.0, -0.0 ] );
74-
v = smean( [ vector( x, 3, 1, 0 ) ] );
75-
t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
76-
77-
x = new Float32Array( [ NaN ] );
78-
v = smean( [ vector( x, 1, 1, 0 ) ] );
79-
t.strictEqual( isnan( v ), true, 'returns expected value' );
80-
81-
x = new Float32Array( [ NaN, NaN ] );
82-
v = smean( [ vector( x, 2, 1, 0 ) ] );
83-
t.strictEqual( isnan( v ), true, 'returns expected value' );
84-
85-
t.end();
86-
});
87-
88-
tape( 'if provided an empty ndarray, the function returns `NaN`', function test( t ) {
89-
var x;
90-
var v;
91-
92-
x = new Float32Array( [] );
93-
94-
v = smean( [ vector( x, 0, 1, 0 ) ] );
95-
t.strictEqual( isnan( v ), true, 'returns expected value' );
96-
97-
t.end();
98-
});
99-
100-
tape( 'if provided an ndarray containing a single element, the function returns that element', function test( t ) {
101-
var x;
102-
var v;
103-
104-
x = new Float32Array( [ 1.0 ] );
105-
106-
v = smean( [ vector( x, 1, 1, 0 ) ] );
107-
t.strictEqual( v, 1.0, 'returns expected value' );
44+
tape( 'if a native implementation is available, the main export is the native implementation', opts, function test( t ) {
45+
var smean = proxyquire( './../lib', {
46+
'@stdlib/utils/try-require': tryRequire
47+
});
10848

49+
t.strictEqual( smean, mock, 'returns expected value' );
10950
t.end();
110-
});
11151

112-
tape( 'the function supports one-dimensional ndarrays having non-unit strides', function test( t ) {
113-
var x;
114-
var v;
52+
function tryRequire() {
53+
return mock;
54+
}
11555

116-
x = new Float32Array([
117-
1.0, // 0
118-
2.0,
119-
2.0, // 1
120-
-7.0,
121-
-2.0, // 2
122-
3.0,
123-
4.0, // 3
124-
2.0
125-
]);
126-
127-
v = smean( [ vector( x, 4, 2, 0 ) ] );
128-
129-
t.strictEqual( v, 1.25, 'returns expected value' );
130-
t.end();
56+
function mock() {
57+
// Mock...
58+
}
13159
});
13260

133-
tape( 'the function supports one-dimensional ndarrays having negative strides', function test( t ) {
134-
var x;
135-
var v;
61+
tape( 'if a native implementation is not available, the main export is a JavaScript implementation', opts, function test( t ) {
62+
var smean;
63+
var main;
13664

137-
x = new Float32Array([
138-
1.0, // 3
139-
2.0,
140-
2.0, // 2
141-
-7.0,
142-
-2.0, // 1
143-
3.0,
144-
4.0, // 0
145-
2.0
146-
]);
65+
main = require( './../lib/main.js' );
14766

148-
v = smean( [ vector( x, 4, -2, 6 ) ] );
67+
smean = proxyquire( './../lib', {
68+
'@stdlib/utils/try-require': tryRequire
69+
});
14970

150-
t.strictEqual( v, 1.25, 'returns expected value' );
71+
t.strictEqual( smean, main, 'returns expected value' );
15172
t.end();
152-
});
15373

154-
tape( 'the function supports one-dimensional ndarrays having non-zero offsets', function test( t ) {
155-
var x;
156-
var v;
157-
158-
x = new Float32Array([
159-
2.0,
160-
1.0, // 0
161-
2.0,
162-
-2.0, // 1
163-
-2.0,
164-
2.0, // 2
165-
3.0,
166-
4.0 // 3
167-
]);
168-
169-
v = smean( [ vector( x, 4, 2, 1 ) ] );
170-
t.strictEqual( v, 1.25, 'returns expected value' );
171-
172-
t.end();
74+
function tryRequire() {
75+
return new Error( 'Cannot find module' );
76+
}
17377
});
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 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 tape = require( 'tape' );
24+
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
25+
var isPositiveZerof = require( '@stdlib/math/base/assert/is-positive-zerof' );
26+
var Float32Array = require( '@stdlib/array/float32' );
27+
var ndarray = require( '@stdlib/ndarray/base/ctor' );
28+
var smean = require( './../lib/main.js' );
29+
30+
31+
// FUNCTIONS //
32+
33+
/**
34+
* Returns a one-dimensional ndarray.
35+
*
36+
* @private
37+
* @param {Float32Array} buffer - underlying data buffer
38+
* @param {NonNegativeInteger} length - number of indexed elements
39+
* @param {integer} stride - stride length
40+
* @param {NonNegativeInteger} offset - index offset
41+
* @returns {ndarray} one-dimensional ndarray
42+
*/
43+
function vector( buffer, length, stride, offset ) {
44+
return new ndarray( 'float32', buffer, [ length ], [ stride ], offset, 'row-major' );
45+
}
46+
47+
48+
// TESTS //
49+
50+
tape( 'main export is a function', function test( t ) {
51+
t.ok( true, __filename );
52+
t.strictEqual( typeof smean, 'function', 'main export is a function' );
53+
t.end();
54+
});
55+
56+
tape( 'the function has an arity of 1', function test( t ) {
57+
t.strictEqual( smean.length, 1, 'has expected arity' );
58+
t.end();
59+
});
60+
61+
tape( 'the function calculates the arithmetic mean of a one-dimensional ndarray', function test( t ) {
62+
var x;
63+
var v;
64+
65+
x = new Float32Array( [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0 ] );
66+
v = smean( [ vector( x, 6, 1, 0 ) ] );
67+
t.strictEqual( v, 0.5, 'returns expected value' );
68+
69+
x = new Float32Array( [ -4.0, -5.0 ] );
70+
v = smean( [ vector( x, 2, 1, 0 ) ] );
71+
t.strictEqual( v, -4.5, 'returns expected value' );
72+
73+
x = new Float32Array( [ -0.0, 0.0, -0.0 ] );
74+
v = smean( [ vector( x, 3, 1, 0 ) ] );
75+
t.strictEqual( isPositiveZerof( v ), true, 'returns expected value' );
76+
77+
x = new Float32Array( [ NaN ] );
78+
v = smean( [ vector( x, 1, 1, 0 ) ] );
79+
t.strictEqual( isnanf( v ), true, 'returns expected value' );
80+
81+
x = new Float32Array( [ NaN, NaN ] );
82+
v = smean( [ vector( x, 2, 1, 0 ) ] );
83+
t.strictEqual( isnanf( v ), true, 'returns expected value' );
84+
85+
t.end();
86+
});
87+
88+
tape( 'if provided an empty ndarray, the function returns `NaN`', function test( t ) {
89+
var x;
90+
var v;
91+
92+
x = new Float32Array( [] );
93+
94+
v = smean( [ vector( x, 0, 1, 0 ) ] );
95+
t.strictEqual( isnanf( v ), true, 'returns expected value' );
96+
97+
t.end();
98+
});
99+
100+
tape( 'if provided an ndarray containing a single element, the function returns that element', function test( t ) {
101+
var x;
102+
var v;
103+
104+
x = new Float32Array( [ 1.0 ] );
105+
106+
v = smean( [ vector( x, 1, 1, 0 ) ] );
107+
t.strictEqual( v, 1.0, 'returns expected value' );
108+
109+
t.end();
110+
});
111+
112+
tape( 'the function supports one-dimensional ndarrays having non-unit strides', function test( t ) {
113+
var x;
114+
var v;
115+
116+
x = new Float32Array([
117+
1.0, // 0
118+
2.0,
119+
2.0, // 1
120+
-7.0,
121+
-2.0, // 2
122+
3.0,
123+
4.0, // 3
124+
2.0
125+
]);
126+
127+
v = smean( [ vector( x, 4, 2, 0 ) ] );
128+
129+
t.strictEqual( v, 1.25, 'returns expected value' );
130+
t.end();
131+
});
132+
133+
tape( 'the function supports one-dimensional ndarrays having negative strides', function test( t ) {
134+
var x;
135+
var v;
136+
137+
x = new Float32Array([
138+
1.0, // 3
139+
2.0,
140+
2.0, // 2
141+
-7.0,
142+
-2.0, // 1
143+
3.0,
144+
4.0, // 0
145+
2.0
146+
]);
147+
148+
v = smean( [ vector( x, 4, -2, 6 ) ] );
149+
150+
t.strictEqual( v, 1.25, 'returns expected value' );
151+
t.end();
152+
});
153+
154+
tape( 'the function supports one-dimensional ndarrays having non-zero offsets', function test( t ) {
155+
var x;
156+
var v;
157+
158+
x = new Float32Array([
159+
2.0,
160+
1.0, // 0
161+
2.0,
162+
-2.0, // 1
163+
-2.0,
164+
2.0, // 2
165+
3.0,
166+
4.0 // 3
167+
]);
168+
169+
v = smean( [ vector( x, 4, 2, 1 ) ] );
170+
t.strictEqual( v, 1.25, 'returns expected value' );
171+
172+
t.end();
173+
});

0 commit comments

Comments
 (0)