From 81fec670ba136704c5ed9881b620d4606810d9d0 Mon Sep 17 00:00:00 2001 From: Fredrick Galoso Date: Sun, 21 Apr 2013 21:39:40 -0500 Subject: [PATCH] Gauss 0.2.8 - Collection.unique, return a set of unique values 97b8db8d01ea708208687d5aa1a3155fb8bb51a1 - Collection.split, binomial cluster function 242384e06e5efbcb35d3b3416c34dbe8310c8974 - Fix object extension and refactoring https://github.com/wayoutmind/gauss/issues/14 - Power/general mean 8628696a103cc238506f541ebf2c018ff4ce8d00 - Sample statistics and increased test coverage --- CONTRIBUTORS.md | 2 +- LICENSE | 2 +- README.md | 121 +++++++++++++++++++++++++++++--------------- bin/gauss | 4 +- gauss.min.js | 2 +- lib/gauss.js | 4 +- lib/vector.js | 18 +++++++ package.json | 4 +- test/vector.test.js | 12 +++++ 9 files changed, 120 insertions(+), 49 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 5f53dd2..8e84e04 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -2,7 +2,7 @@ The awesome people that have contributed to Gauss. #Author -Fredrick Galoso - Stackd +Fredrick Galoso #Contributors Philip Tellis - Yahoo! diff --git a/LICENSE b/LICENSE index 767f3b5..9c85750 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Gauss: JavaScript statistics, analytics, and set library - Node.js and web browser ready -Copyright (c) 2012 Fredrick Galoso https://stackd.com/ +Copyright (c) 2013 Fredrick Galoso http://fredrickgaloso.me/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index 6f3a625..1b5a4e8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ both on Node.js and within the web browser. ## License MIT/X11 - See [LICENSE][2] -[2]: http://github.com/stackd/gauss/blob/master/LICENSE +[2]: http://github.com/wayoutmind/gauss/blob/master/LICENSE ## Getting started @@ -39,7 +39,7 @@ To invoke the tests: ### Using Gauss within a web browser -Gauss requires support for ECMAScript 5 `Object.defineProperties`. Compatibility is listed [here](http://kangax.github.com/es5-compat-table/). Download and include [gauss.min.js](https://raw.github.com/stackd/gauss/master/gauss.min.js): +Gauss requires support for ECMAScript 5 `Object.defineProperties`. Compatibility is listed [here](http://kangax.github.com/es5-compat-table/). Download and include [gauss.min.js](https://raw.github.com/wayoutmind/gauss/master/gauss.min.js): ``` html @@ -52,44 +52,9 @@ Gauss requires support for ECMAScript 5 `Object.defineProperties`. Compatibility ``` -### Using the REPL console - -To experiment with Gauss or to quickly start a Node.js command-line environment for number crunching, Gauss ships with a lightweight REPL (Read–eval–print loop). Start the REPL with `npm start` within the source directory, or `gauss` if installed globally (via `npm install -g gauss`). - -For example, using the `help()` function and analyzing a data file from the Gauss REPL: - -``` javascript -$ gauss -gauss> help() -Gauss 0.2.7 - /* https://github.com/stackd/gauss#api */ - Functions: print, inspect, cwd, clear, install, uninstall, help - Usage: - var set = new Vector(1, 2, 3); - var times = new gauss.TimeSeries(); -{ version: '0.2.7', - Collection: [Function], - Vector: [Function], - TimeSeries: [Function] } -gauss> var fs = require('fs'); -gauss> var data = fs.readFileSync('data.txt').toString(); -gauss> data = data.split('\n'); -[ '8', - '6', - '7', - '5', - '3', - '0', - '9' ] -gauss> data = data.map(function(line) { return parseInt(line) }); -gauss> var set = new Vector(data); -gauss> set.mean() -5.428571428571429 -``` - ## API -Gauss has methods for univariate (Vector) and time series (TimeSeries) analysis. We're constantly working on adding more functions, adding multivariate statistics, and we encourage additions to the library. Accuracy is a primary concern. If Gauss is returning incorrect results, [please submit an issue](https://github.com/stackd/gauss/issues) and/or [submit a patch](https://github.com/stackd/gauss#fork_box)! +Gauss has methods for univariate (Vector) and time series (TimeSeries) analysis. We're constantly working on adding more functions, adding multivariate statistics, and we encourage additions to the library. Accuracy is a primary concern. If Gauss is returning incorrect results, [please submit an issue](https://github.com/wayoutmind/gauss/issues) and/or [submit a patch](https://github.com/wayoutmind/gauss#fork_box)! ### Instantiation @@ -106,7 +71,7 @@ numbers[0] = 2; set[1] = 7; ``` -*Note: To prevent unintended scope/prototype pollution, Gauss versions after 0.2.3 have [removed support for monkey patching](https://github.com/stackd/gauss/issues/6) the native Array data type. +*Note: To prevent unintended scope/prototype pollution, Gauss versions after 0.2.3 have [removed support for monkey patching](https://github.com/wayoutmind/gauss/issues/6) the native Array data type. Use the .toArray() method of any Gauss object to a convert to a vanilla Array. Gauss adds a toVector() convenience method to the Array prototype to facilitate converting to Vectors.* ### Callbacks and method chaining @@ -206,7 +171,7 @@ people.findOne({ lastname: 'Smith' }); .split(predicate[, callback]) -Returns a Collection split by a condition. +Returns a Collection split by a condition (binomial cluster). ``` javascript Collection(1, 2, 3, 4).split(function(e) { return e % 2 === 0 }); @@ -261,6 +226,17 @@ var numbers = new Collection(1, 2, 3).append([1, 2, 3]); > [1, 2, 3, 1, 2, 3] ``` +#### Collection.unique + + .unique(callback) + +Return a Collection with unique values. + +``` javascript +var numbers = new Collection(1, 2, 3, 3, 4, 4).unique(); +> [1, 2, 3, 4] +``` + ### Vector #### Vector.min @@ -343,6 +319,21 @@ Returns the harmonic mean. Returns the quadratic mean (RMS, root mean square). +#### Vector.pmean + + .pmean(p, callback) + +Returns the power/generalized mean given an order or power *p*. + +```javascript +// p = -1, harmonic mean +set.pmean(-1); +// p = 1, arithmetic mean +set.pmean(1); +// p = 2, quadratic mean +set.pmean(2); +``` + #### Vector.median .median(callback) @@ -559,6 +550,21 @@ Returns a copy of the data set. Returns another instance of the Vector object and data. +### Sample + +By default, `Vector` calculates values against the population `n`. However, sample statistics functions on `n - 1` are available by using the `sample` modifier for the following functions: + +``` javascript +Vector().sample +{ mean: [Function], + gmean: [Function], + hmean: [Function], + qmean: [Function], + pmean: [Function], + variance: [Function], + stdev: [Function] } +``` + ### Math `Vector` supports applying all the [Math](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Math#Methods) object methods to an entire Vector set of numbers. @@ -592,3 +598,38 @@ Returns a Vector of the times. .values(callback) Returns a Vector of the time series values. + +### Using the REPL console + +To experiment with Gauss or to quickly start a Node.js command-line environment for number crunching, Gauss ships with a lightweight REPL (Read–eval–print loop). Start the REPL with `npm start` within the source directory, or `gauss` if installed globally (via `npm install -g gauss`). + +For example, using the `help()` function and analyzing a data file from the Gauss REPL: + +``` javascript +$ gauss +gauss> help() +Gauss 0.2.8 + /* https://github.com/wayoutmind/gauss#api */ + Functions: print, inspect, cwd, clear, install, uninstall, help + Usage: + var set = new Vector(1, 2, 3); + var times = new gauss.TimeSeries(); +{ version: '0.2.8', + Collection: [Function], + Vector: [Function], + TimeSeries: [Function] } +gauss> var fs = require('fs'); +gauss> var data = fs.readFileSync('data.txt').toString(); +gauss> data = data.split('\n'); +[ '8', + '6', + '7', + '5', + '3', + '0', + '9' ] +gauss> data = data.map(function(line) { return parseInt(line) }); +gauss> var set = new Vector(data); +gauss> set.mean() +5.428571428571429 +``` diff --git a/bin/gauss b/bin/gauss index 57bd3e0..b8d0ad5 100755 --- a/bin/gauss +++ b/bin/gauss @@ -9,7 +9,7 @@ _/_/ Gauss: JavaScript statistics, analytics, and set library - Node.js and web browser ready -Copyright (c) 2012 Fredrick Galoso https://stackd.com/ +Copyright (c) 2013 Fredrick Galoso http://fredrickgaloso.me/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -64,7 +64,7 @@ session.context.uninstall = function(name) { session.context.help = function(command) { var banner = 'Gauss '+ gauss.version +'\n \ - /* https://github.com/stackd/gauss#api */ \n \ + /* https://github.com/wayoutmind/gauss#api */ \n \ Functions: print, inspect, cwd, clear, install, uninstall, help\n \ Usage:\n \ var set = new Vector(1, 2, 3);\n \ diff --git a/gauss.min.js b/gauss.min.js index 5091254..1be7ffe 100644 --- a/gauss.min.js +++ b/gauss.min.js @@ -1 +1 @@ -(function(){var Collection=function(values){"use strict";var collection=Array.isArray(values)?values:Array.prototype.slice.call(arguments);return 0===Array.prototype.slice.call(arguments).length&&(collection=[]),Object.defineProperties(collection,{indexOf:{value:function(element,callback){for(var index=-1,i=0;this.length>i;i++)if(this[i]===element){index=i;break}return callback?callback(index):index},writable:!0,enumerable:!1},indexBy:{value:function(predicate,callback){for(var index=-1,i=0;this.length>i;i++)if(predicate(this[i])){index=i;break}return callback?callback(index):index},writable:!0,enumerable:!1},indicesOf:{value:function(element,callback){var start=this.indexOf(element),end=this.lastIndexOf(element),indices=new Collection;if(start===end)indices.push(start);else for(var i=start;end>=i;i++)this[i]===element&&indices.push(i);return callback?callback(indices):indices},writable:!0,enumerable:!1},indicesBy:{value:function(predicate,callback){var start=0,end=this.length-1,indices=new Collection;if(start===end)indices.push(start);else for(var i=start;end>=i;i++)predicate(this[i])&&indices.push(i);return callback?callback(indices):indices},writable:!0,enumerable:!1},lastIndexBy:{value:function(predicate,callback){for(var index=-1,i=this.length-1;i>=0;i--)if(predicate(this[i])){index=i;break}return callback?callback(index):index},writable:!0,enumerable:!1},find:{value:function(predicate,callback){var results=new Collection;if("object"==typeof predicate)for(var i=0;this.length>i;i++){var conditions=[];for(var key in predicate)conditions.push(predicate[key]===this[i][key]);conditions.every(function(e){return e===!0})&&results.push(this[i])}else for(var i=0;this.length>i;i++)predicate(this[i])&&results.push(this[i]);return callback?callback(results):results},writable:!0,enumerable:!1},findOne:{value:function(predicate,callback){var result;if("object"==typeof predicate)for(var i=0;this.length>i;i++){var conditions=[];for(var key in predicate)conditions.push(predicate[key]===this[i][key]);if(conditions.every(function(e){return e===!0})){result=this[i];break}}else for(var i=0;this.length>i;i++)if(predicate(this[i])){result=this[i];break}return callback?callback(result):result},writable:!0,enumerable:!1},mode:{value:function(callback){for(var map={},count=1,modes=new Collection,i=0;this.length>i;i++){var e=this[i];null==map[e]?map[e]=1:map[e]++,map[e]>count?(modes=new Collection(e),count=map[e]):map[e]==count&&(modes.push(e),count=map[e])}return 1===modes.length&&(modes=modes[0]),callback?callback(modes):modes},writable:!0,enumerable:!1},frequency:{value:function(element,callback){var freq=0;if(-1!==this.indexOf(element)){var buffer=this.copy().sort();freq=buffer.lastIndexOf(element)-buffer.indexOf(element)+1}return callback?callback(freq):freq},writable:!0,enumerable:!1},distribution:{value:function(format,callback){for(var array=this.copy().sort(),distribution={},i=0;array.length>i;)distribution[array[i]]="relative"===format?array.frequency(array[i])/array.length:array.frequency(array[i]),i=array.lastIndexOf(array[i])+1;return callback?callback(distribution):distribution},writable:!0,enumerable:!1},append:{value:function(that,callback){return collection=this.push.apply(this,that),callback?callback(collection):collection},writable:!0,enumerable:!1},equal:{value:function(that,callback){var equality=!(that>this||this>that);return callback?callback(equality):equality},writable:!0,enumerable:!1},clone:{value:function(callback){var object=Array.isArray(this)?[]:{};for(var i in this)"clone"!==i&&(object[i]=this[i]&&"object"==typeof this[i]?this[i].clone():this[i]);return callback?callback(object):object},writable:!0,enumerable:!1},copy:{value:function(callback){var copy=new Collection(this.slice());return callback?callback(copy):copy},writable:!0,enumerable:!1},toArray:{value:function(callback){var array=Array.prototype.slice.call(this);return callback?callback(array):array},writable:!0,enumerable:!1},concat:{value:function(){var args=Array.prototype.slice.call(arguments),end=args[args.length-1];return"function"==typeof end?"number"!=typeof args[0]?end(new Collection(this.toArray().concat(args[0]))):end(new Collection(this.toArray().concat(args.slice(0,args.length-1)))):"number"!=typeof args[0]?new Collection(this.toArray().concat(args[0])):new Collection(this.toArray().concat(args))},writable:!0,enumerable:!1},slice:{value:function(begin,end,callback){var args=Array.prototype.slice.call(arguments);return 3===args.length?callback(new Collection(this.toArray().slice(begin,end))):2===args.length?"function"==typeof args[1]?callback(new Collection(this.toArray().slice(begin))):new Collection(this.toArray().slice(begin,end)):1===args.length?new Collection(this.toArray().slice(begin)):new Collection(this.toArray().slice())},writable:!0,enumerable:!1},split:{value:function(predicate,callback){var split=new Collection;return split.push(this.toArray().filter(function(e){return!predicate(e)})),split.push(this.toArray().filter(predicate)),callback?callback(split):split},writable:!0,enumerable:!1},unique:{value:function(callback){for(var array=this.copy().sort(),unique=[],i=0;array.length>i;)unique.push(array[i]),i=array.lastIndexOf(array[i])+1;return callback?callback(unique):unique},writable:!0,enumerable:!1},filter:{value:function(callback,next){var filter=new Collection(this.toArray().filter(callback));return next?next(filter):filter},writable:!0,enumerable:!1},every:{value:function(callback,next){var every=this.toArray().every(callback);return next?next(every):every},writable:!0,enumerable:!1},map:{value:function(callback,next){var map=new Collection(this.toArray().map(callback));return next?next(map):map},writable:!0,enumerable:!1},some:{value:function(callback,next){var some=this.toArray().some(callback);return next?next(some):some},writable:!0,enumerable:!1},reduce:{value:function(callback,initialValue,next){var args=Array.prototype.slice.call(arguments);return 3===args.length?next(this.toArray().reduce(callback,initialValue)):2===args.length?"function"==typeof args[1]?next(this.toArray().reduce(callback)):this.toArray().reduce(callback,initialValue):this.toArray().reduce(callback)},writable:!0,enumerable:!1},reduceRight:{value:function(callback,initialValue,next){var args=Array.prototype.slice.call(arguments);return 3===args.length?next(this.toArray().reduceRight(callback,initialValue)):2===args.length?"function"==typeof args[1]?next(this.toArray().reduceRight(callback)):this.toArray().reduceRight(callback,initialValue):this.toArray().reduceRight(callback)},writable:!0,enumerable:!1},extend:{value:function(methods,callback){for(var method in methods)Object.defineProperty(this,method,{value:methods[method],writable:!0,enumerable:!1});return callback?callback(this):this},writable:!0,enumerable:!1}}),collection};Array.prototype.toCollection=function(){return new Collection(this)},"undefined"!=typeof window?(window.gauss=window.gauss===void 0?{}:window.gauss,window.gauss.Collection=Collection):exports=module.exports=Collection})();(function(){var Collection="undefined"==typeof window?require("./collection"):window.gauss.Collection;Collection=Collection();var Vector=function(values){"use strict";var vector=Array.isArray(values)?values:Array.prototype.slice.call(arguments);0===Array.prototype.slice.call(arguments).length&&(vector=[]);var cache={sum:0,product:1,variance:0,sample:{variance:0},values:Array.prototype.slice.call(vector)};cache.sync=function(){cache.values=Array.prototype.slice.call(vector)};var asc=function(a,b){return a-b};return Object.defineProperties(vector,{sum:{value:function(callback){var sum=0;if(this.equal(cache.values)&&0!==cache.sum)sum=cache.sum;else{for(var i=0;this.length>i;)sum+=this[i++];cache.sum=sum,cache.sync()}return callback?callback(sum):sum},writable:!0,enumerable:!1},product:{value:function(callback){var product=1;if(this.equal(cache.values)&&1!==cache.product)product=cache.product;else for(var i=0;this.length>i;)product*=this[i++],cache.product=product,cache.sync();return callback?callback(product):product},writable:!0,enumerable:!1},mean:{value:function(callback){var mean=this.sum()/this.length;return callback?callback(mean):mean},writable:!0,enumerable:!1},gmean:{value:function(callback){var gmean=Math.pow(Math.abs(this.product()),1/this.length);return callback?callback(gmean):gmean},writable:!0,enumerable:!1},hmean:{value:function(callback){function reciprocalSum(set){for(var i=0,sum=0;set.length>i;)sum+=1/Math.abs(set[i++]);return sum}var hmean=this.length/reciprocalSum(this);return callback?callback(hmean):hmean},writable:!0,enumerable:!1},qmean:{value:function(callback){var qmean=Math.sqrt(this.pow(2).sum()/this.length);return callback?callback(qmean):qmean},writable:!0,enumerable:!1},pmean:{value:function(p,callback){for(var pmean=0,i=0;this.length>i;)pmean+=Math.pow(this[i++],p);return pmean=Math.pow(pmean/this.length,1/p),callback?callback(pmean):pmean},writable:!0,enumerable:!1},median:{value:function(callback){var buffer=this.copy();buffer.sort(asc);var median=0===this.length%2?(buffer[this.length/2-1]+buffer[this.length/2])/2:buffer[parseInt(this.length/2)];return callback?callback(median):median},writable:!0,enumerable:!1},range:{value:function(callback){var range=this.max()-this.min();return callback?callback(range):range},writable:!0,enumerable:!1},variance:{value:function(callback){var mean=0,variance=0;if(this.equal(cache.values)&&0!==cache.variance)variance=cache.variance;else{for(var i=0;this.length>i;i++){var _mean=mean;mean+=(this[i]-_mean)/(i+1),variance+=(this[i]-_mean)*(this[i]-mean)}variance/=this.length,cache.variance=variance,cache.sync()}return callback?callback(variance):variance},writable:!0,enumerable:!1},stdev:{value:function(percentile,callback){var stdev=0;return percentile?this.density(percentile).stdev():(stdev=Math.sqrt(this.variance()),callback?callback(stdev):stdev)},writable:!0,enumerable:!1},percentile:{value:function(percent,callback){var buffer=this.copy();buffer.sort(asc);var percentile=buffer[0];return percent>0&&(percentile=buffer[Math.floor(this.length*percent)]),callback?callback(percentile):percentile},writable:!0,enumerable:!1},density:{value:function(percent,callback){var slice,buffer=this.copy();if(buffer.sort(asc),1==percent)return buffer;var begin=Math.round(this.length*(.5-percent/2)-1),end=Math.round(this.length*(.5+percent/2)-1);return slice=new Vector(buffer.slice(begin,end)),callback?callback(slice):slice},writable:!0,enumerable:!1},quantile:{value:function(quantity,callback){var buffer=this.copy();buffer.sort(asc);var increment=1/quantity,results=new Vector;if(quantity>this.length)throw new RangeError("Subset quantity is greater than the Vector length");for(var i=increment;1>i;i+=increment){var index=Math.round(buffer.length*i)-1;buffer.length-1>index&&results.push(buffer[index])}return callback?callback(results):results},writable:!0,enumerable:!1},delta:{value:function(callback){for(var delta=new Vector,i=1;this.length>i;i++)delta.push(this[i]-this[i-1]);return callback?callback(delta):delta},writable:!0,enumerable:!1},sma:{value:function(period,callback){var sma;if(1===period)sma=this;else{var sum=new Vector(this.slice(0,period)).sum();sma=new Vector([sum/period]);for(var i=1;this.length-period+1>i;i++)sum+=this[i+period-1]-this[i-1],sma.push(sum/period)}return callback?callback(sma):sma},writable:!0,enumerable:!1},ema:{value:function(options,callback){if("number"==typeof options){var length=options;options={period:length,ratio:function(n){return 2/(n+1)}}}for(var sum=new Vector(this.slice(0,options.period)).sum(),ema=new Vector([sum/options.period]),ratio=options.ratio(options.period),i=1;this.length-options.period+1>i;i++)ema.push(ratio*(this[i+options.period-1]-ema[i-1])+ema[i-1]);return callback?callback(ema):ema},writable:!0,enumerable:!1},sample:{value:{mean:function(callback){var mean=vector.sum()/(vector.length-1);return callback?callback(mean):mean},gmean:function(callback){var gmean=Math.pow(Math.abs(vector.product()),1/(vector.length-1));return callback?callback(gmean):gmean},hmean:function(callback){function reciprocalSum(set){for(var i=0,sum=0;set.length>i;)sum+=1/Math.abs(set[i++]);return sum}var hmean=(vector.length-1)/reciprocalSum(vector);return callback?callback(hmean):hmean},qmean:function(callback){var qmean=Math.sqrt(vector.pow(2).sum()/(vector.length-1));return callback?callback(qmean):qmean},variance:function(callback){var mean=0,variance=0;if(vector.equal(cache.values)&&0!==cache.sample.variance)variance=cache.sample.variance;else{for(var i=0;vector.length>i;i++){var _mean=mean;mean+=(vector[i]-_mean)/(i+1),variance+=(vector[i]-_mean)*(vector[i]-mean)}variance/=vector.length-1,cache.sample.variance=variance,cache.sync()}return callback?callback(variance):variance}},writable:!0,enumerable:!1},max:{value:function(callback){var max=Math.max.apply({},this);return callback?callback(max):max},writable:!0,enumerable:!1},min:{value:function(callback){var min=Math.min.apply({},this);return callback?callback(min):min},writable:!0,enumerable:!1},abs:{value:function(callback){var abs=this.map(Math.abs);return callback?callback(abs):abs},writable:!0,enumerable:!1},acos:{value:function(callback){var acos=this.map(Math.acos);return callback?callback(acos):acos},writable:!0,enumerable:!1},asin:{value:function(callback){var asin=this.map(Math.asin);return callback?callback(asin):asin},writable:!0,enumerable:!1},atan:{value:function(callback){var atan=this.map(Math.atan);return callback?callback(atan):atan},writable:!0,enumerable:!1},ceil:{value:function(callback){var ceil=this.map(Math.ceil);return callback?callback(ceil):ceil},writable:!0,enumerable:!1},cos:{value:function(callback){var cos=this.map(Math.cos);return callback?callback(cos):cos},writable:!0,enumerable:!1},exp:{value:function(callback){var exp=this.map(Math.exp);return callback?callback(exp):exp},writable:!0,enumerable:!1},floor:{value:function(callback){var floor=this.map(Math.floor);return callback?callback(floor):floor},writable:!0,enumerable:!1},log:{value:function(callback){var log=this.map(Math.log);return callback?callback(log):log},writable:!0,enumerable:!1},pow:{value:function(exponent,callback){var pow=this.map(function(x){return Math.pow(x,exponent)});return callback?callback(pow):pow},writable:!0,enumerable:!1},round:{value:function(callback){var round=this.map(Math.round);return callback?callback(round):round},writable:!0,enumerable:!1},sin:{value:function(callback){var sin=this.map(Math.sin);return callback?callback(sin):sin},writable:!0,enumerable:!1},sqrt:{value:function(callback){var sqrt=this.map(Math.sqrt);return callback?callback(sqrt):sqrt},writable:!0,enumerable:!1},tan:{value:function(callback){var tan=this.map(Math.tan);return callback?callback(tan):tan},writable:!0,enumerable:!1},copy:{value:function(callback){var copy=new Vector(this.slice());return callback?callback(copy):copy},writable:!0,enumerable:!1},push:{value:function(){var mean=0===this.length?0:cache.sum/this.length,variance=0===this.length?0:cache.variance*this.length,args=Array.prototype.slice.call(arguments),end=args[args.length-1],length=this.length;if("function"==typeof end){for(var i=0;args.length-1>i;i++){Array.prototype.push.call(this,args[i]),Array.prototype.push.call(cache.values,args[i]);var _mean=mean;mean+=(args[i]-_mean)/this.length,variance+=(args[i]-_mean)*(args[i]-mean),cache.sum+=args[i],cache.product*=args[i],length++}return variance/=this.length,cache.variance=variance,end(length)}for(var i=0;args.length>i;i++){Array.prototype.push.call(this,args[i]),Array.prototype.push.call(cache.values,args[i]);var _mean=mean;mean+=(args[i]-_mean)/this.length,variance+=(args[i]-_mean)*(args[i]-mean),cache.sum+=args[i],cache.product*=args[i],length++}return variance/=this.length,cache.variance=variance,length},writable:!0,enumerable:!1},concat:{value:function(){var args=Array.prototype.slice.call(arguments),end=args[args.length-1];return"function"==typeof end?"number"!=typeof args[0]?end(new Vector(this.toArray().concat(args[0]))):end(new Vector(this.toArray().concat(args.slice(0,args.length-1)))):"number"!=typeof args[0]?new Vector(this.toArray().concat(args[0])):new Vector(this.toArray().concat(args))},writable:!0,enumerable:!1},slice:{value:function(begin,end,callback){var args=Array.prototype.slice.call(arguments);return 3===args.length?callback(new Vector(this.toArray().slice(begin,end))):2===args.length?"function"==typeof args[1]?callback(new Vector(this.toArray().slice(begin))):new Vector(this.toArray().slice(begin,end)):1===args.length?new Vector(this.toArray().slice(begin)):new Vector(this.toArray().slice())},writable:!0,enumerable:!1},filter:{value:function(callback,next){var filter=new Vector(this.toArray().filter(callback));return next?next(filter):filter},writable:!0,enumerable:!1},map:{value:function(callback,next){var map=new Vector(this.toArray().map(callback));return next?next(map):map},writable:!0,enumerable:!1},extend:{value:function(){return Collection.extend.bind(this),Collection.extend.apply(this,arguments)},writable:!0,enumerable:!1}}),vector.extend({indexOf:Collection.indexOf,mode:Collection.mode,frequency:Collection.frequency,distribution:Collection.distribution,every:Collection.every,append:Collection.append,unique:Collection.unique,some:Collection.some,reduce:Collection.reduce,reduceRight:Collection.reduceRight,toArray:Collection.toArray,equal:Collection.equal,clone:Collection.clone}),cache.sum=vector.sum(),cache.product=vector.product(),cache.variance=vector.variance(),vector};Array.prototype.toVector=function(){return new Vector(this)},"undefined"!=typeof window?(window.gauss=window.gauss===void 0?{}:window.gauss,window.gauss.Vector=Vector):exports=module.exports=Vector})();(function(){var Collection="undefined"==typeof window?require("./collection"):window.gauss.Collection;Collection=Collection();var Vector="undefined"==typeof window?require("./vector"):window.gauss.Vector,TimeSeries=function(values){"use strict";var timeseries=2===arguments.length?Array.prototype.slice.call(arguments):values;return 0===Array.prototype.slice.call(arguments).length&&(timeseries=[]),Object.defineProperties(timeseries,{byValue:{value:function(a,b){return a[1]b[1]?1:0},writable:!0,enumerable:!1},byDate:{value:function(a,b){return a[0]b[0]?1:0},writable:!0,enumerable:!1},times:{value:function(callback){var times=new Vector(Array.prototype.map.call(this,function(i){return i[0]}));return callback?callback(times):times},writable:!0,enumerable:!1},values:{value:function(callback){var values=new Vector(Array.prototype.map.call(this,function(i){return i[1]}));return callback?callback(values):values},writable:!0,enumerable:!1},extend:{value:function(){return Collection.extend.bind(this),Collection.extend.apply(this,arguments)},writable:!0,enumerable:!1}}),timeseries.extend({every:Collection.every,append:Collection.append}),timeseries};"undefined"!=typeof window?(window.gauss=window.gauss===void 0?{}:window.gauss,window.gauss.TimeSeries=TimeSeries):exports=module.exports=TimeSeries})(); \ No newline at end of file +(function(){var Collection=function(values){"use strict";var collection=Array.isArray(values)?values:Array.prototype.slice.call(arguments);return 0===Array.prototype.slice.call(arguments).length&&(collection=[]),Object.defineProperties(collection,{indexOf:{value:function(element,callback){for(var index=-1,i=0;this.length>i;i++)if(this[i]===element){index=i;break}return callback?callback(index):index},writable:!0,enumerable:!1},indexBy:{value:function(predicate,callback){for(var index=-1,i=0;this.length>i;i++)if(predicate(this[i])){index=i;break}return callback?callback(index):index},writable:!0,enumerable:!1},indicesOf:{value:function(element,callback){var start=this.indexOf(element),end=this.lastIndexOf(element),indices=new Collection;if(start===end)indices.push(start);else for(var i=start;end>=i;i++)this[i]===element&&indices.push(i);return callback?callback(indices):indices},writable:!0,enumerable:!1},indicesBy:{value:function(predicate,callback){var start=0,end=this.length-1,indices=new Collection;if(start===end)indices.push(start);else for(var i=start;end>=i;i++)predicate(this[i])&&indices.push(i);return callback?callback(indices):indices},writable:!0,enumerable:!1},lastIndexBy:{value:function(predicate,callback){for(var index=-1,i=this.length-1;i>=0;i--)if(predicate(this[i])){index=i;break}return callback?callback(index):index},writable:!0,enumerable:!1},find:{value:function(predicate,callback){var results=new Collection;if("object"==typeof predicate)for(var i=0;this.length>i;i++){var conditions=[];for(var key in predicate)conditions.push(predicate[key]===this[i][key]);conditions.every(function(e){return e===!0})&&results.push(this[i])}else for(var i=0;this.length>i;i++)predicate(this[i])&&results.push(this[i]);return callback?callback(results):results},writable:!0,enumerable:!1},findOne:{value:function(predicate,callback){var result;if("object"==typeof predicate)for(var i=0;this.length>i;i++){var conditions=[];for(var key in predicate)conditions.push(predicate[key]===this[i][key]);if(conditions.every(function(e){return e===!0})){result=this[i];break}}else for(var i=0;this.length>i;i++)if(predicate(this[i])){result=this[i];break}return callback?callback(result):result},writable:!0,enumerable:!1},mode:{value:function(callback){for(var map={},count=1,modes=new Collection,i=0;this.length>i;i++){var e=this[i];null==map[e]?map[e]=1:map[e]++,map[e]>count?(modes=new Collection(e),count=map[e]):map[e]==count&&(modes.push(e),count=map[e])}return 1===modes.length&&(modes=modes[0]),callback?callback(modes):modes},writable:!0,enumerable:!1},frequency:{value:function(element,callback){var freq=0;if(-1!==this.indexOf(element)){var buffer=this.copy().sort();freq=buffer.lastIndexOf(element)-buffer.indexOf(element)+1}return callback?callback(freq):freq},writable:!0,enumerable:!1},distribution:{value:function(format,callback){for(var array=this.copy().sort(),distribution={},i=0;array.length>i;)distribution[array[i]]="relative"===format?array.frequency(array[i])/array.length:array.frequency(array[i]),i=array.lastIndexOf(array[i])+1;return callback?callback(distribution):distribution},writable:!0,enumerable:!1},append:{value:function(that,callback){return collection=this.push.apply(this,that),callback?callback(collection):collection},writable:!0,enumerable:!1},equal:{value:function(that,callback){var equality=!(that>this||this>that);return callback?callback(equality):equality},writable:!0,enumerable:!1},clone:{value:function(callback){var object=Array.isArray(this)?[]:{};for(var i in this)"clone"!==i&&(object[i]=this[i]&&"object"==typeof this[i]?this[i].clone():this[i]);return callback?callback(object):object},writable:!0,enumerable:!1},copy:{value:function(callback){var copy=new Collection(this.slice());return callback?callback(copy):copy},writable:!0,enumerable:!1},toArray:{value:function(callback){var array=Array.prototype.slice.call(this);return callback?callback(array):array},writable:!0,enumerable:!1},concat:{value:function(){var args=Array.prototype.slice.call(arguments),end=args[args.length-1];return"function"==typeof end?"number"!=typeof args[0]?end(new Collection(this.toArray().concat(args[0]))):end(new Collection(this.toArray().concat(args.slice(0,args.length-1)))):"number"!=typeof args[0]?new Collection(this.toArray().concat(args[0])):new Collection(this.toArray().concat(args))},writable:!0,enumerable:!1},slice:{value:function(begin,end,callback){var args=Array.prototype.slice.call(arguments);return 3===args.length?callback(new Collection(this.toArray().slice(begin,end))):2===args.length?"function"==typeof args[1]?callback(new Collection(this.toArray().slice(begin))):new Collection(this.toArray().slice(begin,end)):1===args.length?new Collection(this.toArray().slice(begin)):new Collection(this.toArray().slice())},writable:!0,enumerable:!1},split:{value:function(predicate,callback){var split=new Collection;return split.push(this.toArray().filter(function(e){return!predicate(e)})),split.push(this.toArray().filter(predicate)),callback?callback(split):split},writable:!0,enumerable:!1},unique:{value:function(callback){for(var array=this.copy().sort(),unique=[],i=0;array.length>i;)unique.push(array[i]),i=array.lastIndexOf(array[i])+1;return callback?callback(unique):unique},writable:!0,enumerable:!1},filter:{value:function(callback,next){var filter=new Collection(this.toArray().filter(callback));return next?next(filter):filter},writable:!0,enumerable:!1},every:{value:function(callback,next){var every=this.toArray().every(callback);return next?next(every):every},writable:!0,enumerable:!1},map:{value:function(callback,next){var map=new Collection(this.toArray().map(callback));return next?next(map):map},writable:!0,enumerable:!1},some:{value:function(callback,next){var some=this.toArray().some(callback);return next?next(some):some},writable:!0,enumerable:!1},reduce:{value:function(callback,initialValue,next){var args=Array.prototype.slice.call(arguments);return 3===args.length?next(this.toArray().reduce(callback,initialValue)):2===args.length?"function"==typeof args[1]?next(this.toArray().reduce(callback)):this.toArray().reduce(callback,initialValue):this.toArray().reduce(callback)},writable:!0,enumerable:!1},reduceRight:{value:function(callback,initialValue,next){var args=Array.prototype.slice.call(arguments);return 3===args.length?next(this.toArray().reduceRight(callback,initialValue)):2===args.length?"function"==typeof args[1]?next(this.toArray().reduceRight(callback)):this.toArray().reduceRight(callback,initialValue):this.toArray().reduceRight(callback)},writable:!0,enumerable:!1},extend:{value:function(methods,callback){for(var method in methods)Object.defineProperty(this,method,{value:methods[method],writable:!0,enumerable:!1});return callback?callback(this):this},writable:!0,enumerable:!1}}),collection};Array.prototype.toCollection=function(){return new Collection(this)},"undefined"!=typeof window?(window.gauss=window.gauss===void 0?{}:window.gauss,window.gauss.Collection=Collection):exports=module.exports=Collection})();(function(){var Collection="undefined"==typeof window?require("./collection"):window.gauss.Collection;Collection=Collection();var Vector=function(values){"use strict";var vector=Array.isArray(values)?values:Array.prototype.slice.call(arguments);0===Array.prototype.slice.call(arguments).length&&(vector=[]);var cache={sum:0,product:1,variance:0,sample:{variance:0},values:Array.prototype.slice.call(vector)};cache.sync=function(){cache.values=Array.prototype.slice.call(vector)};var asc=function(a,b){return a-b};return Object.defineProperties(vector,{sum:{value:function(callback){var sum=0;if(this.equal(cache.values)&&0!==cache.sum)sum=cache.sum;else{for(var i=0;this.length>i;)sum+=this[i++];cache.sum=sum,cache.sync()}return callback?callback(sum):sum},writable:!0,enumerable:!1},product:{value:function(callback){var product=1;if(this.equal(cache.values)&&1!==cache.product)product=cache.product;else for(var i=0;this.length>i;)product*=this[i++],cache.product=product,cache.sync();return callback?callback(product):product},writable:!0,enumerable:!1},mean:{value:function(callback){var mean=this.sum()/this.length;return callback?callback(mean):mean},writable:!0,enumerable:!1},gmean:{value:function(callback){var gmean=Math.pow(Math.abs(this.product()),1/this.length);return callback?callback(gmean):gmean},writable:!0,enumerable:!1},hmean:{value:function(callback){function reciprocalSum(set){for(var i=0,sum=0;set.length>i;)sum+=1/Math.abs(set[i++]);return sum}var hmean=this.length/reciprocalSum(this);return callback?callback(hmean):hmean},writable:!0,enumerable:!1},qmean:{value:function(callback){var qmean=Math.sqrt(this.pow(2).sum()/this.length);return callback?callback(qmean):qmean},writable:!0,enumerable:!1},pmean:{value:function(p,callback){for(var pmean=0,i=0;this.length>i;)pmean+=Math.pow(this[i++],p);return pmean=Math.pow(pmean/this.length,1/p),callback?callback(pmean):pmean},writable:!0,enumerable:!1},median:{value:function(callback){var buffer=this.copy();buffer.sort(asc);var median=0===this.length%2?(buffer[this.length/2-1]+buffer[this.length/2])/2:buffer[parseInt(this.length/2)];return callback?callback(median):median},writable:!0,enumerable:!1},range:{value:function(callback){var range=this.max()-this.min();return callback?callback(range):range},writable:!0,enumerable:!1},variance:{value:function(callback){var mean=0,variance=0;if(this.equal(cache.values)&&0!==cache.variance)variance=cache.variance;else{for(var i=0;this.length>i;i++){var _mean=mean;mean+=(this[i]-_mean)/(i+1),variance+=(this[i]-_mean)*(this[i]-mean)}variance/=this.length,cache.variance=variance,cache.sync()}return callback?callback(variance):variance},writable:!0,enumerable:!1},stdev:{value:function(percentile,callback){var stdev=0;return percentile?this.density(percentile).stdev():(stdev=Math.sqrt(this.variance()),callback?callback(stdev):stdev)},writable:!0,enumerable:!1},percentile:{value:function(percent,callback){var buffer=this.copy();buffer.sort(asc);var percentile=buffer[0];return percent>0&&(percentile=buffer[Math.floor(this.length*percent)]),callback?callback(percentile):percentile},writable:!0,enumerable:!1},density:{value:function(percent,callback){var slice,buffer=this.copy();if(buffer.sort(asc),1==percent)return buffer;var begin=Math.round(this.length*(.5-percent/2)-1),end=Math.round(this.length*(.5+percent/2)-1);return slice=new Vector(buffer.slice(begin,end)),callback?callback(slice):slice},writable:!0,enumerable:!1},quantile:{value:function(quantity,callback){var buffer=this.copy();buffer.sort(asc);var increment=1/quantity,results=new Vector;if(quantity>this.length)throw new RangeError("Subset quantity is greater than the Vector length");for(var i=increment;1>i;i+=increment){var index=Math.round(buffer.length*i)-1;buffer.length-1>index&&results.push(buffer[index])}return callback?callback(results):results},writable:!0,enumerable:!1},delta:{value:function(callback){for(var delta=new Vector,i=1;this.length>i;i++)delta.push(this[i]-this[i-1]);return callback?callback(delta):delta},writable:!0,enumerable:!1},sma:{value:function(period,callback){var sma;if(1===period)sma=this;else{var sum=new Vector(this.slice(0,period)).sum();sma=new Vector([sum/period]);for(var i=1;this.length-period+1>i;i++)sum+=this[i+period-1]-this[i-1],sma.push(sum/period)}return callback?callback(sma):sma},writable:!0,enumerable:!1},ema:{value:function(options,callback){if("number"==typeof options){var length=options;options={period:length,ratio:function(n){return 2/(n+1)}}}for(var sum=new Vector(this.slice(0,options.period)).sum(),ema=new Vector([sum/options.period]),ratio=options.ratio(options.period),i=1;this.length-options.period+1>i;i++)ema.push(ratio*(this[i+options.period-1]-ema[i-1])+ema[i-1]);return callback?callback(ema):ema},writable:!0,enumerable:!1},sample:{value:{mean:function(callback){var mean=vector.sum()/(vector.length-1);return callback?callback(mean):mean},gmean:function(callback){var gmean=Math.pow(Math.abs(vector.product()),1/(vector.length-1));return callback?callback(gmean):gmean},hmean:function(callback){function reciprocalSum(set){for(var i=0,sum=0;set.length>i;)sum+=1/Math.abs(set[i++]);return sum}var hmean=(vector.length-1)/reciprocalSum(vector);return callback?callback(hmean):hmean},qmean:function(callback){var qmean=Math.sqrt(vector.pow(2).sum()/(vector.length-1));return callback?callback(qmean):qmean},pmean:function(p,callback){for(var pmean=0,i=0;vector.length>i;)pmean+=Math.pow(vector[i++],p);return pmean=Math.pow(pmean/(vector.length-1),1/p),callback?callback(pmean):pmean},variance:function(callback){var mean=0,variance=0;if(vector.equal(cache.values)&&0!==cache.sample.variance)variance=cache.sample.variance;else{for(var i=0;vector.length>i;i++){var _mean=mean;mean+=(vector[i]-_mean)/(i+1),variance+=(vector[i]-_mean)*(vector[i]-mean)}variance/=vector.length-1,cache.sample.variance=variance,cache.sync()}return callback?callback(variance):variance},stdev:function(callback){var stdev=Math.sqrt(vector.sample.variance());return callback?callback(stdev):stdev}},writable:!0,enumerable:!1},max:{value:function(callback){var max=Math.max.apply({},this);return callback?callback(max):max},writable:!0,enumerable:!1},min:{value:function(callback){var min=Math.min.apply({},this);return callback?callback(min):min},writable:!0,enumerable:!1},abs:{value:function(callback){var abs=this.map(Math.abs);return callback?callback(abs):abs},writable:!0,enumerable:!1},acos:{value:function(callback){var acos=this.map(Math.acos);return callback?callback(acos):acos},writable:!0,enumerable:!1},asin:{value:function(callback){var asin=this.map(Math.asin);return callback?callback(asin):asin},writable:!0,enumerable:!1},atan:{value:function(callback){var atan=this.map(Math.atan);return callback?callback(atan):atan},writable:!0,enumerable:!1},ceil:{value:function(callback){var ceil=this.map(Math.ceil);return callback?callback(ceil):ceil},writable:!0,enumerable:!1},cos:{value:function(callback){var cos=this.map(Math.cos);return callback?callback(cos):cos},writable:!0,enumerable:!1},exp:{value:function(callback){var exp=this.map(Math.exp);return callback?callback(exp):exp},writable:!0,enumerable:!1},floor:{value:function(callback){var floor=this.map(Math.floor);return callback?callback(floor):floor},writable:!0,enumerable:!1},log:{value:function(callback){var log=this.map(Math.log);return callback?callback(log):log},writable:!0,enumerable:!1},pow:{value:function(exponent,callback){var pow=this.map(function(x){return Math.pow(x,exponent)});return callback?callback(pow):pow},writable:!0,enumerable:!1},round:{value:function(callback){var round=this.map(Math.round);return callback?callback(round):round},writable:!0,enumerable:!1},sin:{value:function(callback){var sin=this.map(Math.sin);return callback?callback(sin):sin},writable:!0,enumerable:!1},sqrt:{value:function(callback){var sqrt=this.map(Math.sqrt);return callback?callback(sqrt):sqrt},writable:!0,enumerable:!1},tan:{value:function(callback){var tan=this.map(Math.tan);return callback?callback(tan):tan},writable:!0,enumerable:!1},copy:{value:function(callback){var copy=new Vector(this.slice());return callback?callback(copy):copy},writable:!0,enumerable:!1},push:{value:function(){var mean=0===this.length?0:cache.sum/this.length,variance=0===this.length?0:cache.variance*this.length,args=Array.prototype.slice.call(arguments),end=args[args.length-1],length=this.length;if("function"==typeof end){for(var i=0;args.length-1>i;i++){Array.prototype.push.call(this,args[i]),Array.prototype.push.call(cache.values,args[i]);var _mean=mean;mean+=(args[i]-_mean)/this.length,variance+=(args[i]-_mean)*(args[i]-mean),cache.sum+=args[i],cache.product*=args[i],length++}return variance/=this.length,cache.variance=variance,end(length)}for(var i=0;args.length>i;i++){Array.prototype.push.call(this,args[i]),Array.prototype.push.call(cache.values,args[i]);var _mean=mean;mean+=(args[i]-_mean)/this.length,variance+=(args[i]-_mean)*(args[i]-mean),cache.sum+=args[i],cache.product*=args[i],length++}return variance/=this.length,cache.variance=variance,length},writable:!0,enumerable:!1},concat:{value:function(){var args=Array.prototype.slice.call(arguments),end=args[args.length-1];return"function"==typeof end?"number"!=typeof args[0]?end(new Vector(this.toArray().concat(args[0]))):end(new Vector(this.toArray().concat(args.slice(0,args.length-1)))):"number"!=typeof args[0]?new Vector(this.toArray().concat(args[0])):new Vector(this.toArray().concat(args))},writable:!0,enumerable:!1},slice:{value:function(begin,end,callback){var args=Array.prototype.slice.call(arguments);return 3===args.length?callback(new Vector(this.toArray().slice(begin,end))):2===args.length?"function"==typeof args[1]?callback(new Vector(this.toArray().slice(begin))):new Vector(this.toArray().slice(begin,end)):1===args.length?new Vector(this.toArray().slice(begin)):new Vector(this.toArray().slice())},writable:!0,enumerable:!1},filter:{value:function(callback,next){var filter=new Vector(this.toArray().filter(callback));return next?next(filter):filter},writable:!0,enumerable:!1},map:{value:function(callback,next){var map=new Vector(this.toArray().map(callback));return next?next(map):map},writable:!0,enumerable:!1},extend:{value:function(){return Collection.extend.bind(this),Collection.extend.apply(this,arguments)},writable:!0,enumerable:!1}}),vector.extend({indexOf:Collection.indexOf,mode:Collection.mode,frequency:Collection.frequency,distribution:Collection.distribution,every:Collection.every,append:Collection.append,unique:Collection.unique,some:Collection.some,reduce:Collection.reduce,reduceRight:Collection.reduceRight,toArray:Collection.toArray,equal:Collection.equal,clone:Collection.clone}),cache.sum=vector.sum(),cache.product=vector.product(),cache.variance=vector.variance(),vector};Array.prototype.toVector=function(){return new Vector(this)},"undefined"!=typeof window?(window.gauss=window.gauss===void 0?{}:window.gauss,window.gauss.Vector=Vector):exports=module.exports=Vector})();(function(){var Collection="undefined"==typeof window?require("./collection"):window.gauss.Collection;Collection=Collection();var Vector="undefined"==typeof window?require("./vector"):window.gauss.Vector,TimeSeries=function(values){"use strict";var timeseries=2===arguments.length?Array.prototype.slice.call(arguments):values;return 0===Array.prototype.slice.call(arguments).length&&(timeseries=[]),Object.defineProperties(timeseries,{byValue:{value:function(a,b){return a[1]b[1]?1:0},writable:!0,enumerable:!1},byDate:{value:function(a,b){return a[0]b[0]?1:0},writable:!0,enumerable:!1},times:{value:function(callback){var times=new Vector(Array.prototype.map.call(this,function(i){return i[0]}));return callback?callback(times):times},writable:!0,enumerable:!1},values:{value:function(callback){var values=new Vector(Array.prototype.map.call(this,function(i){return i[1]}));return callback?callback(values):values},writable:!0,enumerable:!1},extend:{value:function(){return Collection.extend.bind(this),Collection.extend.apply(this,arguments)},writable:!0,enumerable:!1}}),timeseries.extend({every:Collection.every,append:Collection.append}),timeseries};"undefined"!=typeof window?(window.gauss=window.gauss===void 0?{}:window.gauss,window.gauss.TimeSeries=TimeSeries):exports=module.exports=TimeSeries})(); \ No newline at end of file diff --git a/lib/gauss.js b/lib/gauss.js index 26ef394..d9141b3 100644 --- a/lib/gauss.js +++ b/lib/gauss.js @@ -1,7 +1,7 @@ /** * Gauss - * https://github.com/stackd/gauss - * Copyright(c) 2012 Fredrick Galoso + * https://github.com/wayoutmind/gauss + * Copyright(c) 2013 Fredrick Galoso * LICENSE: MIT/X11 */ diff --git a/lib/vector.js b/lib/vector.js index 010e416..aaa7bda 100644 --- a/lib/vector.js +++ b/lib/vector.js @@ -405,6 +405,17 @@ else return qmean; }, + pmean: function(p, callback) { + var pmean = 0.0; + for (var i = 0; i < vector.length;) { + pmean += Math.pow(vector[i++], p); + } + pmean = Math.pow(pmean / (vector.length - 1), 1/p); + if (callback) + return callback(pmean); + else + return pmean; + }, variance: function(callback) { var mean = 0.0, variance = 0.0; @@ -425,6 +436,13 @@ return callback(variance); else return variance; + }, + stdev: function(callback) { + var stdev = Math.sqrt(vector.sample.variance()); + if (callback) + return callback(stdev); + else + return stdev; } }, writable: true, diff --git a/package.json b/package.json index 87bd401..acb1b35 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "author": "Fredrick Galoso ", + "author": "Fredrick Galoso ", "name": "gauss", "description": "JavaScript statistics, analytics, and set library", "version": "0.2.8", "keywords": [ "statistics", "analytics", "timeseries", "math", "gauss", "set" ], "repository": { "type": "git", - "url": "git://github.com/stackd/gauss.git" + "url": "git://github.com/wayoutmind/gauss.git" }, "main": "index", "engines": { diff --git a/test/vector.test.js b/test/vector.test.js index 5260630..c07fc16 100644 --- a/test/vector.test.js +++ b/test/vector.test.js @@ -331,11 +331,23 @@ vows.describe('Vector').addBatch({ assert.equal(topic, 61.88748843255635); } }, + '(Power Mean)': { + topic: set.sample.pmean(1), + '55.04081632653061': function(topic) { + assert.equal(topic, set.sample.mean()); + } + }, '(Variance)': { topic: set.sample.variance(), '861.1595918367346': function(topic) { assert.equal(topic, 861.1595918367346); } + }, + '(Standard Deviation)': { + topic: set.sample.stdev(), + '29.34552081386075': function(topic) { + assert.equal(topic, 29.34552081386075); + } } }, // Math methods