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);
        }