예제 #1
0
        /// <summary>
        /// Solves <i>A*X = B</i>; returns <i>X</i>.
        /// </summary>
        /// <param name="B">A Matrix with as many rows as <i>A</i> and any number of columns.</param>
        /// <returns><i>X</i> so that <i>L*L'*X = B</i>.</returns>
        /// <exception cref="ArgumentException">if <i>B.Rows != A.Rows</i>.</exception>
        /// <exception cref="ArgumentException">if <i>!isSymmetricPositiveDefinite()</i>.</exception>
        private DoubleMatrix2D XXXsolveBuggy(DoubleMatrix2D B)
        {
            var F = Cern.Jet.Math.Functions.functions;

            if (B.Rows != n)
            {
                throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixRowDimensionsMustAgree);
            }
            if (!isSymmetricPositiveDefinite)
            {
                throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_MatrixIsNotSymmetricPositiveDefinite);
            }

            // Copy right hand side.
            DoubleMatrix2D X  = B.Copy();
            int            nx = B.Columns;

            // precompute and cache some views to avoid regenerating them time and again
            DoubleMatrix1D[] Xrows = new DoubleMatrix1D[n];
            for (int k = 0; k < n; k++)
            {
                Xrows[k] = X.ViewRow(k);
            }

            // Solve L*Y = B;
            for (int k = 0; k < n; k++)
            {
                for (int i = k + 1; i < n; i++)
                {
                    // X[i,j] -= X[k,j]*L[i,k]
                    Xrows[i].Assign(Xrows[k], F2.MinusMult(mL[i, k]));
                }
                Xrows[k].Assign(F1.Div(mL[k, k]));
            }

            // Solve L'*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                Xrows[k].Assign(F1.Div(mL[k, k]));
                for (int i = 0; i < k; i++)
                {
                    // X[i,j] -= X[k,j]*L[k,i]
                    Xrows[i].Assign(Xrows[k], F2.MinusMult(mL[k, i]));
                }
            }
            return(X);
        }