SPB Git

spb/earth-now Public License

earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.

TypeScript 93% Shell 2.3% SQL 1.4% JavaScript 1.3% Dockerfile 1.2% CSS 0.8%
2.1 KB · 61 lines typescript
Raw Blame History
1/**2 * earth-now.co3 * Author:  Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File:    packages/models/src/linalg.ts6 * Purpose: Minimal dense linear algebra — least-squares via normal equations with partial-pivot Gaussian elimination7 */89/** Solve A x = b (A: n×n, row-major) with partial pivoting. Throws on singular systems. */10export function solveLinearSystem(A: number[][], b: number[]): number[] {11  const n = b.length;12  // Augmented copy so callers' arrays are never mutated.13  const M = A.map((row, i) => [...row, b[i]!]);1415  for (let col = 0; col < n; col++) {16    let pivot = col;17    for (let r = col + 1; r < n; r++) {18      if (Math.abs(M[r]![col]!) > Math.abs(M[pivot]![col]!)) pivot = r;19    }20    if (Math.abs(M[pivot]![col]!) < 1e-12) throw new Error("solveLinearSystem: singular matrix");21    if (pivot !== col) {22      const tmp = M[col]!;23      M[col] = M[pivot]!;24      M[pivot] = tmp;25    }26    for (let r = col + 1; r < n; r++) {27      const f = M[r]![col]! / M[col]![col]!;28      for (let c = col; c <= n; c++) M[r]![c]! -= f * M[col]![c]!;29    }30  }3132  const x = new Array<number>(n).fill(0);33  for (let r = n - 1; r >= 0; r--) {34    let acc = M[r]![n]!;35    for (let c = r + 1; c < n; c++) acc -= M[r]![c]! * x[c]!;36    x[r] = acc / M[r]![r]!;37  }38  return x;39}4041/**42 * Ordinary least squares: minimize ||X β − y||² via normal equations XᵀX β = Xᵀy.43 * X is m×k row-major (m observations, k basis functions).44 */45export function leastSquares(X: number[][], y: number[]): number[] {46  const m = X.length;47  if (m === 0 || m !== y.length) throw new Error("leastSquares: dimension mismatch");48  const k = X[0]!.length;49  const XtX: number[][] = Array.from({ length: k }, () => new Array<number>(k).fill(0));50  const Xty = new Array<number>(k).fill(0);51  for (let i = 0; i < m; i++) {52    const row = X[i]!;53    for (let a = 0; a < k; a++) {54      Xty[a]! += row[a]! * y[i]!;55      for (let b = a; b < k; b++) XtX[a]![b]! += row[a]! * row[b]!;56    }57  }58  for (let a = 0; a < k; a++) for (let b = 0; b < a; b++) XtX[a]![b] = XtX[b]![a]!;59  return solveLinearSystem(XtX, Xty);60}61