-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnumeric_arrays.js
191 lines (163 loc) · 3.56 KB
/
numeric_arrays.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
* Mixin functions (aka traits) for numeric arrays
*/
/*jslint indent:2, node:true, sloppy:true, nomen:true*/
(function () {
//"use strict";
var extend, exported_functions;
/**
* Strip
*
* Return a copy of the array without extensions
*/
function strip() {
return this.slice(0);
}
/**
* Return the sum of an array
*/
function sum() {
function add_next(memo, val) {
return memo + val;
}
return this.reduce(add_next, 0);
}
/**
* Calculate the mean of an array
*/
function mean() {
return this.sum() / this.length;
}
/**
* Population Standard Deviation
*/
function stddevpop() {
var mu, len;
if (this.length === 0) { return NaN; }
if (this.length === 1) { return 0; }
mu = this.mean();
len = this.length;
function add_sub_mean_and_square(memo, val) {
return memo + (val - mu) * (val - mu);
}
return Math.sqrt(this.reduce(add_sub_mean_and_square, 0) / len);
}
/**
* Sample Standard Deviation
*/
function stddev() {
var mu, len;
if (this.length === 0) { return NaN; }
if (this.length === 1) { return 0; }
mu = this.mean();
len = this.length;
function add_sub_mean_and_square(memo, val) {
return memo + (val - mu) * (val - mu);
}
return Math.sqrt(this.reduce(add_sub_mean_and_square, 0) / (len - 1));
}
/**
* Maximum
*/
function max() {
return Math.max.apply(null, this);
}
/**
* Minimum
*/
function min() {
return Math.min.apply(null, this);
}
/**
* Pad
*
* Pad array to a given length with a given value
*/
function pad(len, val) {
while (this.length < len) {
this.push(val);
}
}
function _padToEqualLengths(arr) {
var len;
// Make sure arrays are equal length
this.pad(arr.length, 0);
len = this.len;
while (arr.length < len) {
arr.push(0);
}
return arr;
}
/**
* Add one array to another
*/
function add(arr) {
// Make sure arrays are equal length
arr = _padToEqualLengths.call(this, arr);
// Add the two arrays
function add_together(val, idx) {
this[idx] += val;
}
arr.forEach(add_together, this);
return this;
}
/**
* Subtract one array from another
*/
function subtract(arr) {
// Make sure arrays are equal length
arr = _padToEqualLengths.call(this, arr);
// Add the two arrays
function add_together(val, idx) {
this[idx] -= val;
}
arr.forEach(add_together, this);
return this;
}
/**
* Multiply
*
* Multiply two arrays, element by element
*/
function multiply(arr) {
// Make sure arrays are equal length
arr = _padToEqualLengths.call(this, arr);
// Multiply the two arrays together
function mul_together(val, idx) {
this[idx] = val * this[idx];
}
arr.forEach(mul_together, this);
return this;
}
/**
* Calculate dot product of two arrays
*/
function dot(arr) {
return extend(this.slice(0)).multiply(arr).sum();
}
/**
* Multiply each element by a scalar value
*/
function scale(val) {
function mul(x, idx) {
this[idx] = val * x;
}
this.forEach(mul, this);
return this;
}
exported_functions = [
sum, mean, stddevpop, stddev, max, min, pad, add, subtract, multiply, dot,
scale
];
/**
* Extend a given array with mixins
*/
extend = function (arr) {
function export_funcs(func) {
arr[func.name] = func.bind(arr);
}
exported_functions.forEach(export_funcs);
return arr;
};
exports.extend = extend;
}());