singularValueDecomposition(epsilon=0, maxIterations=100) {
        if (this._width !== this._height) {
            throw new DetailedError("Expected a square matrix.", this);
        }

        let {U, S, V} = this._width === 2 ?
            this._unordered_singularValueDecomposition_2x2() :
            this._unordered_singularValueDecomposition_iterative(epsilon, maxIterations);

        // Fix ordering, so that the singular values are ascending.
        let permutation = Seq.range(this._width).sortedBy(i => -S.cell(i, i).norm2()).toArray();
        for (let i = 0; i < S._width; i++) {
            let j = permutation.indexOf(i);
            if (i !== j) {
                U._inline_colMix_postMultiply(i, j, Matrix.PAULI_X);
                V._inline_rowMix_preMultiply(i, j, Matrix.PAULI_X);
                let si = i*(S._width + 1)*2;
                let sj = j*(S._width + 1)*2;
                [S._buffer[si], S._buffer[sj]] = [S._buffer[sj], S._buffer[si]];
                [S._buffer[si+1], S._buffer[sj+1]] = [S._buffer[sj+1], S._buffer[si+1]];
                [permutation[j], permutation[i]] = [permutation[i], permutation[j]];
            }
        }

        // Fix phases.
        for (let i = 0; i < S._width; i++) {
            U._inline_colScale_postMultiply(i, S.cell(i, i).unit());
        }

        // Discard off-diagonal elements.
        S = Matrix.generateDiagonal(S._width, k => S.cell(k, k).abs());

        return {U, S, V};
    }
Factors the matrix int u*s*v parts, where u and v are unitary matrices and s is a real diagonal matrix.
@param {!number=} epsilon
@param {!int=} maxIterations
@returns {!{U: !Matrix, S: !Matrix, V: !Matrix}}