linearRegressionFit function
Implementation
List<double> linearRegressionFit(List<List<double>> X, List<double> y) {
final n = X.length;
if (n == 0) return [0.0];
final m = X[0].length;
if (y.length != n) throw ArgumentError('X and y length mismatch');
// Build design matrix with intercept column and compute normal equation
// using X^T * X and X^T * y. For small m this is acceptable.
final xtx = List.generate(m + 1, (_) => List<double>.filled(m + 1, 0.0));
final xty = List<double>.filled(m + 1, 0.0);
for (var i = 0; i < n; i++) {
final row = [1.0, ...X[i]];
final yi = y[i];
for (var a = 0; a <= m; a++) {
for (var b = 0; b <= m; b++) {
xtx[a][b] += row[a] * row[b];
}
xty[a] += row[a] * yi;
}
}
// Solve linear system xtx * beta = xty using Gaussian elimination
final A = List.generate(m + 1, (i) => List<double>.from(xtx[i]));
final B = List<double>.from(xty);
final dim = m + 1;
for (var i = 0; i < dim; i++) {
// pivot
var pivot = i;
for (var r = i + 1; r < dim; r++) {
if (A[r][i].abs() > A[pivot][i].abs()) pivot = r;
}
if (A[pivot][i].abs() < 1e-12) continue; // singular-ish
if (pivot != i) {
final tmp = A[i];
A[i] = A[pivot];
A[pivot] = tmp;
final bt = B[i];
B[i] = B[pivot];
B[pivot] = bt;
}
final div = A[i][i];
for (var j = i; j < dim; j++) {
A[i][j] /= div;
}
B[i] /= div;
for (var r = 0; r < dim; r++) {
if (r == i) continue;
final factor = A[r][i];
for (var c = i; c < dim; c++) {
A[r][c] -= factor * A[i][c];
}
B[r] -= factor * B[i];
}
}
return B;
}