Implement `pinv()` and tests
This implements pinv()
for three different cases:
- diagonal matrices (by inverting the diagonal safely)
- symmetric matrices (by eigendecomposition)
- general matrices (by singular value decomposition)
Diagonal matrices required implementing some kernels to look for NaNs, and changing slightly how the existing diagonal kernels work. (Side note: I don't think we need specialized diagonal kernels at all. Existing kernels could be adapted to support a "leading dimension" parameter, like LAPACK/BLAS routines, and then you could operate on a diagonal without needing a special kernel. But that's a different story for another day.)