Skip to content

Commit 08c6d20

Browse files
committed
Add two-sample variance test
1 parent bb1ae26 commit 08c6d20

File tree

18 files changed

+1888
-0
lines changed

18 files changed

+1888
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2018 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Two-sample F-test
22+
23+
> Two-sample F-test for equal variances.
24+
25+
<section class="usage">
26+
27+
## Usage
28+
29+
```javascript
30+
var vartest = require( '@stdlib/stats/vartest' );
31+
```
32+
33+
#### vartest( x, y\[, opts] )
34+
35+
By default, the function performs a two-sample F-test for the null hypothesis that the data in [arrays][mdn-array] or [typed arrays][mdn-typed-array] `x` and `y` is independently drawn from normal distributions with _equal_ variances.
36+
37+
```javascript
38+
var x = [ 610, 610, 550, 590, 565, 570 ];
39+
var y = [ 560, 550, 580, 550, 560, 590, 550, 590 ];
40+
41+
var out = vartest( x, y );
42+
/* returns
43+
{
44+
'rejected': false,
45+
'pValue': ~0.399,
46+
'statistic': ~1.976,
47+
'ci': [ ~0.374, ~13.542 ],
48+
// ...
49+
}
50+
*/
51+
```
52+
53+
The returned object comes with a `.print()` method which when invoked will print a formatted output of the results of the hypothesis test.
54+
55+
<!-- run-disable -->
56+
57+
```javascript
58+
console.log( out.print() );
59+
/* e.g., =>
60+
F test for comparing two variances
61+
62+
Alternative hypothesis: True ratio in variances is not equal to 1
63+
64+
pValue: 0.3992
65+
statistic: 1.976
66+
variance of x: 617.5 (df of x: 5)
67+
variance of y: 312.5 (df of y: 7)
68+
95% confidence interval: [0.3739,13.5417]
69+
70+
Test Decision: Fail to reject null in favor of alternative at 5% significance level
71+
*/
72+
```
73+
74+
The function accepts the following `options`:
75+
76+
- **alpha**: `number` in the interval `[0,1]` giving the significance level of the hypothesis test. Default: `0.05`.
77+
- **alternative**: Either `two-sided`, `less` or `greater`. Indicates whether the alternative hypothesis is that the true ratio of variances is greater than one (`greater`), smaller than one (`less`), or that the variances are the same (`two-sided`). Default: `two-sided`.
78+
- **difference**: `number` denoting the difference in means under the null hypothesis. Default: `0`.
79+
80+
By default, the hypothesis test is carried out at a significance level of `0.05`. To choose a different significance level, set the `alpha` option.
81+
82+
```javascript
83+
var x = [ 610, 610, 550, 590, 565, 570, 500, 650, 500, 650 ];
84+
var y = [ 560, 550, 580, 550, 560, 590, 550, 590 ];
85+
86+
var out = vartest( x, y, {
87+
'alpha': 0.01
88+
});
89+
var table = out.print();
90+
/* e.g., returns
91+
F test for comparing two variances
92+
93+
Alternative hypothesis: True ratio in variances is not equal to 1
94+
95+
pValue: 0.0081
96+
statistic: 9.1458
97+
variance of x: 2858.0556 (df of x: 9)
98+
variance of y: 312.5 (df of y: 7)
99+
90% confidence interval: [2.4875,30.1147]
100+
101+
Test Decision: Reject null in favor of alternative at 1% significance level
102+
103+
Exited with status 0
104+
*/
105+
```
106+
107+
By default, a two-sided test is performed. To perform either of the one-sided tests, set the `alternative` option to `less` or `greater`.
108+
109+
```javascript
110+
var x = [ 610, 610, 550, 590, 565, 570, 500, 650, 500, 650 ];
111+
var y = [ 560, 550, 580, 550, 560, 590, 550, 590 ];
112+
113+
var out = vartest( x, y, {
114+
'alternative': 'less'
115+
});
116+
var table = out.print();
117+
/* e.g., returns
118+
Alternative hypothesis: True ratio in variances is less than 1
119+
120+
pValue: 0.996
121+
statistic: 9.1458
122+
variance of x: 2858.0556 (df of x: 9)
123+
variance of y: 312.5 (df of y: 7)
124+
95% confidence interval: [0,30.1147]
125+
126+
Test Decision: Fail to reject null in favor of alternative at 5% significance level
127+
128+
Exited with status 0
129+
*/
130+
131+
out = vartest( x, y, {
132+
'alternative': 'greater'
133+
});
134+
table = out.print();
135+
/* e.g., returns
136+
Alternative hypothesis: True ratio in variances is greater than 1
137+
138+
pValue: 0.004
139+
statistic: 9.1458
140+
variance of x: 2858.0556 (df of x: 9)
141+
variance of y: 312.5 (df of y: 7)
142+
95% confidence interval: [2.4875,Infinity]
143+
144+
Test Decision: Reject null in favor of alternative at 5% significance level
145+
146+
Exited with status 0
147+
*/
148+
```
149+
150+
To test whether the ratio in the population variances is equal to some other value than `1`, set the `ratio` option.
151+
152+
```javascript
153+
var x = [ 610, 610, 550, 590, 565, 570, 500, 650, 500, 650 ];
154+
var y = [ 560, 550, 580, 550, 560, 590, 550, 590 ];
155+
156+
var out = vartest( x, y, {
157+
'ratio': 10.0
158+
});
159+
/* e.g., returns
160+
{
161+
'rejected': false,
162+
'pValue': ~0.879,
163+
'statistic': ~-0.915,
164+
'ci': [ ~1.896, ~38.385 ],
165+
// ...
166+
}
167+
*/
168+
169+
var table = out.print();
170+
/* e.g., returns
171+
F test for comparing two variances
172+
173+
Alternative hypothesis: True ratio in variances is not equal to 10
174+
175+
pValue: 0.8794
176+
statistic: 0.9146
177+
variance of x: 2858.0556 (df of x: 9)
178+
variance of y: 312.5 (df of y: 7)
179+
95% confidence interval: [1.8962,38.3853]
180+
181+
Test Decision: Fail to reject null in favor of alternative at 5% significance level
182+
*/
183+
```
184+
185+
</section>
186+
187+
<!-- /.usage -->
188+
189+
<section class="examples">
190+
191+
## Examples
192+
193+
<!-- eslint no-undef: "error" -->
194+
195+
```javascript
196+
var rnorm = require( '@stdlib/random/base/normal' );
197+
var vartest = require( '@stdlib/stats/vartest' );
198+
199+
var table;
200+
var out;
201+
var x;
202+
var y;
203+
var i;
204+
205+
x = new Array( 60 );
206+
for ( i = 0; i < x.length; i++ ) {
207+
x[ i ] = rnorm( 2.0, 1.0 );
208+
}
209+
y = new Array( 40 );
210+
for ( i = 0; i < y.length; i++ ) {
211+
y[ i ] = rnorm( 1.0, 2.0 );
212+
}
213+
214+
// Test whether the variances of `x` and `y` are the same:
215+
out = vartest( x, y );
216+
table = out.print();
217+
/* e.g., returns
218+
F test for comparing two variances
219+
220+
Alternative hypothesis: True ratio in variances is not equal to 1
221+
222+
pValue: 0
223+
statistic: 0.1717
224+
variance of x: 0.6406 (df of x: 60)
225+
variance of y: 3.7306 (df of y: 40)
226+
95% confidence interval: [0.0953,0.2995]
227+
228+
Test Decision: Reject null in favor of alternative at 5% significance level
229+
*/
230+
231+
// Test whether the variance of `x` is one fourth of the variance of `y`:
232+
out = vartest( x, y, {
233+
'ratio': 0.25
234+
});
235+
table = out.print();
236+
/* e.g., returns
237+
F test for comparing two variances
238+
239+
Alternative hypothesis: True ratio in variances is not equal to 0.25
240+
241+
pValue: 0.1847
242+
statistic: 0.6869
243+
variance of x: 0.6406 (df of x: 60)
244+
variance of y: 3.7306 (df of y: 40)
245+
95% confidence interval: [0.0953,0.2995]
246+
247+
Test Decision: Fail to reject null in favor of alternative at 5% significance level
248+
*/
249+
```
250+
251+
</section>
252+
253+
<!-- /.examples -->
254+
255+
<section class="links">
256+
257+
[mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
258+
259+
[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
260+
261+
</section>
262+
263+
<!-- /.links -->
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2018 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 isObject = require( '@stdlib/assert/is-object' );
26+
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
27+
var pkg = require( './../package.json' ).name;
28+
var vartest = require( './../lib' );
29+
30+
31+
// MAIN //
32+
33+
bench( pkg, function benchmark( b ) {
34+
var result;
35+
var y;
36+
var x;
37+
var i;
38+
39+
x = new Array( 100 );
40+
for ( i = 0; i < x.length; i++ ) {
41+
x[ i ] = ( randu()*2.0 ) + 1.0;
42+
}
43+
44+
y = new Array( 120 );
45+
for ( i = 0; i < y.length; i++ ) {
46+
y[ i ] = ( randu()*4.0 ) + 1.0;
47+
}
48+
49+
b.tic();
50+
for ( i = 0; i < b.iterations; i++ ) {
51+
x[ i % x.length ] = randu()*2.0;
52+
result = vartest( x, y );
53+
if ( typeof result !== 'object' ) {
54+
b.fail( 'should return an object' );
55+
}
56+
}
57+
b.toc();
58+
if ( !isObject( result ) ) {
59+
b.fail( 'should return an object' );
60+
}
61+
b.pass( 'benchmark finished' );
62+
b.end();
63+
});
64+
65+
bench( pkg+'::one-sided', function benchmark( b ) {
66+
var result;
67+
var opts;
68+
var y;
69+
var x;
70+
var i;
71+
72+
x = new Array( 100 );
73+
for ( i = 0; i < x.length; i++ ) {
74+
x[ i ] = ( randu()*2.0 ) + 1.0;
75+
}
76+
y = new Array( 120 );
77+
for ( i = 0; i < y.length; i++ ) {
78+
y[ i ] = ( randu()*2.0 ) + 1.0;
79+
}
80+
opts = {
81+
'alternative': 'less'
82+
};
83+
84+
b.tic();
85+
for ( i = 0; i < b.iterations; i++ ) {
86+
x[ i % x.length ] = randu()*2.0;
87+
result = vartest( x, y, opts );
88+
if ( typeof result !== 'object' ) {
89+
b.fail( 'should return an object' );
90+
}
91+
}
92+
b.toc();
93+
if ( !isObject( result ) ) {
94+
b.fail( 'should return an object' );
95+
}
96+
b.pass( 'benchmark finished' );
97+
b.end();
98+
});
99+
100+
bench( pkg+':print', function benchmark( b ) {
101+
var numdigits;
102+
var result;
103+
var output;
104+
var y;
105+
var x;
106+
var i;
107+
108+
x = new Array( 100 );
109+
for ( i = 0; i < x.length; i++ ) {
110+
x[ i ] = ( randu()*2.0 ) + 1.0;
111+
}
112+
y = new Array( 120 );
113+
for ( i = 0; i < y.length; i++ ) {
114+
y[ i ] = ( randu()*2.0 ) + 1.0;
115+
}
116+
result = vartest( x, y );
117+
118+
b.tic();
119+
for ( i = 0; i < b.iterations; i++ ) {
120+
numdigits = ( i % 8 ) + 1;
121+
output = result.print({
122+
'numdigits': numdigits
123+
});
124+
if ( typeof output !== 'string' ) {
125+
b.fail( 'should return a string' );
126+
}
127+
}
128+
b.toc();
129+
if ( !isString( output ) ) {
130+
b.fail( 'should return a string' );
131+
}
132+
b.pass( 'benchmark finished' );
133+
b.end();
134+
});

0 commit comments

Comments
 (0)