Пример #1
0
        /// <summary>
        /// Modifies <c>this</c> to be the inverse of A.
        /// </summary>
        /// <param name="A">Can be the same object as <c>this</c></param>
        public void SetToInverse(LowerTriangularMatrix A)
        {
#if LAPACK
            if (object.ReferenceEquals(this, A))
            {
                A = (LowerTriangularMatrix)A.Clone();
            }
            this.SetToIdentity();
            Lapack.PredivideBy(this, A);
#else
            // Reference: Golub and van Loan (1996)
            Assert.IsTrue(A.Rows == A.Cols);
            Assert.IsTrue(A.Rows == this.Rows);
            for (int k = 0; k < rows; k++)
            {
                if (A[k, k] == 0)
                {
                    throw new MatrixSingularException(A);
                }
            }
            for (int j = 0; j < cols; j++)
            {
                int index1 = j;
                // k < j case
                for (int k = 0; k < j; k++)
                {
                    //B[k, j] = 0.0;
                    data[index1] = 0.0;
                    index1      += cols;
                }
                // k == j case
                int    index2 = j + j * cols;
                double v      = 1.0 / A.data[index2];
                data[index1] = v;
                for (int i = j + 1; i < rows; i++)
                {
                    // B[i, j] = -v * A[i, j];
                    index1      += cols;
                    index2      += cols;
                    data[index1] = -v * A.data[index2];
                }
                // k > j case
                for (int k = j + 1; k < rows; k++)
                {
                    index1 = j + k * cols;
                    index2 = k + k * cols;
                    if (data[index1] != 0)
                    {
                        //double u = B[k,j]/A[k,k];
                        //B[k, j] = u;
                        // TM: this style of indexing may look ugly but it runs much faster
                        double u = data[index1] / A.data[index2];
                        data[index1] = u;
                        for (int i = k + 1; i < rows; i++)
                        {
                            // B[i, j] -= u * A[i, k];
                            index1       += cols;
                            index2       += cols;
                            data[index1] -= u * A.data[index2];
                        }
                    }
                }
            }
#endif
        }