public GeneralMatrix[] decompose(int svCount, GeneralMatrix m) { SingularValueDecomposition s = new SingularValueDecomposition(m); try { sv = svCount; frameScale = m.RowDimension; if (m.RowDimension > m.ColumnDimension) { frameScale = m.ColumnDimension; } else if (m.RowDimension < m.ColumnDimension) { frameScale = m.RowDimension; } // Make square matrix of data if (m.RowDimension != m.ColumnDimension) { squareM = m.GetMatrix(0, frameScale - 1, 0, frameScale - 1); } else { squareM = m; } //perform the SVD here: SingularValueDecomposition svd = new SingularValueDecomposition(squareM); GeneralMatrix U = svd.GetU().GetMatrix(0, frameScale - 1, 0, sv - 1); GeneralMatrix V = svd.GetV(); double[] D = svd.SingularValues; GeneralMatrix dMat = makeDiagonalSquare(D, sv); GeneralMatrix vMat = V.Transpose().GetMatrix(0, sv - 1, 0, frameScale - 1); /*Console.WriteLine(U.RowDimension + "x" + U.ColumnDimension + " * " + dMat.RowDimension + "x" + dMat.ColumnDimension + " * " + vMat.RowDimension + "x" + vMat.ColumnDimension); recomposition = U.Multiply(dMat).Multiply(vMat); int[,] recompositionData = new int[recomposition.ColumnDimension, recomposition.RowDimension]; for (int i = 0; i < recomposition.ColumnDimension; i++) { for (int j = 0; j < recomposition.RowDimension; j++) { recompositionData[j, i] = (int)(recomposition.GetElement(j, i)); } }*/ GeneralMatrix[] result = new GeneralMatrix[2]; result[0] = U; result[1] = vMat; return result; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return null; }
/** * Computes the Moore–Penrose pseudoinverse using the SVD method. * * Modified version of the original implementation by Kim van der Linde. */ public static GeneralMatrix pinv(GeneralMatrix x) { if (x.Rank() < 1) return null; if (x.ColumnDimension > x.RowDimension) return pinv(x.Transpose()).Transpose(); SingularValueDecomposition svdX = new SingularValueDecomposition(x); double[] singularValues = svdX.SingularValues; double tol = Math.Max(x.ColumnDimension, x.RowDimension) * singularValues[0] * 2E-16; double[] singularValueReciprocals = new double[singularValues.Count()]; for (int i = 0; i < singularValues.Count(); i++) singularValueReciprocals[i] = Math.Abs(singularValues[i]) < tol ? 0 : (1.0 / singularValues[i]); double[][] u = svdX.GetU().Array; double[][] v = svdX.GetV().Array; int min = Math.Min(x.ColumnDimension, u[0].Count()); double[][] inverse = new double[x.ColumnDimension][]; for (int i = 0; i < x.ColumnDimension; i++) { inverse[i] = new double[x.RowDimension]; for (int j = 0; j < u.Count(); j++) for (int k = 0; k < min; k++) inverse[i][j] += v[i][k] * singularValueReciprocals[k] * u[j][k]; } return new GeneralMatrix(inverse); }