Finds
The method is based off the TNT paper by J. M. Myre et al.
Recommendations
-
Speed. Best when these apply:
-
$\large\frac{\mathrm{rows}}{\mathrm{cols}} \geq 1$ . - Data columns
$\geq 10$ . 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=A^T,A$ (N
is Symmetric.) - Cholesky Decomposition and factor: R, p = Cho(N)
-
if !p: N = N + e\*I
,$\epsilon$ being a tiny number. - Residual
$r_0 = A,x_0 - b$ - Gradient per coefficient (
$r$ ),$g_0 = A^T r_0$ - Error in the coefficients
$z_0 = R^{-1},g_0$ - Get
$\alpha$ asa = dot(z,g)/dot (r,r)
- Update
$x$ as$x_{i+1}=x_{i} + a_i\times p_i$ - Next residual
$r_{i+1} = r_i - a_i \times r_i$ - New gradient
$g_{i+1} = A^T r_{i+1}$ - New error in coefficients:
$z_{i+1} = R^{-1},g_{i+1}$ - Get
$\beta$ beta = dot(z_{i+1},g_{i+1})/dot (z_i,g_i)