예제 #1
0
        /// <summary>
        /// Calculates the inverse of the original matrix and returns it in a new <see cref="SymmetricMatrix"/> instance.
        /// WARNING: If <paramref name="inPlace"/> is set to true, this object must not be used again, otherwise a
        /// <see cref="InvalidOperationException"/> will be thrown.
        /// </summary>
        /// <param name="inPlace">False, to copy the internal factorization data before inversion. True, to overwrite it with
        ///     the inverse matrix, thus saving memory and time. However, that will make this object unusable, so you MUST NOT
        ///     call any other members afterwards.</param>
        public SymmetricMatrix Invert(bool inPlace)
        {
            CheckOverwritten();

            // Call LAPACK
            double[] inverse; // if A is posdef, so is inv(A)
            if (inPlace)
            {
                inverse       = data;
                IsOverwritten = true;
            }
            else
            {
                inverse = new double[data.Length];
                Array.Copy(data, inverse, data.Length);
            }
            int indefiniteMinorIdx = LapackLinearEquations.Dpptri(StoredTriangle.Upper, Order, inverse, 0);

            // Check LAPACK execution
            if (indefiniteMinorIdx < 0)
            {
                return(SymmetricMatrix.CreateFromPackedColumnMajorArray(inverse, Order, DefiniteProperty.PositiveDefinite));
            }
            else  // this should not have happened
            {
                throw new IndefiniteMatrixException($"The entry ({indefiniteMinorIdx}, {indefiniteMinorIdx}) of the factor U"
                                                    + " is 0 and the inverse could not be computed.");
            }
        }