/**
         * <p>
         * Computes a metric which measures the the quality of an eigen value decomposition.  If a
         * value is returned that is close to or smaller than 1e-15 then it is within machine precision.
         * </p>
         * <p>
         * EVD quality is defined as:<br>
         * <br>
         * Quality = ||A*V - V*D|| / ||A*V||.
         *  </p>
         *
         * @param orig The original matrix. Not modified.
         * @param eig EVD of the original matrix. Not modified.
         * @return The quality of the decomposition.
         */
        public static float quality(FMatrixRMaj orig, EigenDecomposition_F32 <FMatrixRMaj> eig)
        {
            FMatrixRMaj A = orig;
            FMatrixRMaj V = EigenOps_FDRM.createMatrixV(eig);
            FMatrixRMaj D = EigenOps_FDRM.createMatrixD(eig);

            // L = A*V
            FMatrixRMaj L = new FMatrixRMaj(A.numRows, V.numCols);

            CommonOps_FDRM.mult(A, V, L);
            // R = V*D
            FMatrixRMaj R = new FMatrixRMaj(V.numRows, D.numCols);

            CommonOps_FDRM.mult(V, D, R);

            FMatrixRMaj diff = new FMatrixRMaj(L.numRows, L.numCols);

            CommonOps_FDRM.subtract(L, R, diff);

            float top    = NormOps_FDRM.normF(diff);
            float bottom = NormOps_FDRM.normF(L);

            float error = top / bottom;

            return(error);
        }
        public static float quality(FMatrixRMaj orig, FMatrixRMaj U, FMatrixRMaj W, FMatrixRMaj Vt)
        {
            // foundA = U*W*Vt
            FMatrixRMaj UW = new FMatrixRMaj(U.numRows, W.numCols);

            CommonOps_FDRM.mult(U, W, UW);
            FMatrixRMaj foundA = new FMatrixRMaj(UW.numRows, Vt.numCols);

            CommonOps_FDRM.mult(UW, Vt, foundA);

            float normA = NormOps_FDRM.normF(foundA);

            return(SpecializedOps_FDRM.diffNormF(orig, foundA) / normA);
        }