Solve
It supports multiple right-hand-sides.
The method is based off the TNT paper by J. M. Myre et al.
Recommendations
-
Speed. Best when these apply:
-
. - Data columns
. But it's worth trying in any case.
-
-
Accuracy: it's frequently as accurate as QR or PseudoInverse but it will have larger error (normally still acceptable) with tricky matrices.
For speed, see comparison here.
For calculations with non-zero intercept, remember to push a
A more thorough webpage to compare speed/accuracy will hopefully be included soon.
npm i fit-tnt
import { TNT } from 'fit-tnt';
const A = [
[1, 2, 3],
[4, 5, 6],
]; // 2x3
const b = [6, 12]; // or [[6],[12]]
try {
const { XBest, metadata } = new TNT(A, b);
} catch (e) {
console.error(e);
}
A related method is Ridge Regression.
- Matrix Shape: rows 500, columns 200
- Speed Up: 5.20
- Inverting the shape below, TNT is slower.
┌───────────────┬─────────────────────┬─────────────────────┐
│ (index) │ Avg Exec Time │ Avg Error │
├───────────────┼─────────────────────┼─────────────────────┤
│ TNT │ 0.09470919929999999 │ 0.04945702797110891 │
│ PseudoInverse │ 0.49272041820000007 │ 0.04945702797110894 │
└───────────────┴─────────────────────┴─────────────────────┘
- In some cases it won't get to a low error, but normalizing improves performance.
Theoretical Background
Linear systems appear everywhere:
Searching the gradient-vector
This is also a linear system!
When computed directly (as done here),
TNT
The Conjugate Gradient for Normal Residual (CGNR) is a popular method for solving Sparse Least-Squares problems, where the design matrix has many zeros.
For wide-$A$, where
TNT preconditions
Positive definite means that
The
So we want to pre-condition
Algorithm Description
- Carry out product:
( N
is Symmetric.) - Cholesky Decomposition and factor: R, p = Cho(N)
-
if !p: N = N + e\*I
,being a tiny number. - Residual
- Gradient per coefficient (
), - Error in the coefficients
- Get
as a = dot(z,g)/dot (r,r)
- Update
as - Next residual
- New gradient
- New error in coefficients:
- Get
beta = dot(z_{i+1},g_{i+1})/dot (z_i,g_i)