# TNT

The Template Numerical Toolkit (TNT) is a series of C++ templates that implement matrices and vectors. You can get the code and documentation from http://math.nist.gov/tnt. The most useful basic data type is `TNT::Array2D`, which is the preferred matrix data type. `TNT::Array1D` is occasionally useful for vectors that you are using with TNT code. Operators and []s are overloaded for matrices like you would expect, and an the templates handle memory allocation and sizing. The associated JAMA templates (same URL) provide Cholesky, Eigenvalue, LU, QR, and SVD decompositions.

The nice things about this library are that it is simple, free, and implemented entirely as templates (so you just specify -I/path/to/tnt and include the headers). On the down side, it's a bit limited in what it provides, and bjbrown has encountered a couple of bugs. He thinks they were in QR and Eigenvalue decompositions, and if they aren't fixed in the official distro, e-mail him for the fixes.

Oddly, the library doesn't transpose matrices. It also doesn't invert them. Here's the simplest matrix inversion (and determinant) code:

```#include <assert.h>
#include <tnt_array1d.h>
#include <tnt_array2d.h>
#include <jama_lu.h>

TNT::Array2D<float> invert(TNT::Array2D<float> &M) {
assert(M.dim1() == M.dim2()); // square matrices only please

// create identity matrix
TNT::Array2D<float> id(M.dim1(), M.dim2(), 0);
for (int i = 0; i < M.dim1(); i++) id[i][i] = 1;

// solve for inverse with LU decomposition
JAMA::LU lu(M);
assert(LU.det() > THRESHOLD); // non-singularity
return lu.solve(id);
}
```

Howdy:

I am not sure I should be able to edit this, but I can. Did you folks end up rolling your own transpose? I have recently done a very short survey of c++ matrix packages for svd, with the notable exception of blast. "newmat" was all but useless for for anything but positive definite matrices, and I was only using symmetric square matrices of size ~600x600.

While Im here, one more gotcha with TNT is you need to use the "matmult" methods, instead of naively doing C = A * B. I convinced myself of this with a little toy svd on 3x3 random numbers.

--John