/// <summary>
        ///   Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        ///   A new object that is a copy of this instance.
        /// </returns>
        ///
        public object Clone()
        {
            var clone = new CholeskyDecompositionF();

            clone.L                = L.MemberwiseClone();
            clone.D                = (Single[])D.Clone();
            clone.destroyed        = destroyed;
            clone.n                = n;
            clone.undefined        = undefined;
            clone.robust           = robust;
            clone.positiveDefinite = positiveDefinite;
            return(clone);
        }
        /// <summary>
        ///   Solves a set of equation systems of type <c>A * X = B</c>.
        /// </summary>
        ///
        /// <param name="value">Right hand side matrix with as many rows as <c>A</c> and any number of columns.</param>
        /// <returns>Matrix <c>X</c> so that <c>L * L' * X = B</c>.</returns>
        /// <exception cref="T:System.ArgumentException">Matrix dimensions do not match.</exception>
        /// <exception cref="T:System.NonSymmetricMatrixException">Matrix is not symmetric.</exception>
        /// <exception cref="T:System.NonPositiveDefiniteMatrixException">Matrix is not positive-definite.</exception>
        /// <param name="inPlace">True to compute the solving in place, false otherwise.</param>
        ///
        public Single[,] Solve(Single[,] value, bool inPlace)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (value.Rows() != n)
            {
                throw new ArgumentException("Argument matrix should have the same number of rows as the decomposed matrix.", "value");
            }

            if (!robust && !positiveDefinite)
            {
                throw new NonPositiveDefiniteMatrixException("Decomposed matrix is not positive definite.");
            }

            if (undefined)
            {
                throw new InvalidOperationException("The decomposition is undefined (zero in diagonal).");
            }

            if (destroyed)
            {
                throw new InvalidOperationException("The decomposition has been destroyed.");
            }

            // int count = value.Columns();
            var B = inPlace ? value : value.MemberwiseClone();
            int m = B.Columns();

            // Solve L*Y = B;
            for (int k = 0; k < n; k++)
            {
                for (int j = 0; j < m; j++)
                {
                    for (int i = 0; i < k; i++)
                    {
                        B[k, j] -= B[i, j] * L[k, i];
                    }
                    B[k, j] /= L[k, k];
                }
            }

            if (robust)
            {
                for (int k = 0; k < D.Length; k++)
                {
                    for (int j = 0; j < m; j++)
                    {
                        B[k, j] /= D[k];
                    }
                }
            }

            // Solve L'*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < m; j++)
                {
                    for (int i = k + 1; i < n; i++)
                    {
                        B[k, j] -= B[i, j] * L[i, k];
                    }

                    B[k, j] /= L[k, k];
                }
            }

            return(B);
        }