public static Array <float> PseudoInv(Array <float> a) { // https://en.wikipedia.org/wiki/Moore–Penrose_pseudoinverse // http://vene.ro/blog/inverses-pseudoinverses-numerical-issues-speed-symmetry.html // https://software.intel.com/en-us/forums/intel-math-kernel-library/topic/296030 // dgelss can do the job with one input your matrix, the other the unit matrix // http://icl.cs.utk.edu/lapack-forum/viewtopic.php?f=2&t=160 var m = a.Shape[0]; var n = a.Shape[1]; /* Compute SVD */ var k = Math.Min(m, n); var s = new float[k]; var u = NN.Zeros <float>(m, m); var vt = NN.Zeros <float>(n, n); var copy = (float[])a.Values.Clone(); // if (jobu != 'O' && jobv != 'O') a is destroyed by dgesdv (https://software.intel.com/en-us/node/521150) var superb = new float[k - 1]; Lapack.gesvd('A', 'A', m, n, copy, n, s, u.Values, m, vt.Values, n, superb); var invSigma = NN.Zeros <float>(n, m); invSigma[Range(0, k), Range(0, k)] = NN.Diag(1 / NN.Array(s)); var pseudoInv = vt.T.Dot(invSigma).Dot(u.T); return(pseudoInv); }