UNPKG

als-statistics

Version:

Modular JS statistics toolkit for Node.js and the browser: descriptive stats, correlations (Pearson/Spearman/Kendall), t-tests & ANOVA (Student/Welch), reliability (Cronbach’s alpha), regression (linear/logistic), clustering (DBSCAN/HDBSCAN), and table/co

50 lines (44 loc) 1.84 kB
import { Pearson } from '../correlate/pearson.js' function meanAbsDiff(x, y) { const n = Math.min(x.length, y.length); if (n === 0) return NaN; // пусть валидация поймает let s = 0; for (let i = 0; i < n; i++) s += Math.abs(x[i] - y[i]); return s / n; } function rangeUnionPlus(x, y) { let minv = Infinity, maxv = -Infinity; for (let i = 0; i < x.length; i++) { const v = x[i]; if (v < minv) minv = v; if (v > maxv) maxv = v; } for (let i = 0; i < y.length; i++) { const v = y[i]; if (v < minv) minv = v; if (v > maxv) maxv = v; } const r = maxv - minv; return (r === 0 || !Number.isFinite(r)) ? 1 : (r + 1); } function pearson(x, y) { const { r } = new Pearson({ x: x.values, y: y.values }, true) return Number.isFinite(r) ? Math.max(-1, Math.min(1, r)) : NaN } export default function computeDistances(samples, metric = 'mad') { const k = samples.length const distances = Array.from({ length: k }, () => Array(k).fill(0)); for (let i = 0; i < k; i++) { const colI = samples[i]; for (let j = i + 1; j < k; j++) { const colJ = samples[j]; let dist; if (metric === 'pearson') { const r = pearson(colI, colJ); if (!Number.isFinite(r)) throw new Error('Pearson correlation failed: non-finite'); dist = 1 - r; } else { // 'mad' const mad = meanAbsDiff(colI.values, colJ.values); const rng = rangeUnionPlus(colI.values, colJ.values); if (!Number.isFinite(mad) || !Number.isFinite(rng)) throw new Error('MAD distance failed: non-finite'); dist = mad / rng; } distances[i][j] = dist; distances[j][i] = dist; } distances[i][i] = 0; } return distances; }