/// <summary> /// Computes the singular value decomposition of the matrix. /// </summary> /// <returns>The SVD of the matrix.</returns> public SingularValueDecomposition SingularValueDecomposition() { if (rows >= cols) { // copy the matrix so as not to distrub the original double[] copy = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, rows, cols); // bidiagonalize it double[] a, b; MatrixAlgorithms.Bidiagonalize(copy, rows, cols, out a, out b); // form the U and V matrices double[] left = MatrixAlgorithms.AccumulateBidiagonalU(copy, rows, cols); double[] right = MatrixAlgorithms.AccumulateBidiagonalV(copy, rows, cols); // find the singular values of the bidiagonal matrix MatrixAlgorithms.ExtractSingularValues(a, b, left, right, rows, cols); // sort them MatrixAlgorithms.SortValues(a, left, right, rows, cols); // package it all up return(new SingularValueDecomposition(left, a, right, rows, cols)); } else { double[] scratch = MatrixAlgorithms.Transpose(store, rows, cols); double[] a, b; MatrixAlgorithms.Bidiagonalize(scratch, cols, rows, out a, out b); double[] left = MatrixAlgorithms.AccumulateBidiagonalU(scratch, cols, rows); double[] right = MatrixAlgorithms.AccumulateBidiagonalV(scratch, cols, rows); MatrixAlgorithms.ExtractSingularValues(a, b, left, right, cols, rows); MatrixAlgorithms.SortValues(a, left, right, cols, rows); left = MatrixAlgorithms.Transpose(left, cols, cols); right = MatrixAlgorithms.Transpose(right, rows, rows); return(new SingularValueDecomposition(right, a, left, rows, cols)); } }