Spaces:
Sleeping
Sleeping
File size: 1,681 Bytes
f8df83d | 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 | /**
* Centered rolling average over sorted array.
* Returns array of { index, value, avg } where avg may be null at edges.
*/
export function rollingAverage(sorted, window = 7) {
const half = Math.floor(window / 2)
return sorted.map((item, i) => {
const start = Math.max(0, i - half)
const end = Math.min(sorted.length - 1, i + half)
const slice = sorted.slice(start, end + 1)
const avg = slice.reduce((s, x) => s + x.value, 0) / slice.length
return { ...item, avg }
})
}
/**
* Pearson correlation coefficient for two arrays of equal length.
*/
export function pearsonR(x, y) {
const n = x.length
if (n < 2) return 0
const mx = x.reduce((a, b) => a + b, 0) / n
const my = y.reduce((a, b) => a + b, 0) / n
const num = x.reduce((s, xi, i) => s + (xi - mx) * (y[i] - my), 0)
const den = Math.sqrt(
x.reduce((s, xi) => s + (xi - mx) ** 2, 0) *
y.reduce((s, yi) => s + (yi - my) ** 2, 0)
)
return den === 0 ? 0 : num / den
}
/**
* Simple linear regression. Returns { slope, intercept }.
*/
export function linearRegression(x, y) {
const n = x.length
if (n < 2) return { slope: 0, intercept: 0 }
const mx = x.reduce((a, b) => a + b, 0) / n
const my = y.reduce((a, b) => a + b, 0) / n
const slope = x.reduce((s, xi, i) => s + (xi - mx) * (y[i] - my), 0) /
x.reduce((s, xi) => s + (xi - mx) ** 2, 0)
const intercept = my - slope * mx
return { slope, intercept }
}
/**
* Human-readable correlation description.
*/
export function describeCorrelation(r) {
const abs = Math.abs(r)
if (abs >= 0.7) return 'strong'
if (abs >= 0.4) return 'moderate'
if (abs >= 0.2) return 'weak'
return 'no meaningful'
}
|