Permalink
Browse files

Expand mode documentation, add .jshintrc, add CONTRIBUTING

Fixes #63
  • Loading branch information...
1 parent 0ff29bc commit 9b14b5d59845d448d3d28da370b4b4fd3872b39e @tmcw tmcw committed Mar 27, 2014
Showing with 156 additions and 46 deletions.
  1. +5 −0 .jshintrc
  2. +66 −0 CONTRIBUTING.md
  3. +85 −46 src/simple_statistics.js
View
@@ -0,0 +1,5 @@
+{
+ "indent": 4,
+ "undef": true,
+ "unused": true
+}
View
@@ -0,0 +1,66 @@
+# Contributing to simple-statistics
+
+Simple statistics is a statistics library that can be both used and read.
+It should help programmers learn statistics and statisticians learn programming.
+In order to achieve this goal, it must be **simple** and **explanatory**.
+
+## Simple
+
+`simple-statistics` is written in a subset of JavaScript. Unused features
+include:
+
+* [Conditional Operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)
+* [ES5 Array methods](http://ie.microsoft.com/TestDrive/HTML5/ECMAScript5Array/Default.html)
+* `with`, `eval`, and other forms of `eval`
+* Most micro-optimizations, like [alternative for loop forms](http://jsperf.com/loops/70)
+* [Shortcut branching](http://javascriptweblog.wordpress.com/2010/07/26/no-more-ifs-alternatives-to-statement-branching-in-javascript/)
+
+## Explanatory
+
+Example:
+
+```js
+// # harmonic mean
+//
+// a mean function typically used to find the average of rates
+//
+// this is the reciprocal of the arithmetic mean of the reciprocals
+// of the input numbers
+//
+// This runs on `O(n)`, linear time in respect to the array
+```
+
+`simple-statistics` tries to stay away from speaking only in the language of math:
+for instance, while JavaScript supports UTF8 characters like π, they are not used
+in the source:
+
+* UTF8 in JavaScript on pages without specific meta-tag or Content-Type encodings will fail
+* UTF8 can be hard to type, since users need to memorize key combinations or code points
+* Mathematical symbols have meanings that are often better communicated by words:
+ in the form of code, we do not run out of space on the paper, and can afford
+ to call a variable `reciprocal_sum` instead of `r`.
+
+Every function has a comment that ideally includes:
+
+* The English, long-form name of the method
+* What the method does
+* What purpose the method typically serves
+* A link to a longer description on Wikipedia, Mathematica, or another
+ web-accessible, non-paywalled source
+* The efficiency of the function in terms of Big-O notation, if appropriate
+* If the function depends on another function in the library, a note of this, like
+ `depends on mean()`
+
+## Code Style
+
+We use the [Airbnb style for Javascript](https://github.com/airbnb/javascript) with
+only one difference:
+
+**4 space soft tabs always for Javascript, not 2.**
+
+No aligned `=`, no aligned arguments, spaces are either indents or the 1
+space between expressions. No hard tabs.
+
+* All comparisons should be as strict and obvious as possible: prefer `(foo === 0)` to
+ `(!foo)`.
+* Straightforward code is more important than most optimizations.
View
@@ -1,3 +1,4 @@
+/* global module */
// # simple-statistics
//
// A simple, literate statistics system. The code below uses the
@@ -10,7 +11,7 @@
if (typeof module !== 'undefined') {
// Assign the `ss` object to exports, so that you can require
// it in [node.js](http://nodejs.org/)
- exports = module.exports = ss;
+ module.exports = ss;
} else {
// Otherwise, in a browser, we assign `ss` to the window object,
// so you can simply refer to it as `ss`.
@@ -53,7 +54,7 @@
var sum_x = 0, sum_y = 0,
sum_xx = 0, sum_xy = 0;
- // Use local variables to grab point values
+ // Use local variables to grab point values
// with minimal object property lookups
var point, x, y;
@@ -442,7 +443,7 @@
// The two datasets must have the same length which must be more than 1
if (x.length <= 1 || x.length != y.length){
- return null;
+ return null;
}
// determine the mean of each dataset so that we can judge each
@@ -507,7 +508,14 @@
}
// # [mode](http://bit.ly/W5K4Yt)
+ //
+ // The mode is the number that appears in a list the highest number of times.
+ // There can be multiple modes in a list: in the event of a tie, this
+ // algorithm will return the most recently seen mode.
+ //
// This implementation is inspired by [science.js](https://github.com/jasondavies/science.js/blob/master/src/stats/mode.js)
+ //
+ // This runs on `O(n)`, linear time in respect to the array
function mode(x) {
// Handle edge cases:
@@ -568,18 +576,18 @@
//
// Depends on `standard_deviation()` and `mean()`
function t_test(sample, x) {
- // The mean of the sample
- var sample_mean = mean(sample);
+ // The mean of the sample
+ var sample_mean = mean(sample);
- // The standard deviation of the sample
- var sd = standard_deviation(sample);
+ // The standard deviation of the sample
+ var sd = standard_deviation(sample);
- // Square root the length of the sample
- var rootN = Math.sqrt(sample.length);
+ // Square root the length of the sample
+ var rootN = Math.sqrt(sample.length);
- // Compute the known value against the sample,
- // returning the t value
- return (sample_mean - x) / (sd / rootN);
+ // Compute the known value against the sample,
+ // returning the t value
+ return (sample_mean - x) / (sd / rootN);
}
// # [2-sample t-test](http://en.wikipedia.org/wiki/Student's_t-test)
@@ -667,10 +675,10 @@
// If p is 1, directly return the last element
return sample[sample.length - 1];
} else if (p === 0) {
- // If p is 0, directly return the first element
- return sample[0];
+ // If p is 0, directly return the first element
+ return sample[0];
} else if (idx % 1 !== 0) {
- // If p is not integer, return the next element in array
+ // If p is not integer, return the next element in array
return sample[Math.ceil(idx) - 1];
} else if (sample.length % 2 === 0) {
// If the list has even-length, we'll take the average of this number
@@ -912,37 +920,68 @@
// (even though the latter has 5 digits precision, instead of 4).
var standard_normal_table = [
/* z 0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 */
- /* 0.0 */ 0.5000, 0.5040, 0.5080, 0.5120, 0.5160, 0.5199, 0.5239, 0.5279, 0.5319, 0.5359,
- /* 0.1 */ 0.5398, 0.5438, 0.5478, 0.5517, 0.5557, 0.5596, 0.5636, 0.5675, 0.5714, 0.5753,
- /* 0.2 */ 0.5793, 0.5832, 0.5871, 0.5910, 0.5948, 0.5987, 0.6026, 0.6064, 0.6103, 0.6141,
- /* 0.3 */ 0.6179, 0.6217, 0.6255, 0.6293, 0.6331, 0.6368, 0.6406, 0.6443, 0.6480, 0.6517,
- /* 0.4 */ 0.6554, 0.6591, 0.6628, 0.6664, 0.6700, 0.6736, 0.6772, 0.6808, 0.6844, 0.6879,
- /* 0.5 */ 0.6915, 0.6950, 0.6985, 0.7019, 0.7054, 0.7088, 0.7123, 0.7157, 0.7190, 0.7224,
- /* 0.6 */ 0.7257, 0.7291, 0.7324, 0.7357, 0.7389, 0.7422, 0.7454, 0.7486, 0.7517, 0.7549,
- /* 0.7 */ 0.7580, 0.7611, 0.7642, 0.7673, 0.7704, 0.7734, 0.7764, 0.7794, 0.7823, 0.7852,
- /* 0.8 */ 0.7881, 0.7910, 0.7939, 0.7967, 0.7995, 0.8023, 0.8051, 0.8078, 0.8106, 0.8133,
- /* 0.9 */ 0.8159, 0.8186, 0.8212, 0.8238, 0.8264, 0.8289, 0.8315, 0.8340, 0.8365, 0.8389,
- /* 1.0 */ 0.8413, 0.8438, 0.8461, 0.8485, 0.8508, 0.8531, 0.8554, 0.8577, 0.8599, 0.8621,
- /* 1.1 */ 0.8643, 0.8665, 0.8686, 0.8708, 0.8729, 0.8749, 0.8770, 0.8790, 0.8810, 0.8830,
- /* 1.2 */ 0.8849, 0.8869, 0.8888, 0.8907, 0.8925, 0.8944, 0.8962, 0.8980, 0.8997, 0.9015,
- /* 1.3 */ 0.9032, 0.9049, 0.9066, 0.9082, 0.9099, 0.9115, 0.9131, 0.9147, 0.9162, 0.9177,
- /* 1.4 */ 0.9192, 0.9207, 0.9222, 0.9236, 0.9251, 0.9265, 0.9279, 0.9292, 0.9306, 0.9319,
- /* 1.5 */ 0.9332, 0.9345, 0.9357, 0.9370, 0.9382, 0.9394, 0.9406, 0.9418, 0.9429, 0.9441,
- /* 1.6 */ 0.9452, 0.9463, 0.9474, 0.9484, 0.9495, 0.9505, 0.9515, 0.9525, 0.9535, 0.9545,
- /* 1.7 */ 0.9554, 0.9564, 0.9573, 0.9582, 0.9591, 0.9599, 0.9608, 0.9616, 0.9625, 0.9633,
- /* 1.8 */ 0.9641, 0.9649, 0.9656, 0.9664, 0.9671, 0.9678, 0.9686, 0.9693, 0.9699, 0.9706,
- /* 1.9 */ 0.9713, 0.9719, 0.9726, 0.9732, 0.9738, 0.9744, 0.9750, 0.9756, 0.9761, 0.9767,
- /* 2.0 */ 0.9772, 0.9778, 0.9783, 0.9788, 0.9793, 0.9798, 0.9803, 0.9808, 0.9812, 0.9817,
- /* 2.1 */ 0.9821, 0.9826, 0.9830, 0.9834, 0.9838, 0.9842, 0.9846, 0.9850, 0.9854, 0.9857,
- /* 2.2 */ 0.9861, 0.9864, 0.9868, 0.9871, 0.9875, 0.9878, 0.9881, 0.9884, 0.9887, 0.9890,
- /* 2.3 */ 0.9893, 0.9896, 0.9898, 0.9901, 0.9904, 0.9906, 0.9909, 0.9911, 0.9913, 0.9916,
- /* 2.4 */ 0.9918, 0.9920, 0.9922, 0.9925, 0.9927, 0.9929, 0.9931, 0.9932, 0.9934, 0.9936,
- /* 2.5 */ 0.9938, 0.9940, 0.9941, 0.9943, 0.9945, 0.9946, 0.9948, 0.9949, 0.9951, 0.9952,
- /* 2.6 */ 0.9953, 0.9955, 0.9956, 0.9957, 0.9959, 0.9960, 0.9961, 0.9962, 0.9963, 0.9964,
- /* 2.7 */ 0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9970, 0.9971, 0.9972, 0.9973, 0.9974,
- /* 2.8 */ 0.9974, 0.9975, 0.9976, 0.9977, 0.9977, 0.9978, 0.9979, 0.9979, 0.9980, 0.9981,
- /* 2.9 */ 0.9981, 0.9982, 0.9982, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986,
- /* 3.0 */ 0.9987, 0.9987, 0.9987, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.9990, 0.9990
+ /* 0.0 */
+ 0.5000, 0.5040, 0.5080, 0.5120, 0.5160, 0.5199, 0.5239, 0.5279, 0.5319, 0.5359,
+ /* 0.1 */
+ 0.5398, 0.5438, 0.5478, 0.5517, 0.5557, 0.5596, 0.5636, 0.5675, 0.5714, 0.5753,
+ /* 0.2 */
+ 0.5793, 0.5832, 0.5871, 0.5910, 0.5948, 0.5987, 0.6026, 0.6064, 0.6103, 0.6141,
+ /* 0.3 */
+ 0.6179, 0.6217, 0.6255, 0.6293, 0.6331, 0.6368, 0.6406, 0.6443, 0.6480, 0.6517,
+ /* 0.4 */
+ 0.6554, 0.6591, 0.6628, 0.6664, 0.6700, 0.6736, 0.6772, 0.6808, 0.6844, 0.6879,
+ /* 0.5 */
+ 0.6915, 0.6950, 0.6985, 0.7019, 0.7054, 0.7088, 0.7123, 0.7157, 0.7190, 0.7224,
+ /* 0.6 */
+ 0.7257, 0.7291, 0.7324, 0.7357, 0.7389, 0.7422, 0.7454, 0.7486, 0.7517, 0.7549,
+ /* 0.7 */
+ 0.7580, 0.7611, 0.7642, 0.7673, 0.7704, 0.7734, 0.7764, 0.7794, 0.7823, 0.7852,
+ /* 0.8 */
+ 0.7881, 0.7910, 0.7939, 0.7967, 0.7995, 0.8023, 0.8051, 0.8078, 0.8106, 0.8133,
+ /* 0.9 */
+ 0.8159, 0.8186, 0.8212, 0.8238, 0.8264, 0.8289, 0.8315, 0.8340, 0.8365, 0.8389,
+ /* 1.0 */
+ 0.8413, 0.8438, 0.8461, 0.8485, 0.8508, 0.8531, 0.8554, 0.8577, 0.8599, 0.8621,
+ /* 1.1 */
+ 0.8643, 0.8665, 0.8686, 0.8708, 0.8729, 0.8749, 0.8770, 0.8790, 0.8810, 0.8830,
+ /* 1.2 */
+ 0.8849, 0.8869, 0.8888, 0.8907, 0.8925, 0.8944, 0.8962, 0.8980, 0.8997, 0.9015,
+ /* 1.3 */
+ 0.9032, 0.9049, 0.9066, 0.9082, 0.9099, 0.9115, 0.9131, 0.9147, 0.9162, 0.9177,
+ /* 1.4 */
+ 0.9192, 0.9207, 0.9222, 0.9236, 0.9251, 0.9265, 0.9279, 0.9292, 0.9306, 0.9319,
+ /* 1.5 */
+ 0.9332, 0.9345, 0.9357, 0.9370, 0.9382, 0.9394, 0.9406, 0.9418, 0.9429, 0.9441,
+ /* 1.6 */
+ 0.9452, 0.9463, 0.9474, 0.9484, 0.9495, 0.9505, 0.9515, 0.9525, 0.9535, 0.9545,
+ /* 1.7 */
+ 0.9554, 0.9564, 0.9573, 0.9582, 0.9591, 0.9599, 0.9608, 0.9616, 0.9625, 0.9633,
+ /* 1.8 */
+ 0.9641, 0.9649, 0.9656, 0.9664, 0.9671, 0.9678, 0.9686, 0.9693, 0.9699, 0.9706,
+ /* 1.9 */
+ 0.9713, 0.9719, 0.9726, 0.9732, 0.9738, 0.9744, 0.9750, 0.9756, 0.9761, 0.9767,
+ /* 2.0 */
+ 0.9772, 0.9778, 0.9783, 0.9788, 0.9793, 0.9798, 0.9803, 0.9808, 0.9812, 0.9817,
+ /* 2.1 */
+ 0.9821, 0.9826, 0.9830, 0.9834, 0.9838, 0.9842, 0.9846, 0.9850, 0.9854, 0.9857,
+ /* 2.2 */
+ 0.9861, 0.9864, 0.9868, 0.9871, 0.9875, 0.9878, 0.9881, 0.9884, 0.9887, 0.9890,
+ /* 2.3 */
+ 0.9893, 0.9896, 0.9898, 0.9901, 0.9904, 0.9906, 0.9909, 0.9911, 0.9913, 0.9916,
+ /* 2.4 */
+ 0.9918, 0.9920, 0.9922, 0.9925, 0.9927, 0.9929, 0.9931, 0.9932, 0.9934, 0.9936,
+ /* 2.5 */
+ 0.9938, 0.9940, 0.9941, 0.9943, 0.9945, 0.9946, 0.9948, 0.9949, 0.9951, 0.9952,
+ /* 2.6 */
+ 0.9953, 0.9955, 0.9956, 0.9957, 0.9959, 0.9960, 0.9961, 0.9962, 0.9963, 0.9964,
+ /* 2.7 */
+ 0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9970, 0.9971, 0.9972, 0.9973, 0.9974,
+ /* 2.8 */
+ 0.9974, 0.9975, 0.9976, 0.9977, 0.9977, 0.9978, 0.9979, 0.9979, 0.9980, 0.9981,
+ /* 2.9 */
+ 0.9981, 0.9982, 0.9982, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986,
+ /* 3.0 */
+ 0.9987, 0.9987, 0.9987, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.9990, 0.9990
];
// # [Cumulative Standard Normal Probability](http://en.wikipedia.org/wiki/Standard_normal_table)

0 comments on commit 9b14b5d

Please sign in to comment.