@visactor/vmind
Version:
<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu
130 lines (112 loc) • 4.46 kB
JavaScript
import jStat from "jstat";
import quantile from "@stdlib/stats-base-dists-t-quantile";
export var TrendType;
function mkScore(x, n) {
let s = 0;
for (let k = 0; k < n - 1; k++) for (let j = k + 1; j < n; j++) x[j] > x[k] ? s += 1 : x[j] < x[k] && (s -= 1);
return s;
}
function varianceS(x, n) {
const uniqueX = Array.from(new Set(x)), g = uniqueX.length;
let varS;
if (n === g) varS = n * (n - 1) * (2 * n + 5) / 18; else {
const tp = new Array(g).fill(0);
for (let i = 0; i < g; i++) tp[i] = x.filter((item => item === uniqueX[i])).length;
varS = (n * (n - 1) * (2 * n + 5) - tp.reduce(((acc, curr) => acc + curr * (curr - 1) * (2 * curr + 5)), 0)) / 18;
}
return varS;
}
function zScore(s, varS) {
let z;
return s > 0 ? z = (s - 1) / Math.sqrt(varS) : 0 === s ? z = 0 : s < 0 && (z = (s + 1) / Math.sqrt(varS)),
z;
}
function sensEstimator(x) {
let idx = 0;
const n = x.length, d = new Array(n * (n - 1) / 2).fill(1);
for (let i = 0; i < n - 1; i++) for (let j = i + 1; j < n; j++) d[idx] = (x[j] - x[i]) / (j - i),
idx++;
return d;
}
function median(array) {
const sortedArray = array.filter((item => !isNaN(item))).sort(((a, b) => a - b)), midIndex = Math.floor(sortedArray.length / 2);
return sortedArray.length % 2 == 0 ? (sortedArray[midIndex - 1] + sortedArray[midIndex]) / 2 : sortedArray[midIndex];
}
function sensSlope(x) {
const n = x.length, slope = median(sensEstimator(x));
return {
slope: slope,
intercept: median(x) - median(Array.from(Array(n).keys())) * slope
};
}
function pValue(z, alpha) {
const p = 2 * (1 - jStat.normal.cdf(Math.abs(z), 0, 1)), h = Math.abs(z) > jStat.normal.inv(1 - alpha / 2, 0, 1);
let trend;
return trend = z < 0 && h ? TrendType.DECREASING : z > 0 && h ? TrendType.INCREASING : TrendType.NO_TREND,
{
p: p,
h: h,
trend: trend
};
}
!function(TrendType) {
TrendType.NO_TREND = "no trend", TrendType.INCREASING = "increasing", TrendType.DECREASING = "decreasing";
}(TrendType || (TrendType = {}));
export function originalMKTest(xOld, alpha = .05, calcScope = !1) {
const x = xOld, n = x.length, s = mkScore(x, n), z = zScore(s, varianceS(x, n)), {p: p, h: h, trend: trend} = pValue(z, alpha);
let finalSlope, finalIntercept;
if (h && calcScope) {
const {slope: slope, intercept: intercept} = sensSlope(xOld);
finalSlope = slope, finalIntercept = intercept;
}
return {
trend: trend,
pValue: p,
zScore: z,
slope: finalSlope,
intercept: finalIntercept
};
}
export function spearmanCoefficient(array1, array2) {
return jStat.spearmancoeff(array1, array2);
}
export function pearsonCorrelationCoeff(array1, array2) {
return jStat.corrcoeff(array1, array2);
}
export function studentTQuantile(x, degree) {
return quantile(x, degree);
}
export function coefficientVariation(data) {
return jStat.coeffvar(data);
}
export function longestTrendInterval(data, trendType) {
if (0 === data.length) return {
length: 0,
start: -1,
end: -1
};
let maxLength = 1, currentLength = 1, start = 0, end = 0, maxStart = 0, maxEnd = 0, maxTrend = 0, trend = 0;
for (let i = 1; i <= data.length; i++) {
const currentTrend = i === data.length ? null : Math.sign(data[i] - data[i - 1]);
currentTrend === trend ? (currentLength++, end = i) : (currentLength > maxLength && (!trendType || (0 === (trendValue = trend) ? TrendType.NO_TREND : 1 === trendValue ? TrendType.INCREASING : TrendType.DECREASING) === trendType) && (maxLength = currentLength,
maxStart = start, maxEnd = end, maxTrend = trend), trend = currentTrend, currentLength = 0 !== currentTrend ? 2 : 1,
start = i - 1, end = i);
}
var trendValue;
return {
length: maxLength,
start: maxStart,
end: maxEnd,
maxTrend: maxTrend
};
}
export const getMeanAndstdDev = data => {
const validData = data.filter((v => !isNaN(v))), mean = validData.reduce(((sum, v) => sum + v), 0) / validData.length, stdDev = Math.sqrt(validData.reduce(((sum, v) => sum + Math.pow(v - mean, 2)), 0) / validData.length);
return {
mean: mean,
stdDev: stdDev,
max: Math.max(...validData),
min: Math.min(...validData)
};
};
//# sourceMappingURL=statistics.js.map