Esempio n. 1
0
        protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix)
        {
            var watch = new Stopwatch();

            // Factorization
            if (mustFactorize)
            {
                watch.Start();
                factorization = CholeskySuiteSparse.Factorize(linearSystem.Matrix, useSuperNodalFactorization);
                watch.Stop();
                Logger.LogTaskDuration("Matrix factorization", watch.ElapsedMilliseconds);
                watch.Reset();
                mustFactorize = false;
            }

            // Substitutions
            watch.Start();
            Matrix solutionVectors;

            if (otherMatrix is Matrix otherDense)
            {
                return(factorization.SolveLinearSystems(otherDense));
            }
            else
            {
                try
                {
                    // If there is enough memory, copy the RHS matrix to a dense one, to speed up computations.
                    //TODO: must be benchmarked, if it is actually more efficient than solving column by column.
                    Matrix rhsVectors = otherMatrix.CopyToFullMatrix();
                    solutionVectors = factorization.SolveLinearSystems(rhsVectors);
                }
                catch (InsufficientMemoryException) //TODO: what about OutOfMemoryException?
                {
                    // Solution vectors
                    int systemOrder = linearSystem.Matrix.NumColumns;
                    int numRhs      = otherMatrix.NumColumns;
                    solutionVectors = Matrix.CreateZero(systemOrder, numRhs);
                    Vector solutionVector = linearSystem.CreateZeroVectorConcrete();

                    // Solve each linear system separately, to avoid copying the RHS matrix to a dense one.
                    for (int j = 0; j < numRhs; ++j)
                    {
                        if (j != 0)
                        {
                            solutionVector.Clear();
                        }
                        Vector rhsVector = otherMatrix.GetColumn(j);
                        factorization.SolveLinearSystem(rhsVector, solutionVector);
                        solutionVectors.SetSubcolumn(j, solutionVector);
                    }
                }
            }
            watch.Stop();
            Logger.LogTaskDuration("Back/forward substitutions", watch.ElapsedMilliseconds);
            Logger.IncrementAnalysisStep();
            return(solutionVectors);
        }
        protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix)
        {
            //TODO: Use a reorthogonalizetion approach when solving multiple rhs vectors. It would be even better if the CG
            //      algorithm exposed a method for solving for multiple rhs vectors.
            var watch = new Stopwatch();

            // Preconditioning
            if (mustUpdatePreconditioner)
            {
                watch.Start();
                preconditioner = preconditionerFactory.CreatePreconditionerFor(linearSystem.Matrix);
                watch.Stop();
                Logger.LogTaskDuration("Calculating preconditioner", watch.ElapsedMilliseconds);
                watch.Reset();
                mustUpdatePreconditioner = false;
            }

            // Iterative algorithm
            watch.Start();
            int    systemOrder     = linearSystem.Matrix.NumColumns;
            int    numRhs          = otherMatrix.NumColumns;
            var    solutionVectors = Matrix.CreateZero(systemOrder, numRhs);
            Vector solutionVector  = linearSystem.CreateZeroVectorConcrete();

            // Solve each linear system
            for (int j = 0; j < numRhs; ++j)
            {
                if (j != 0)
                {
                    solutionVector.Clear();
                }

                //TODO: we should make sure this is the same type as the vectors used by this solver, otherwise vector operations
                //      in CG will be slow.
                Vector rhsVector = otherMatrix.GetColumn(j);

                IterativeStatistics stats = pcgAlgorithm.Solve(linearSystem.Matrix, preconditioner, rhsVector,
                                                               solutionVector, true, () => linearSystem.CreateZeroVector());

                solutionVectors.SetSubcolumn(j, solutionVector);
            }

            watch.Stop();
            Logger.LogTaskDuration("Iterative algorithm", watch.ElapsedMilliseconds);
            Logger.IncrementAnalysisStep();
            return(solutionVectors);
        }