time-to-botec/squiggle/node_modules/jstat/src/test.js
NunoSempere b6addc7f05 feat: add the node modules
Necessary in order to clearly see the squiggle hotwiring.
2022-12-03 12:44:49 +00:00

340 lines
9.6 KiB
JavaScript

(function(jStat, Math) {
var slice = [].slice;
var isNumber = jStat.utils.isNumber;
var isArray = jStat.utils.isArray;
// flag==true denotes use of sample standard deviation
// Z Statistics
jStat.extend({
// 2 different parameter lists:
// (value, mean, sd)
// (value, array, flag)
zscore: function zscore() {
var args = slice.call(arguments);
if (isNumber(args[1])) {
return (args[0] - args[1]) / args[2];
}
return (args[0] - jStat.mean(args[1])) / jStat.stdev(args[1], args[2]);
},
// 3 different paramter lists:
// (value, mean, sd, sides)
// (zscore, sides)
// (value, array, sides, flag)
ztest: function ztest() {
var args = slice.call(arguments);
var z;
if (isArray(args[1])) {
// (value, array, sides, flag)
z = jStat.zscore(args[0],args[1],args[3]);
return (args[2] === 1) ?
(jStat.normal.cdf(-Math.abs(z), 0, 1)) :
(jStat.normal.cdf(-Math.abs(z), 0, 1)*2);
} else {
if (args.length > 2) {
// (value, mean, sd, sides)
z = jStat.zscore(args[0],args[1],args[2]);
return (args[3] === 1) ?
(jStat.normal.cdf(-Math.abs(z),0,1)) :
(jStat.normal.cdf(-Math.abs(z),0,1)* 2);
} else {
// (zscore, sides)
z = args[0];
return (args[1] === 1) ?
(jStat.normal.cdf(-Math.abs(z),0,1)) :
(jStat.normal.cdf(-Math.abs(z),0,1)*2);
}
}
}
});
jStat.extend(jStat.fn, {
zscore: function zscore(value, flag) {
return (value - this.mean()) / this.stdev(flag);
},
ztest: function ztest(value, sides, flag) {
var zscore = Math.abs(this.zscore(value, flag));
return (sides === 1) ?
(jStat.normal.cdf(-zscore, 0, 1)) :
(jStat.normal.cdf(-zscore, 0, 1) * 2);
}
});
// T Statistics
jStat.extend({
// 2 parameter lists
// (value, mean, sd, n)
// (value, array)
tscore: function tscore() {
var args = slice.call(arguments);
return (args.length === 4) ?
((args[0] - args[1]) / (args[2] / Math.sqrt(args[3]))) :
((args[0] - jStat.mean(args[1])) /
(jStat.stdev(args[1], true) / Math.sqrt(args[1].length)));
},
// 3 different paramter lists:
// (value, mean, sd, n, sides)
// (tscore, n, sides)
// (value, array, sides)
ttest: function ttest() {
var args = slice.call(arguments);
var tscore;
if (args.length === 5) {
tscore = Math.abs(jStat.tscore(args[0], args[1], args[2], args[3]));
return (args[4] === 1) ?
(jStat.studentt.cdf(-tscore, args[3]-1)) :
(jStat.studentt.cdf(-tscore, args[3]-1)*2);
}
if (isNumber(args[1])) {
tscore = Math.abs(args[0])
return (args[2] == 1) ?
(jStat.studentt.cdf(-tscore, args[1]-1)) :
(jStat.studentt.cdf(-tscore, args[1]-1) * 2);
}
tscore = Math.abs(jStat.tscore(args[0], args[1]))
return (args[2] == 1) ?
(jStat.studentt.cdf(-tscore, args[1].length-1)) :
(jStat.studentt.cdf(-tscore, args[1].length-1) * 2);
}
});
jStat.extend(jStat.fn, {
tscore: function tscore(value) {
return (value - this.mean()) / (this.stdev(true) / Math.sqrt(this.cols()));
},
ttest: function ttest(value, sides) {
return (sides === 1) ?
(1 - jStat.studentt.cdf(Math.abs(this.tscore(value)), this.cols()-1)) :
(jStat.studentt.cdf(-Math.abs(this.tscore(value)), this.cols()-1)*2);
}
});
// F Statistics
jStat.extend({
// Paramter list is as follows:
// (array1, array2, array3, ...)
// or it is an array of arrays
// array of arrays conversion
anovafscore: function anovafscore() {
var args = slice.call(arguments),
expVar, sample, sampMean, sampSampMean, tmpargs, unexpVar, i, j;
if (args.length === 1) {
tmpargs = new Array(args[0].length);
for (i = 0; i < args[0].length; i++) {
tmpargs[i] = args[0][i];
}
args = tmpargs;
}
// Builds sample array
sample = new Array();
for (i = 0; i < args.length; i++) {
sample = sample.concat(args[i]);
}
sampMean = jStat.mean(sample);
// Computes the explained variance
expVar = 0;
for (i = 0; i < args.length; i++) {
expVar = expVar + args[i].length * Math.pow(jStat.mean(args[i]) - sampMean, 2);
}
expVar /= (args.length - 1);
// Computes unexplained variance
unexpVar = 0;
for (i = 0; i < args.length; i++) {
sampSampMean = jStat.mean(args[i]);
for (j = 0; j < args[i].length; j++) {
unexpVar += Math.pow(args[i][j] - sampSampMean, 2);
}
}
unexpVar /= (sample.length - args.length);
return expVar / unexpVar;
},
// 2 different paramter setups
// (array1, array2, array3, ...)
// (anovafscore, df1, df2)
anovaftest: function anovaftest() {
var args = slice.call(arguments),
df1, df2, n, i;
if (isNumber(args[0])) {
return 1 - jStat.centralF.cdf(args[0], args[1], args[2]);
}
var anovafscore = jStat.anovafscore(args);
df1 = args.length - 1;
n = 0;
for (i = 0; i < args.length; i++) {
n = n + args[i].length;
}
df2 = n - df1 - 1;
return 1 - jStat.centralF.cdf(anovafscore, df1, df2);
},
ftest: function ftest(fscore, df1, df2) {
return 1 - jStat.centralF.cdf(fscore, df1, df2);
}
});
jStat.extend(jStat.fn, {
anovafscore: function anovafscore() {
return jStat.anovafscore(this.toArray());
},
anovaftes: function anovaftes() {
var n = 0;
var i;
for (i = 0; i < this.length; i++) {
n = n + this[i].length;
}
return jStat.ftest(this.anovafscore(), this.length - 1, n - this.length);
}
});
// Tukey's range test
jStat.extend({
// 2 parameter lists
// (mean1, mean2, n1, n2, sd)
// (array1, array2, sd)
qscore: function qscore() {
var args = slice.call(arguments);
var mean1, mean2, n1, n2, sd;
if (isNumber(args[0])) {
mean1 = args[0];
mean2 = args[1];
n1 = args[2];
n2 = args[3];
sd = args[4];
} else {
mean1 = jStat.mean(args[0]);
mean2 = jStat.mean(args[1]);
n1 = args[0].length;
n2 = args[1].length;
sd = args[2];
}
return Math.abs(mean1 - mean2) / (sd * Math.sqrt((1 / n1 + 1 / n2) / 2));
},
// 3 different parameter lists:
// (qscore, n, k)
// (mean1, mean2, n1, n2, sd, n, k)
// (array1, array2, sd, n, k)
qtest: function qtest() {
var args = slice.call(arguments);
var qscore;
if (args.length === 3) {
qscore = args[0];
args = args.slice(1);
} else if (args.length === 7) {
qscore = jStat.qscore(args[0], args[1], args[2], args[3], args[4]);
args = args.slice(5);
} else {
qscore = jStat.qscore(args[0], args[1], args[2]);
args = args.slice(3);
}
var n = args[0];
var k = args[1];
return 1 - jStat.tukey.cdf(qscore, k, n - k);
},
tukeyhsd: function tukeyhsd(arrays) {
var sd = jStat.pooledstdev(arrays);
var means = arrays.map(function (arr) {return jStat.mean(arr);});
var n = arrays.reduce(function (n, arr) {return n + arr.length;}, 0);
var results = [];
for (var i = 0; i < arrays.length; ++i) {
for (var j = i + 1; j < arrays.length; ++j) {
var p = jStat.qtest(means[i], means[j], arrays[i].length, arrays[j].length, sd, n, arrays.length);
results.push([[i, j], p]);
}
}
return results;
}
});
// Error Bounds
jStat.extend({
// 2 different parameter setups
// (value, alpha, sd, n)
// (value, alpha, array)
normalci: function normalci() {
var args = slice.call(arguments),
ans = new Array(2),
change;
if (args.length === 4) {
change = Math.abs(jStat.normal.inv(args[1] / 2, 0, 1) *
args[2] / Math.sqrt(args[3]));
} else {
change = Math.abs(jStat.normal.inv(args[1] / 2, 0, 1) *
jStat.stdev(args[2]) / Math.sqrt(args[2].length));
}
ans[0] = args[0] - change;
ans[1] = args[0] + change;
return ans;
},
// 2 different parameter setups
// (value, alpha, sd, n)
// (value, alpha, array)
tci: function tci() {
var args = slice.call(arguments),
ans = new Array(2),
change;
if (args.length === 4) {
change = Math.abs(jStat.studentt.inv(args[1] / 2, args[3] - 1) *
args[2] / Math.sqrt(args[3]));
} else {
change = Math.abs(jStat.studentt.inv(args[1] / 2, args[2].length - 1) *
jStat.stdev(args[2], true) / Math.sqrt(args[2].length));
}
ans[0] = args[0] - change;
ans[1] = args[0] + change;
return ans;
},
significant: function significant(pvalue, alpha) {
return pvalue < alpha;
}
});
jStat.extend(jStat.fn, {
normalci: function normalci(value, alpha) {
return jStat.normalci(value, alpha, this.toArray());
},
tci: function tci(value, alpha) {
return jStat.tci(value, alpha, this.toArray());
}
});
// internal method for calculating the z-score for a difference of proportions test
function differenceOfProportions(p1, n1, p2, n2) {
if (p1 > 1 || p2 > 1 || p1 <= 0 || p2 <= 0) {
throw new Error("Proportions should be greater than 0 and less than 1")
}
var pooled = (p1 * n1 + p2 * n2) / (n1 + n2);
var se = Math.sqrt(pooled * (1 - pooled) * ((1/n1) + (1/n2)));
return (p1 - p2) / se;
}
// Difference of Proportions
jStat.extend(jStat.fn, {
oneSidedDifferenceOfProportions: function oneSidedDifferenceOfProportions(p1, n1, p2, n2) {
var z = differenceOfProportions(p1, n1, p2, n2);
return jStat.ztest(z, 1);
},
twoSidedDifferenceOfProportions: function twoSidedDifferenceOfProportions(p1, n1, p2, n2) {
var z = differenceOfProportions(p1, n1, p2, n2);
return jStat.ztest(z, 2);
}
});
}(jStat, Math));