Skip to content

Commit f42f1b6

Browse files
committed
feat: add variance and standardDeviation methods
1 parent 6b57aae commit f42f1b6

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

matrix.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ declare module 'ml-matrix' {
244244
pseudoInverse(threshold?: number): Matrix;
245245
clone(): Matrix;
246246
entropy(eps?: number): number;
247+
variance(unbiased?: boolean, means?: number[]): number[];
248+
standardDeviation(unbiased?: boolean, means?: number[]): number[];
247249

248250
// From here we document methods dynamically generated from operators
249251

src/abstractMatrix.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ import {
1010
checkRange,
1111
checkIndices
1212
} from './util';
13-
import { sumByRow, sumByColumn, sumAll, productByRow, productByColumn, productAll } from './stat';
13+
import {
14+
sumByRow,
15+
sumByColumn,
16+
sumAll,
17+
productByRow,
18+
productByColumn,
19+
productAll
20+
} from './stat';
1421
import MatrixTransposeView from './views/transpose';
1522
import MatrixRowView from './views/row';
1623
import MatrixSubView from './views/sub';
@@ -1778,6 +1785,51 @@ export default function AbstractMatrix(superCtor) {
17781785
}
17791786
return 0 - sum;
17801787
}
1788+
1789+
variance(unbiased = true, means = this.mean('column')) {
1790+
if (typeof unbiased !== 'boolean') {
1791+
throw new TypeError('unbiased must be a boolean');
1792+
}
1793+
if (!Array.isArray(means)) {
1794+
throw new TypeError('means must be an array');
1795+
}
1796+
1797+
const rows = this.rows;
1798+
const cols = this.columns;
1799+
const variance = [];
1800+
1801+
for (var j = 0; j < cols; j++) {
1802+
var sum1 = 0;
1803+
var sum2 = 0;
1804+
var x = 0;
1805+
for (var i = 0; i < rows; i++) {
1806+
x = this.get(i, j) - means[j];
1807+
sum1 += x;
1808+
sum2 += x * x;
1809+
}
1810+
if (unbiased) {
1811+
variance.push((sum2 - (sum1 * sum1) / rows) / (rows - 1));
1812+
} else {
1813+
variance.push((sum2 - (sum1 * sum1) / rows) / rows);
1814+
}
1815+
}
1816+
return variance;
1817+
}
1818+
1819+
standardDeviation(unbiased = true, means = this.mean('column')) {
1820+
if (typeof unbiased !== 'boolean') {
1821+
throw new TypeError('unbiased must be a boolean');
1822+
}
1823+
if (!Array.isArray(means)) {
1824+
throw new TypeError('means must be an array');
1825+
}
1826+
1827+
const variance = this.variance(means, unbiased);
1828+
for (var i = 0; i < variance.length; i++) {
1829+
variance[i] = Math.sqrt(variance[i]);
1830+
}
1831+
return variance;
1832+
}
17811833
}
17821834

17831835
Matrix.prototype.klass = 'Matrix';

0 commit comments

Comments
 (0)