/**
         * Makes a draw on the distribution.  The results are added to parameter 'x'
         */
        public void next(DMatrixRMaj x)
        {
            for (int i = 0; i < r.numRows; i++)
            {
                r.set(i, 0, (double)rand.NextGaussian());
            }

            CommonOps_DDRM.multAdd(A, r, x);
        }
        public override /**/ double quality()
        {
            return(SpecializedOps_DDRM.qualityTriangular(R));
        }

        /**
         * <p>
         * Upgrades the basic solution to the optimal 2-norm solution.
         * </p>
         *
         * <pre>
         * First solves for 'z'
         *
         *       || x_b - P*[ R_11^-1 * R_12 ] * z ||2
         * min z ||         [ - I_{n-r}      ]     ||
         *
         * </pre>
         *
         * @param X basic solution, also output solution
         */
        protected void upgradeSolution(DMatrixRMaj X)
        {
            DMatrixRMaj z = Y; // recycle Y

            // compute the z which will minimize the 2-norm of X
            // because of the identity matrix tacked onto the end 'A' should never be singular
            if (!internalSolver.setA(W))
            {
                throw new InvalidOperationException("This should never happen.  Is input NaN?");
            }
            z.reshape(numCols - rank, 1);
            internalSolver.solve(X, z);

            // compute X by tweaking the original
            CommonOps_DDRM.multAdd(-1, W, z, X);
        }