export type Vector = I[] & { length: D }; export type Matrix = Vector>; export function vec(s: D, f: (i: number) => I): Vector { return Array.from({ length: s }, (_, i) => f(i)) as Vector; } export function mat(r: R, c: C, f: (x: number, y: number) => number): Matrix { return Array.from({ length: r }, (_, y) => Array.from({ length: c }, (_, x) => f(x, y))) as Matrix; } export function sum(l: Matrix, r: Matrix): Matrix { const result: Matrix = mat(l.length, l[0].length, () => 0); for (let i = 0; i < l.length; i++) { for (let j = 0; j < r[0].length; j++) { result[i][j] += l[i][j] + r[i][j]; } } return result; } export function mul(l: Matrix, r: number): Matrix; export function mul(l: Vector, r: Matrix): Vector; export function mul(l: Matrix, r: Matrix): Matrix; export function mul(l: Matrix | Vector, r: Matrix | number): Matrix | Vector { if (typeof r === 'number') { const lm: Matrix = l as Matrix; const result = Array.from({ length: lm.length }, () => Array(lm[0].length).fill(0)); for (let i = 0; i < lm.length; i++) { for (let j = 0; j < lm[i].length; j++) { result[i][j] += lm[i][j] * r; } } return result; } else if (!Array.isArray(l[0])) { const lv: Vector = l as Vector; const result = Array(r[0].length).fill(0); for (let j = 0; j < r[0].length; j++) { for (let i = 0; i < lv.length; i++) { result[j] += lv[i] * r[i][j]; } } return result; } else { const lm: Matrix = l as Matrix; const result = Array.from({ length: lm.length }, () => Array(r[0].length).fill(0)); for (let i = 0; i < lm.length; i++) { for (let j = 0; j < r[0].length; j++) { for (let k = 0; k < r.length; k++) { result[i][j] += lm[i][k] * r[k][j]; } } } return result; } } export function transpose(m: Matrix): Matrix { return mat(m[0].length, m.length, (x, y) => m[x][y]); } export function softmax(row: number[]): number[] { const max = Math.max(...row); const exps = row.map(v => Math.exp(v - max)); const sum = exps.reduce((a, b) => a + b, 0); return exps.map(v => v / sum); } export function msoftmax(m: Matrix): Matrix { return m.map(softmax) as Matrix; } export function norm(x: Matrix, epsilon = 1e-5): Matrix { return x.map(vec => { const mean = vec.reduce((sum, val) => sum + val, 0) / vec.length; const variance = vec.reduce((sum, val) => sum + (val - mean) ** 2, 0) / vec.length; return vec.map(val => (val - mean) / Math.sqrt(variance + epsilon)); }) as Matrix; } export function relu(vec: Vector): Vector { return vec.map(v => Math.max(0, v)) as Vector; } export function mean(v: Vector): number { return v.reduce((s, c) => s + c, 0) / v.length; } export function drm(data: number[], interval = 0.9): number { const sorted = [...data].sort((a, b) => a - b); const count = Math.floor(data.length * interval); let mi = 0; let mv = Infinity; for (let i = 0; i <= data.length - count; i++) { const range = sorted[i + count - 1] - sorted[i]; if (range < mv) { mv = range; mi = i; } } return sorted.slice(mi, mi + count).reduce((a, b) => a + b, 0) / count; } export function randseq(n: number): number[] { const is = Array.from({ length: n }, (_, i) => i); for (let i = n - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [is[i], is[j]] = [is[j], is[i]]; // swap } return is; } export function stddev(xs: number[]): number { const m = mean(xs); return Math.sqrt(xs.reduce((s, v) => s + (v - m) ** 2, 0) / xs.length); } export function ema(xs: number[], alpha = 0.1): number { let result = xs[0]; for (let i = 1; i < xs.length; i++) { result = alpha * xs[i] + (1 - alpha) * result; } return result; } export function slope(xs: number[]): number { const xMean = (xs.length - 1) / 2; const yMean = mean(xs); let num = 0, den = 0; for (let i = 0; i < xs.length; i++) { const x = i - xMean; const y = xs[i] - yMean; num += x * y; den += x * x; } return num / den; }