Game
- Starting solo game with physics
This commit is contained in:
7
site/real_game/node_modules/statsjs/LICENSE
generated
vendored
Normal file
7
site/real_game/node_modules/statsjs/LICENSE
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright (c) 2012 Angus Gibbs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
32
site/real_game/node_modules/statsjs/README.md
generated
vendored
Normal file
32
site/real_game/node_modules/statsjs/README.md
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# Stats.js by [Angus Gibbs](http://angusgibbs.com)
|
||||
|
||||
Provides functions for many of the statistical operations that you might need.
|
||||
|
||||
## About
|
||||
|
||||
Stats.js currently supports many of the statistical functions that you might need, including
|
||||
|
||||
* regression lines (linear, power, exponential)
|
||||
* min, max, mean, median, first quartile, third quartile
|
||||
* least common multiple and greatest common factor
|
||||
* standard deviation
|
||||
* sorting a list of points by an attribute
|
||||
* probabilities (binomial, geometric, normal)
|
||||
* z procedures
|
||||
|
||||
It also supports many of the functions on the data set that you'd expect from [Underscore](http://underscore.js), such as `pluck`, `map`, and `each`.
|
||||
|
||||
See the [getting started guide](https://github.com/angusgibbs/statsjs/blob/master/docs/getting_started.md) for more information.
|
||||
|
||||
## Roadmap
|
||||
|
||||
* Better documentation
|
||||
* Auto-detect best regression line
|
||||
|
||||
## Contributing
|
||||
|
||||
Patches are welcome, just make sure there are matching unit tests. Tests use [mocha](http://visionmedia.github.com/mocha/) with my fork of [expect.js](https://github.com/angusgibbs/expect.js) (which allows you to assert that a value is within a certain error range of another value). Once you clone the repo (either your fork or this repository), `cd` into it and run `npm install` to install mocha and expect.js. Tests can be found within `test/test.js`.
|
||||
|
||||
## License
|
||||
|
||||
Stats.js is licensed under the [MIT License](http://opensource.org/licenses/mit-license.php). See https://github.com/angusgibbs/statsjs/blob/master/LICENSE for the full license.
|
954
site/real_game/node_modules/statsjs/lib/stats.js
generated
vendored
Normal file
954
site/real_game/node_modules/statsjs/lib/stats.js
generated
vendored
Normal file
@ -0,0 +1,954 @@
|
||||
/*!
|
||||
* Stats.js (https://github.com/angusgibbs/stats.js)
|
||||
* Copyright 2012 Angus Gibbs
|
||||
*/
|
||||
(function(root) {
|
||||
// Create the top level stats object
|
||||
// =================================
|
||||
|
||||
// Wrapper to create a chainable stats object.
|
||||
//
|
||||
// arr - The array to work with.
|
||||
//
|
||||
// Returns a new chainable object.
|
||||
var stats = function(arr) {
|
||||
return new stats.init(arguments.length > 1 ?
|
||||
Array.prototype.slice.call(arguments, 0) :
|
||||
arr);
|
||||
};
|
||||
|
||||
// Creates a new chainable array object.
|
||||
//
|
||||
// arr - The array to work with.
|
||||
//
|
||||
// Returns a new chainable object.
|
||||
stats.init = function(arr) {
|
||||
this.arr = arr;
|
||||
this.length = arr.length;
|
||||
};
|
||||
|
||||
// Define the methods for the stats object
|
||||
stats.init.prototype = {
|
||||
// Calls a function on each element in an array or JSON object.
|
||||
//
|
||||
// fn - The function to call on each element.
|
||||
// el - The array or object element
|
||||
// index - The index or key of the array element
|
||||
// arr - The array or object
|
||||
//
|
||||
// Returns nothing.
|
||||
each: function(fn) {
|
||||
if (this.arr.length === undefined) {
|
||||
// The wrapped array is a JSON object
|
||||
for (var key in arr) {
|
||||
fn.call(this.arr[key], key, this.arr[key], this.arr);
|
||||
}
|
||||
} else {
|
||||
// The wrapper array is an array
|
||||
for (var i = 0, l = this.arr.length; i < l; i++) {
|
||||
fn.call(this.arr[i], this.arr[i], i, this.arr);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Replaces each element in an array or JSON object with the result of
|
||||
// the function that is called against each element.
|
||||
//
|
||||
// fn - The function to call on each element
|
||||
// el - The array or object element
|
||||
// index - The index or key of the array element
|
||||
//
|
||||
// Returns nothing.
|
||||
map: function(fn) {
|
||||
var arr = this.arr;
|
||||
|
||||
if (arr.length === undefined) {
|
||||
// The wrapped array is a JSON object
|
||||
for (var key in arr) {
|
||||
this.arr[key] = fn.call(arr[key], arr[key], key, arr);
|
||||
}
|
||||
} else {
|
||||
// The wrapped array is an array
|
||||
for (var i = 0, l = this.arr.length; i < l; i++) {
|
||||
this.arr[i] = fn.call(arr[i], arr[i], i, arr);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Replaces each element of the array with the attribute of that given
|
||||
// element.
|
||||
//
|
||||
// attr - The attribute to pluck.
|
||||
//
|
||||
// Returns nothing.
|
||||
pluck: function(attr) {
|
||||
var newArr = [];
|
||||
|
||||
if (this.arr.length === undefined) {
|
||||
// The wrapped array is a JSON object
|
||||
for (var key in arr) {
|
||||
newArr.push(this.arr[key][attr]);
|
||||
}
|
||||
} else {
|
||||
// The wrapped array is an array
|
||||
for (var i = 0, l = this.arr.length; i < l; i++) {
|
||||
newArr.push(this.arr[i][attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return stats(newArr);
|
||||
},
|
||||
|
||||
// Finds the smallest number.
|
||||
//
|
||||
// attr - Optional. If passed, the elemnt with the minimum value for the
|
||||
// given attribute will be returned.
|
||||
//
|
||||
// Returns the minimum.
|
||||
min: function(attr) {
|
||||
// Get the numbers
|
||||
var arr = this.arr;
|
||||
|
||||
// Go through each of the numbers and find the minimum
|
||||
var minimum = attr == null ? arr[0] : arr[0][attr];
|
||||
var minimumEl = attr == null ? arr[0] : arr[0];
|
||||
|
||||
stats(arr).each(function(num, index) {
|
||||
if ((attr == null ? num : num[attr]) < minimum) {
|
||||
minimum = attr == null ? num : num[attr];
|
||||
minimumEl = num;
|
||||
}
|
||||
});
|
||||
|
||||
return minimumEl;
|
||||
},
|
||||
|
||||
// Finds the largest number.
|
||||
//
|
||||
// attr - Optional. If passed, the elemnt with the maximum value for the
|
||||
// given attribute will be returned.
|
||||
//
|
||||
// Returns the maximum.
|
||||
max: function(attr) {
|
||||
// Get the numbers
|
||||
var arr = this.arr;
|
||||
|
||||
// Go through each of the numbers and find the maximum
|
||||
var maximum = attr == null ? arr[0] : arr[0][attr];
|
||||
var maximumEl = attr == null ? arr[0] : arr[0];
|
||||
|
||||
stats(arr).each(function(num, index) {
|
||||
if ((attr == null ? num : num[attr]) > maximum) {
|
||||
maximum = attr == null ? num : num[attr];
|
||||
maximumEl = num;
|
||||
}
|
||||
});
|
||||
|
||||
return maximumEl;
|
||||
},
|
||||
|
||||
// Finds the median of the numbers.
|
||||
//
|
||||
// Returns the median.
|
||||
median: function() {
|
||||
// Sort the numbers
|
||||
var arr = this.clone().sort().toArray();
|
||||
|
||||
if (arr.length % 2 === 0) {
|
||||
// There are an even number of elements in the array; the median
|
||||
// is the average of the middle two
|
||||
return (arr[arr.length / 2 - 1] + arr[arr.length / 2]) / 2;
|
||||
} else {
|
||||
// There are an odd number of elements in the array; the median
|
||||
// is the middle one
|
||||
return arr[(arr.length - 1) / 2];
|
||||
}
|
||||
},
|
||||
|
||||
// Finds the first quartile of the numbers.
|
||||
//
|
||||
// Returns the first quartile.
|
||||
q1: function() {
|
||||
// Handle the single element case
|
||||
if (this.length == 1) {
|
||||
return this.arr[0];
|
||||
}
|
||||
|
||||
// Sort the numbers
|
||||
var nums = this.clone().sort();
|
||||
|
||||
// The first quartile is the median of the lower half of the numbers
|
||||
return nums.slice(0, Math.floor(nums.size() / 2)).median();
|
||||
},
|
||||
|
||||
// Finds the third quartile of the numbers.
|
||||
//
|
||||
// Returns the third quartile.
|
||||
q3: function() {
|
||||
// Handle the single element case
|
||||
if (this.length == 1) {
|
||||
return this.arr[0];
|
||||
}
|
||||
|
||||
// Sort the numbers
|
||||
var nums = this.clone().sort();
|
||||
|
||||
// The third quartile is the median of the upper half of the numbers
|
||||
return nums.slice(Math.ceil(nums.size() / 2)).median();
|
||||
},
|
||||
|
||||
// Finds the interquartile range of the data set.
|
||||
//
|
||||
// Returns the IQR.
|
||||
iqr: function() {
|
||||
return this.q3() - this.q1();
|
||||
},
|
||||
|
||||
// Finds all outliers in the data set, using the 1.5 * IQR away from
|
||||
// the median test.
|
||||
//
|
||||
// Returns a new stats object with the outliers.
|
||||
findOutliers: function() {
|
||||
// Get the median and the range that the number must fall within
|
||||
var median = this.median();
|
||||
var range = this.iqr() * 1.5;
|
||||
|
||||
// Create a new stats object to hold the outliers
|
||||
var outliers = stats([]);
|
||||
|
||||
// Go through each element in the data set and test to see if it
|
||||
// is an outlier
|
||||
this.each(function(num) {
|
||||
if (Math.abs(num - median) > range) {
|
||||
// The number is an outlier
|
||||
outliers.push(num);
|
||||
}
|
||||
});
|
||||
|
||||
return outliers;
|
||||
},
|
||||
|
||||
// Tests if the given number would be an outlier in the data set.
|
||||
//
|
||||
// num - The number to test.
|
||||
//
|
||||
// Returns a boolean.
|
||||
testOutlier: function(num) {
|
||||
return (Math.abs(num - this.median()) > this.iqr() * 1.5);
|
||||
},
|
||||
|
||||
// Removes all the outliers from the data set.
|
||||
//
|
||||
// Returns nothing.
|
||||
removeOutliers: function() {
|
||||
// Get the median and the range that the number must fall within
|
||||
var median = this.median();
|
||||
var range = this.iqr() * 1.5;
|
||||
|
||||
// Create a new stats object that will hold all the non-outliers
|
||||
var notOutliers = stats([]);
|
||||
|
||||
// Go through each element in the data set and test to see if it
|
||||
// is an outlier
|
||||
this.each(function(num) {
|
||||
if (Math.abs(num - median) <= range) {
|
||||
// The number is not an outlier
|
||||
notOutliers.push(num);
|
||||
}
|
||||
});
|
||||
|
||||
return notOutliers;
|
||||
},
|
||||
|
||||
// Finds the mean of the numbers.
|
||||
//
|
||||
// Returns the mean.
|
||||
mean: function() {
|
||||
return this.sum() / this.size();
|
||||
},
|
||||
|
||||
// Finds the sum of the numbers.
|
||||
//
|
||||
// Returns the sum.
|
||||
sum: function() {
|
||||
var result = 0;
|
||||
|
||||
this.each(function(num) {
|
||||
result += num;
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
// Finds the standard deviation of the numbers.
|
||||
//
|
||||
// Returns the standard deviation.
|
||||
stdDev: function() {
|
||||
// Get the mean
|
||||
var mean = this.mean();
|
||||
|
||||
// Get a new stats object to work with
|
||||
var nums = this.clone();
|
||||
|
||||
// Map each element of nums to the square of the element minus the
|
||||
// mean
|
||||
nums.map(function(num) {
|
||||
return Math.pow(num - mean, 2);
|
||||
});
|
||||
|
||||
// Return the standard deviation
|
||||
return Math.sqrt(nums.sum() / (nums.size() - 1));
|
||||
},
|
||||
|
||||
// Calculates the correlation coefficient for the data set.
|
||||
//
|
||||
// Returns the value of r.
|
||||
r: function() {
|
||||
// Get the x and y coordinates
|
||||
var xCoords = this.pluck('x');
|
||||
var yCoords = this.pluck('y');
|
||||
|
||||
// Get the means for the x and y coordinates
|
||||
var meanX = xCoords.mean();
|
||||
var meanY = yCoords.mean();
|
||||
|
||||
// Get the standard deviations for the x and y coordinates
|
||||
var stdDevX = xCoords.stdDev();
|
||||
var stdDevY = yCoords.stdDev();
|
||||
|
||||
// Map each element to the difference of the element and the mean
|
||||
// divided by the standard deviation
|
||||
xCoords.map(function(num) {
|
||||
return (num - meanX) / stdDevX;
|
||||
});
|
||||
yCoords.map(function(num) {
|
||||
return (num - meanY) / stdDevY;
|
||||
});
|
||||
|
||||
// Multiply each element in the x by the corresponding value in
|
||||
// the y
|
||||
var nums = this.clone().map(function(num, index) {
|
||||
return xCoords.get(index) * yCoords.get(index);
|
||||
});
|
||||
|
||||
// r is the sum of xCoords over the number of points minus 1
|
||||
return nums.sum() / (nums.size() - 1);
|
||||
},
|
||||
|
||||
// Calculates the Least Squares Regression line for the data set.
|
||||
//
|
||||
// Returns an object with the slope and y intercept.
|
||||
linReg: function() {
|
||||
// Get the x and y coordinates
|
||||
var xCoords = this.pluck('x');
|
||||
var yCoords = this.pluck('y');
|
||||
|
||||
// Get the means for the x and y coordinates
|
||||
var meanX = xCoords.mean();
|
||||
var meanY = yCoords.mean();
|
||||
|
||||
// Get the standard deviations for the x and y coordinates
|
||||
var stdDevX = xCoords.stdDev();
|
||||
var stdDevY = yCoords.stdDev();
|
||||
|
||||
// Calculate the correlation coefficient
|
||||
var r = this.r();
|
||||
|
||||
// Calculate the slope
|
||||
var slope = r * (stdDevY / stdDevX);
|
||||
|
||||
// Calculate the y-intercept
|
||||
var yIntercept = meanY - slope * meanX;
|
||||
|
||||
return {
|
||||
slope: slope,
|
||||
yIntercept: yIntercept,
|
||||
r: r
|
||||
};
|
||||
},
|
||||
|
||||
// Calculates the exponential regression line for the data set.
|
||||
//
|
||||
// Returns an object with the coefficient, base, and correlation
|
||||
// coefficient for the linearized data.
|
||||
expReg: function() {
|
||||
// Get y coordinates
|
||||
var yCoords = this.pluck('y');
|
||||
|
||||
// Do a semi-log transformation of the coordinates
|
||||
yCoords.map(function(num) {
|
||||
return Math.log(num);
|
||||
});
|
||||
|
||||
// Get a new stats object to work with that has the transformed data
|
||||
var nums = this.clone().map(function(coord, index) {
|
||||
return {
|
||||
x: coord.x,
|
||||
y: yCoords.get(index)
|
||||
};
|
||||
});
|
||||
|
||||
// Calculate the linear regression for the linearized data
|
||||
var linReg = nums.linReg();
|
||||
|
||||
// Calculate the coefficient for the exponential equation
|
||||
var coefficient = Math.pow(Math.E, linReg.yIntercept);
|
||||
|
||||
// Calculate the base for the exponential equation
|
||||
var base = Math.pow(Math.E, linReg.slope);
|
||||
|
||||
return {
|
||||
coefficient: coefficient,
|
||||
base: base,
|
||||
r: linReg.r
|
||||
};
|
||||
},
|
||||
|
||||
// Calculates the power regression line for the data set.
|
||||
//
|
||||
// Returns an object with the coefficient, base, and correlation
|
||||
// coefficient for the linearized data.
|
||||
powReg: function() {
|
||||
// Get y coordinates
|
||||
var xCoords = this.pluck('x');
|
||||
var yCoords = this.pluck('y');
|
||||
|
||||
// Do a log-log transformation of the coordinates
|
||||
xCoords.map(function(num) {
|
||||
return Math.log(num);
|
||||
});
|
||||
yCoords.map(function(num) {
|
||||
return Math.log(num);
|
||||
});
|
||||
|
||||
// Get a new stats object to work with that has the transformed data
|
||||
var nums = this.clone().map(function(coord, index) {
|
||||
return {
|
||||
x: xCoords.get(index),
|
||||
y: yCoords.get(index)
|
||||
};
|
||||
});
|
||||
|
||||
// Calculate the linear regression for the linearized data
|
||||
var linReg = nums.linReg();
|
||||
|
||||
// Calculate the coefficient for the power equation
|
||||
var coefficient = Math.pow(Math.E, linReg.yIntercept);
|
||||
|
||||
// Calculate the exponent for the power equation
|
||||
var exponent = linReg.slope;
|
||||
|
||||
return {
|
||||
coefficient: coefficient,
|
||||
exponent: exponent,
|
||||
r: linReg.r
|
||||
};
|
||||
},
|
||||
|
||||
// Returns the number of elements.
|
||||
size: function() {
|
||||
return this.arr.length;
|
||||
},
|
||||
|
||||
// Clones the current stats object, providing a new stats object which
|
||||
// can be changed without modifying the original object.
|
||||
//
|
||||
// Returns a new stats object.
|
||||
clone: function() {
|
||||
return stats(this.arr.slice(0));
|
||||
},
|
||||
|
||||
// Sorts the internal array, optionally by an attribute.
|
||||
//
|
||||
// attr - The attribute of the JSON object to sort by. (Optional.)
|
||||
//
|
||||
// Returns nothing.
|
||||
sort: function(attr) {
|
||||
// Create the sort function
|
||||
var sortFn;
|
||||
|
||||
// CASE: Simple ascending sort
|
||||
if (attr == null) {
|
||||
sortFn = function(a, b) { return a - b; };
|
||||
}
|
||||
// CASE: Simple descending sort
|
||||
else if (attr === true) {
|
||||
sortFn = function(a, b) { return b - a; };
|
||||
}
|
||||
// CASE: Sort by an attribute
|
||||
else if (typeof attr === 'string') {
|
||||
sortFn = function(a, b) { return a[attr] - b[attr]; };
|
||||
}
|
||||
// CASE: Sort by a function
|
||||
else {
|
||||
sortFn = attr;
|
||||
}
|
||||
|
||||
this.arr = this.arr.sort(sortFn);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Gets an element from the object.
|
||||
//
|
||||
// i - The index to retrieve.
|
||||
//
|
||||
// Returns the element at that index.
|
||||
get: function(i) {
|
||||
return this.arr[i];
|
||||
},
|
||||
|
||||
// Sets an element on the object.
|
||||
//
|
||||
// i - The index to set.
|
||||
// val - The value to set the index to.
|
||||
//
|
||||
// Returns nothing.
|
||||
set: function(i, val) {
|
||||
this.arr[i] = val;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Calculates the greatest common divisor of the set.
|
||||
//
|
||||
// Returns a Number, the gcd.
|
||||
gcd: function() {
|
||||
// Create a new stats object to work with
|
||||
var nums = this.clone();
|
||||
|
||||
// Go through each element and make the element the gcd of it
|
||||
// and the element to its left
|
||||
for (var i = 1; i < nums.size(); i++) {
|
||||
nums.set(i, gcd(nums.get(i - 1), nums.get(i)));
|
||||
}
|
||||
|
||||
// The gcd of all the numbers is now in the final element
|
||||
return nums.get(nums.size() - 1);
|
||||
},
|
||||
|
||||
// Calculates the least common multiple of the set.
|
||||
//
|
||||
// Returns a Number, the lcm.
|
||||
lcm: function() {
|
||||
// Create a new stats object to work with
|
||||
var nums = this.clone();
|
||||
|
||||
// Go through each element and make the element the lcm of it
|
||||
// and the element to its left
|
||||
for (var i = 1; i < nums.size(); i++) {
|
||||
nums.set(i, lcm(nums.get(i - 1), nums.get(i)));
|
||||
}
|
||||
|
||||
// The lcm of all the numbers if now in the final element
|
||||
return nums.get(nums.size() - 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Private. Calculates the gcd of two numbers using Euclid's method.
|
||||
//
|
||||
// Returns a Number.
|
||||
function gcd(a, b) {
|
||||
if (b === 0) {
|
||||
return a;
|
||||
}
|
||||
|
||||
return gcd(b, a - b * Math.floor(a / b));
|
||||
}
|
||||
|
||||
// Private. Calculates the lcm of two numbers.
|
||||
//
|
||||
// Returns a Number.
|
||||
function lcm(a, b) {
|
||||
// The least common multiple is the absolute value of the product of
|
||||
// the numbers divided by the greatest common denominator
|
||||
return Math.abs(a * b) / gcd(a, b);
|
||||
}
|
||||
|
||||
// Provide built in JavaScript array mutator methods for the data list
|
||||
var mutators = ['pop', 'push', 'shift', 'splice', 'unshift'];
|
||||
for (var i = 0; i < mutators.length; i++) {
|
||||
stats.init.prototype[mutators[i]] = (function(method) {
|
||||
return function() {
|
||||
return Array.prototype[method].apply(
|
||||
this.arr,
|
||||
Array.prototype.slice.call(arguments, 0)
|
||||
);
|
||||
};
|
||||
})(mutators[i]);
|
||||
}
|
||||
|
||||
// Provide built in JavaScript array accessor methods for the data list
|
||||
var accessors = ['concat', 'join', 'slice', 'reverse'];
|
||||
for (var i = 0; i < accessors.length; i++) {
|
||||
stats.init.prototype[accessors[i]] = (function(method) {
|
||||
return function() {
|
||||
this.arr = Array.prototype[method].apply(
|
||||
this.arr,
|
||||
Array.prototype.slice.call(arguments, 0)
|
||||
);
|
||||
|
||||
return this;
|
||||
};
|
||||
})(accessors[i]);
|
||||
}
|
||||
|
||||
// Override the built-in #toJSON() and #toArray() methods
|
||||
stats.init.prototype.toJSON = stats.init.prototype.toArray = function() {
|
||||
return this.arr;
|
||||
};
|
||||
|
||||
// Creates a list from the specified lower bound to the specified upper
|
||||
// bound.
|
||||
//
|
||||
// lower - The lower bound.
|
||||
// upper - The upper bound.
|
||||
// step - The amount to count by.
|
||||
//
|
||||
// Returns a new stats object.
|
||||
stats.list = function(lower, upper, step) {
|
||||
// Create the array
|
||||
var arr = [];
|
||||
for (var i = lower; i <= upper; i += step || 1) {
|
||||
arr[i - lower] = i;
|
||||
}
|
||||
|
||||
return stats(arr);
|
||||
};
|
||||
|
||||
// Computes the factorial of a number.
|
||||
//
|
||||
// num - The number.
|
||||
//
|
||||
// Returns the factorial.
|
||||
stats.factorial = function(num) {
|
||||
// Handle the special case of 0
|
||||
if (num === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Otherwise compute the factorial
|
||||
for (var i = num - 1; i > 1; i--) {
|
||||
num *= i;
|
||||
}
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
// Computes a permutation.
|
||||
//
|
||||
// n - The length of the set.
|
||||
// r - The number of elements in the subset.
|
||||
//
|
||||
// Returns the permutation.
|
||||
stats.permutation = stats.nPr = function(n, r) {
|
||||
return stats.factorial(n) / stats.factorial(n - r);
|
||||
};
|
||||
|
||||
// Computes a combination.
|
||||
//
|
||||
// n - The length of the set.
|
||||
// r - The number of elements in the subset.
|
||||
//
|
||||
// Returns the combination.
|
||||
stats.combination = stats.nCr = function(n, r) {
|
||||
return stats.factorial(n) /
|
||||
(stats.factorial(r) * stats.factorial(n - r));
|
||||
};
|
||||
|
||||
// Computes the probability of a binomial event.
|
||||
//
|
||||
// trials - The number of trials.
|
||||
// p - The probability of success.
|
||||
// x - The event number (optional).
|
||||
//
|
||||
// If x is not passed, an array with all the probabilities
|
||||
// will be returned.
|
||||
//
|
||||
// Returns a number or an array.
|
||||
stats.binompdf = function(trials, p, x) {
|
||||
// CASE: Specific event was passed
|
||||
if (x != null) {
|
||||
// Return 0 if the event does not exist
|
||||
if (x > trials || x < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the probability otherwise
|
||||
return stats.nCr(trials, x) * Math.pow(p, x) *
|
||||
Math.pow(1 - p, trials - x);
|
||||
}
|
||||
// CASE: No specific event was passed
|
||||
else {
|
||||
// Compute the probabilities
|
||||
return stats.list(0, trials).map(function(num) {
|
||||
return stats.binompdf(trials, p, num);
|
||||
}).toArray();
|
||||
}
|
||||
};
|
||||
|
||||
// Computes the cumulative probability of a binomial event.
|
||||
//
|
||||
// trials - The number of trials.
|
||||
// p - The probability of success.
|
||||
// x - The upper bound (inclusive).
|
||||
//
|
||||
// Returns the probability.
|
||||
stats.binomcdf = function(trials, p, x) {
|
||||
return stats.list(0, x).map(function(num) {
|
||||
return stats.binompdf(trials, p, num);
|
||||
}).sum();
|
||||
};
|
||||
|
||||
// Computes the probability of a geometric event.
|
||||
//
|
||||
// p - The probability of success.
|
||||
// x - The event number.
|
||||
//
|
||||
// Returns the probability.
|
||||
stats.geompdf = function(p, x) {
|
||||
return Math.pow(1 - p, x - 1) * p;
|
||||
};
|
||||
|
||||
// Computes the cumulative probability of a geometric event.
|
||||
//
|
||||
// p - The probability of success.
|
||||
// x - The event number.
|
||||
//
|
||||
// Returns the probability.
|
||||
stats.geomcdf = function(p, x) {
|
||||
return stats.list(1, x).map(function(num) {
|
||||
return stats.geompdf(p, num);
|
||||
}).sum();
|
||||
};
|
||||
|
||||
// Computes the normal probability of an event.
|
||||
//
|
||||
// x - The event number.
|
||||
// mu - The mean.
|
||||
// sigma - The standard deviation.
|
||||
//
|
||||
// Returns the probability.
|
||||
stats.normalpdf = function(x, mu, sigma) {
|
||||
return (1 / (sigma * Math.sqrt(2 * Math.PI))) *
|
||||
Math.exp(-1 * (x - mu) * (x - mu) /
|
||||
(2 * sigma * sigma));
|
||||
};
|
||||
|
||||
// Computes the cumulative normal probability of an event.
|
||||
//
|
||||
// x - The event number.
|
||||
// mu - The mean.
|
||||
// sigma - The standard deviation.
|
||||
//
|
||||
// If four parameters are passed the first two are taken as the
|
||||
// low and high.
|
||||
//
|
||||
// Returns the probability.
|
||||
stats.normalcdf = function(x, mu, sigma) {
|
||||
// If four parameters were passed, return the difference of
|
||||
// the probabilities of the upper and lower
|
||||
if (arguments.length === 4) {
|
||||
// The cumulative probability is the difference of the
|
||||
// probabilities of the upper and the lower
|
||||
return stats.normalcdf(arguments[1], arguments[2], arguments[3]) -
|
||||
stats.normalcdf(arguments[0], arguments[2], arguments[3]);
|
||||
}
|
||||
|
||||
|
||||
// Convert the event to a z score
|
||||
var z = (x - mu) / sigma;
|
||||
|
||||
// The probability will be stored here
|
||||
var p;
|
||||
|
||||
// Coefficients
|
||||
var p0 = 220.2068679123761;
|
||||
var p1 = 221.2135961699311;
|
||||
var p2 = 112.0792914978709;
|
||||
var p3 = 33.91286607838300;
|
||||
var p4 = 6.373962203531650;
|
||||
var p5 = .7003830644436881;
|
||||
var p6 = .03526249659989109;
|
||||
|
||||
var q0 = 440.4137358247522;
|
||||
var q1 = 793.8265125199484;
|
||||
var q2 = 637.3336333788311;
|
||||
var q3 = 296.5642487796737;
|
||||
var q4 = 86.78073220294608;
|
||||
var q5 = 16.06417757920695;
|
||||
var q6 = 1.755667163182642;
|
||||
var q7 = .08838834764831844;
|
||||
|
||||
// Another coefficient (10/sqrt(2))
|
||||
var cutoff = 7.071;
|
||||
|
||||
// Cache the absolute value of the z score
|
||||
var zabs = Math.abs(z);
|
||||
|
||||
// If you're more than 37 z scores away just return 1 or 0
|
||||
if (z > 37) {
|
||||
return 1;
|
||||
}
|
||||
if (z < -37) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Compute the normalpdf of this event
|
||||
var exp = Math.exp(-.5 * zabs * zabs);
|
||||
var pdf = exp / Math.sqrt(2 * Math.PI);
|
||||
|
||||
// Compute the probability
|
||||
if (zabs < cutoff) {
|
||||
p = exp*((((((p6*zabs + p5)*zabs + p4)*zabs + p3)*zabs +
|
||||
p2)*zabs + p1)*zabs + p0)/(((((((q7*zabs + q6)*zabs +
|
||||
q5)*zabs + q4)*zabs + q3)*zabs + q2)*zabs + q1)*zabs +
|
||||
q0);
|
||||
}
|
||||
else {
|
||||
p = pdf/(zabs + 1.0/(zabs + 2.0/(zabs + 3.0/(zabs + 4.0/
|
||||
(zabs + 0.65)))));
|
||||
}
|
||||
|
||||
if (z < 0.0) {
|
||||
return p;
|
||||
} else {
|
||||
return 1 - p;
|
||||
}
|
||||
};
|
||||
|
||||
// Computes the inverse normal.
|
||||
//
|
||||
// p - The probability of x being less than or equal to *x*, the value we
|
||||
// are looking for.
|
||||
//
|
||||
// Returns the x value.
|
||||
stats.invNorm = function(p) {
|
||||
// Coefficients for the rational approximation
|
||||
var a = [
|
||||
-3.969683028665376e+01,
|
||||
2.209460984245205e+02,
|
||||
-2.759285104469687e+02,
|
||||
1.383577518672690e+02,
|
||||
-3.066479806614716e+01,
|
||||
2.506628277459239e+00
|
||||
];
|
||||
var b = [
|
||||
-5.447609879822406e+01,
|
||||
1.615858368580409e+02,
|
||||
-1.556989798598866e+02,
|
||||
6.680131188771972e+01,
|
||||
-1.328068155288572e+01
|
||||
];
|
||||
var c = [
|
||||
-7.784894002430293e-03,
|
||||
-3.223964580411365e-01,
|
||||
-2.400758277161838e+00,
|
||||
-2.549732539343734e+00,
|
||||
4.374664141464968e+00,
|
||||
2.938163982698783e+00
|
||||
];
|
||||
var d = [
|
||||
7.784695709041462e-03,
|
||||
3.224671290700398e-01,
|
||||
2.445134137142996e+00,
|
||||
3.754408661907416e+00
|
||||
];
|
||||
|
||||
// Breakpoints
|
||||
var pLow = .02425;
|
||||
var pHigh = 1 - pLow;
|
||||
|
||||
// Rational appoximation for the lower region
|
||||
if (0 < p && p < pLow) {
|
||||
var q = Math.sqrt(-2 * Math.log(p));
|
||||
return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) /
|
||||
((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) *q + 1);
|
||||
}
|
||||
else if (pLow <= p && p <= pHigh) {
|
||||
var q = p - 0.5;
|
||||
var r = q * q;
|
||||
return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q /
|
||||
(((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);
|
||||
}
|
||||
else if (pHigh < p && p < 1) {
|
||||
var q = Math.sqrt(-2 * Math.log(1 - p));
|
||||
return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) /
|
||||
((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Runs a 1-mean z-test.
|
||||
//
|
||||
// muZero - The proposed population mean.
|
||||
// sigma - The standard deviation of the population.
|
||||
// xBar - The sample mean.
|
||||
// n - The sample size.
|
||||
// inequality - One of "notequal", "lessthan", or "greaterthan", depending
|
||||
// on what you're testing
|
||||
//
|
||||
// Returns an object with the z-test statistic (z) and P-value (p).
|
||||
stats.ZTest = function(muZero, sigma, xBar, n, inequality) {
|
||||
// Calculate the z-test statistic
|
||||
var z = (xBar - muZero) / (sigma / Math.sqrt(n));
|
||||
|
||||
// Calculate the P-value
|
||||
var p;
|
||||
if (z < 0) {
|
||||
// Use normalcdf from -infinity to the z statistic
|
||||
p = stats.normalcdf(-Infinity, z, 0, 1);
|
||||
}
|
||||
else {
|
||||
// Use normalcdf from the z statistic to +infinity
|
||||
p = stats.normalcdf(z, Infinity, 0, 1);
|
||||
}
|
||||
|
||||
// Multiply the P-value by two if you're doing a not equal test
|
||||
if (inequality === 'notequal') {
|
||||
p *= 2;
|
||||
}
|
||||
|
||||
return {
|
||||
z: z,
|
||||
p: p
|
||||
};
|
||||
};
|
||||
|
||||
// Computes a 1-mean z-interval.
|
||||
//
|
||||
// sigma - The population standard deviation.
|
||||
// xBar - The sample mean.
|
||||
// n - The sample size.
|
||||
// level - The confidence level (between 0 and 1, exclusive).
|
||||
//
|
||||
// Returns an object with the low, high, and margin of error (moe).
|
||||
stats.ZInterval = function(sigma, xBar, n, level) {
|
||||
// Compute the margin of error
|
||||
var moe = -stats.invNorm((1 - level) / 2) * sigma / Math.sqrt(n);
|
||||
|
||||
return {
|
||||
low: xBar - moe,
|
||||
high: xBar + moe,
|
||||
moe: moe
|
||||
};
|
||||
};
|
||||
|
||||
// Export the stats object
|
||||
// =================================================
|
||||
if (typeof define === 'function') {
|
||||
// Expose to AMD loaders
|
||||
define(function() {
|
||||
return stats;
|
||||
});
|
||||
} else if (typeof module !== 'undefined' && module.exports) {
|
||||
// Expose to Node and similar environments
|
||||
module.exports = stats;
|
||||
} else {
|
||||
// Just write to window (or whatever is the root object)
|
||||
root.stats = stats;
|
||||
}
|
||||
}(this));
|
48
site/real_game/node_modules/statsjs/package.json
generated
vendored
Normal file
48
site/real_game/node_modules/statsjs/package.json
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "statsjs",
|
||||
"description": "Provides functions for many of the statistical operations that you might need",
|
||||
"version": "1.0.7",
|
||||
"author": "Angus Gibbs (http://angusgibbs.com)",
|
||||
"homepage": "http://github.com/angusgibbs/statsjs",
|
||||
"keywords": [
|
||||
"math",
|
||||
"stats",
|
||||
"statistics",
|
||||
"average",
|
||||
"mean",
|
||||
"min",
|
||||
"max",
|
||||
"standard",
|
||||
"deviation",
|
||||
"regression",
|
||||
"quartile",
|
||||
"median",
|
||||
"outliers",
|
||||
"factorial",
|
||||
"probability",
|
||||
"permutation",
|
||||
"combination",
|
||||
"binomial",
|
||||
"geometric",
|
||||
"normal",
|
||||
"z-test"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/angusgibbs/statsjs.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "http://github.com/angusgibbs/statsjs/issues"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/angusgibbs/statsjs/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"main": "lib/stats",
|
||||
"devDependencies": {
|
||||
"expect.js": "git://github.com/angusgibbs/expect.js.git",
|
||||
"mocha": "^1.4.3"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user