Skip to content

Commit

Permalink
[UPDATE] lib, tests, examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
kgryte committed Dec 8, 2014
1 parent 5d3044d commit 72e4d84
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 22 deletions.
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mstdev
Moving Sample Standard Deviation
===
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Dependencies][dependencies-image]][dependencies-url]

> Computes a moving sample standard deviation over a numeric array.
> Computes a moving (sliding window) sample standard deviation over a numeric array.

## Installation
Expand All @@ -19,18 +19,39 @@ For use in the browser, use [browserify](https://github.com/substack/node-browse
To use the module,

``` javascript
var foo = require( 'compute-mstdev' );
var mstdev = require( 'compute-mstdev' );
```

#### foo( arr )
#### mstdev( arr, window )

What does this function do?
Slides a `window` over a numeric `array` to compute a moving sample standard deviation.

``` javascript
var data = [ 1, 5, 0, 10, 2 ];

var arr = mstdev( data, 3 );
// returns [ ~2.6, 5, ~5.3 ]
```

Note: the returned `array` has length `L - W + 1`, where `L` is the length of the input `array` and `W` is the `window` size.


## Examples

``` javascript
var foo = require( 'compute-mstdev' );
var mstdev = require( 'compute-mstdev' );

// Simulate some data...
var data = new Array( 50 );

for ( var i = 0; i < data.length; i++ ) {
data[ i ] = Math.random() * 100;
}

// Compute the moving sample standard deviation:
var arr = mstdev( data, 7 );

console.log( arr.join( '\n' ) );
```

To run the example code from the top-level application directory,
Expand Down
14 changes: 13 additions & 1 deletion examples/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
'use strict';

var module = require( './../lib' );
var mstdev = require( './../lib' );

// Simulate some data...
var data = new Array( 50 );

for ( var i = 0; i < data.length; i++ ) {
data[ i ] = Math.random() * 100;
}

// Compute the moving sample standard deviation:
var arr = mstdev( data, 7 );

console.log( arr.join( '\n' ) );
73 changes: 62 additions & 11 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,73 @@

'use strict';

// MODULES //

// var module_alias = require( 'module_name' );


// FUNCTIONS //
// MOVING SAMPLE STANDARD DEVIATION //

/**
* FUNCTION: foo()
* {{ foo description }}.
* FUNCTION: mstdev( arr, window )
* Computes a moving sample standard deviation over a numeric array.
*
* @param {Array} arr - array of data values
* @param {Number} window - size of moving window
* @returns {Array} array of sample standard deviation values
*/
function foo() {
function mstdev( arr, W ) {
if ( !Array.isArray( arr ) ) {
throw new TypeError( 'mstdev()::invalid input argument. Must provide an array.' );
}
if ( typeof W !== 'number' || W !== W ) {
throw new TypeError( 'mstdev()::invalid input argument. Window must be numeric.' );
}
if ( (W%1) !== 0 || W < 1 ) {
throw new TypeError( 'mstdev()::invalid input argument. Window must be a positive integer.' );
}
if ( W > arr.length ) {
throw new TypeError( 'mstdev()::invalid input argument. Window cannot exceed the array length.' );
}
var len = arr.length,
out = new Array( len-W+1 ),
n = W - 1,
mu = 0,
M2 = 0,
delta,
x1,
x2,
d1,
d2,
i, j;

if ( W === 1 ) {
for ( i = 0; i < out.length; i++ ) {
out[ i ] = 0;
}
return out;
}

// Compute the sample standard deviation for the first window...
for ( i = 0; i < W; i++ ) {
x1 = arr[ i ];
delta = x1 - mu;
mu += delta / (i+1);
M2 += delta * (x1 - mu);
}
out[ 0 ] = Math.sqrt( M2 / n );

} // end FUNCTION foo()
// Compute the remaining sample standard deviations...
for ( j = W; j < len; j++ ) {
i = j - W;
x1 = arr[ i ];
x2 = arr[ j ];
delta = x2 - x1;
d1 = x1 - mu;
mu += delta / W;
d2 = x2 - mu;
M2 += delta * (d1+d2);
out[ i+1 ] = Math.sqrt( M2 / n );
}
return out;
} // end FUNCTION mstdev()


// EXPORTS //

module.exports = foo;
module.exports = mstdev;
18 changes: 17 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,23 @@
"keywords": [
"compute.io",
"compute",
"computation"
"computation",
"mathematics",
"math",
"statistics",
"stats",
"timeseries",
"arithmetic",
"variance",
"sample variance",
"stdev",
"standard deviation",
"sample standard deviation",
"moving",
"window",
"array",
"dispersion",
"sliding"
],
"bugs": {
"url": "https://github.com/compute-io/mstdev/issues"
Expand Down
90 changes: 87 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global describe, it, require */
'use strict';

// MODULES //
Expand All @@ -6,7 +7,7 @@ var // Expectation library:
chai = require( 'chai' ),

// Module to be tested:
lib = require( './../lib' );
mstdev = require( './../lib' );


// VARIABLES //
Expand All @@ -20,9 +21,92 @@ var expect = chai.expect,
describe( 'compute-mstdev', function tests() {

it( 'should export a function', function test() {
expect( lib ).to.be.a( 'function' );
expect( mstdev ).to.be.a( 'function' );
});

it( 'should do something' );
it( 'should throw an error if provided a non-array', function test() {
var values = [
'5',
5,
true,
undefined,
null,
NaN,
function(){},
{}
];

for ( var i = 0; i < values.length; i++ ) {
expect( badValue( values[i] ) ).to.throw( TypeError );
}
function badValue( value ) {
return function() {
mstdev( value , 3 );
};
}
});

it( 'should throw an error if provided a window size which is not a positive integer', function test() {
var values = [
'5',
2.7,
-3,
true,
undefined,
null,
NaN,
function(){},
{},
[]
];

for ( var i = 0; i < values.length; i++ ) {
expect( badValue( values[i] ) ).to.throw( TypeError );
}
function badValue( value ) {
return function() {
mstdev( [], value );
};
}
});

it( 'should throw an error if the window size is greater than the array size', function test() {
var data = [ 1, 2, 3 ];

expect( foo ).to.throw( TypeError );

function foo() {
mstdev( data, data.length+1 );
}
});

it( 'should return an array of zeros if provided a window size equal to 1', function test() {
var data, expected, actual;

data = [ 1, 2, 3 ];
expected = [ 0, 0, 0 ];
actual = mstdev( data, 1 );

assert.deepEqual( actual, expected );
});

it( 'should compute a moving sample standard deviation', function test() {
var data, actual, expected, W;

// Set the window size:
W = 3;

// Simulate some data...
data = [ 2, 1, 3, 5, 7, 0, 2];

// Expected values:
expected = [ 1, 2, 2, Math.sqrt(13), Math.sqrt(13) ];

// Actual values:
actual = mstdev( data , W );

assert.strictEqual( actual.length, data.length-W+1 );
assert.deepEqual( actual, expected );
});

});

0 comments on commit 72e4d84

Please sign in to comment.